The JavaScriptCore Virtual Machine Filip Pizlo Apple Inc. 3 Pizlo - - PowerPoint PPT Presentation

the javascriptcore virtual machine
SMART_READER_LITE
LIVE PREVIEW

The JavaScriptCore Virtual Machine Filip Pizlo Apple Inc. 3 Pizlo - - PowerPoint PPT Presentation

The JavaScriptCore Virtual Machine Filip Pizlo Apple Inc. 3 Pizlo Keynotes / Week ICCV17 Symmetry as the fundamental prior in human 3D vision Zygmunt Pizlo webkit.org https://svn.webkit.org/repository/webkit/trunk Safari What


slide-1
SLIDE 1

The JavaScriptCore Virtual Machine

Filip Pizlo Apple Inc.

slide-2
SLIDE 2

3 Pizlo Keynotes / Week

ICCV’17 “Symmetry as the fundamental prior in human 3D vision” Zygmunt Pizlo

slide-3
SLIDE 3

webkit.org

https://svn.webkit.org/repository/webkit/trunk

slide-4
SLIDE 4

Safari

slide-5
SLIDE 5

What JSC Supports

  • ECMAScript 2016+
  • WebAssembly
slide-6
SLIDE 6

What JSC Supports

  • ECMAScript 2016+
  • WebAssembly
slide-7
SLIDE 7

Architecture

slide-8
SLIDE 8

Architecture

  • Interpreters and JITs
  • Object Model
  • Type Inference
  • Garbage Collector
slide-9
SLIDE 9

Interpreters and JITs

slide-10
SLIDE 10

Four Tiers

LLInt

(interpreter)

Baseline

(template JIT)

DFG

(less optimizing JIT)

FTL

(optimizing JIT)

latency throughput

slide-11
SLIDE 11
  • Four tiers for JavaScript
  • Two tiers for WebAssembly
  • Two tiers for regular expressions
slide-12
SLIDE 12
  • Four tiers for JavaScript
  • Two tiers for WebAssembly
  • Two tiers for regular expressions
slide-13
SLIDE 13

Four Tiers

  • How we tier up
  • How the tiers work
  • How we OSR exit
slide-14
SLIDE 14

time "use strict"; let result = 0; for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f; } print(result); concurrency

slide-15
SLIDE 15

time "use strict"; let result = 0; for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f; } print(result); concurrency

LLInt

slide-16
SLIDE 16

time "use strict"; let result = 0; for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f; } print(result); concurrency

LLInt

trigger
slide-17
SLIDE 17

time "use strict"; let result = 0; for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f; } print(result); concurrency

LLInt

baseline compiler

trigger
slide-18
SLIDE 18

time "use strict"; let result = 0; for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f; } print(result); concurrency

LLInt

baseline compiler

trigger

LLInt

slide-19
SLIDE 19

time "use strict"; let result = 0; for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f; } print(result); concurrency

LLInt

baseline compiler

trigger

LLInt

OSR
slide-20
SLIDE 20

time "use strict"; let result = 0; for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f; } print(result); concurrency

LLInt

baseline compiler

trigger

LLInt

OSR

Baseline

DFG compiler

trigger

Baseline

OSR

DFG

trigger

FTL compiler

DFG

OSR

FTL

slide-21
SLIDE 21

time "use strict"; let result = 0; for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f; } print(result); concurrency

LLInt

baseline compiler

trigger

LLInt

OSR

Baseline

DFG compiler

trigger

Baseline

OSR

DFG

trigger

FTL compiler

DFG

OSR

FTL

0.12ms

slide-22
SLIDE 22

time "use strict"; let result = 0; for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f; } print(result); concurrency

LLInt

baseline compiler

trigger

LLInt

OSR

Baseline

DFG compiler

trigger

Baseline

OSR

DFG

trigger

FTL compiler

DFG

OSR

FTL

0.12ms 0.48ms

slide-23
SLIDE 23

time "use strict"; let result = 0; for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f; } print(result); concurrency

LLInt

baseline compiler

trigger

LLInt

OSR

Baseline

DFG compiler

trigger

Baseline

OSR

DFG

trigger

FTL compiler

DFG

OSR

FTL

0.12ms 0.48ms 2.86ms

slide-24
SLIDE 24

How We Tier Up

  • Counting trigger
  • Concurrent JITs
  • Parallel JITs
  • OSR
slide-25
SLIDE 25

Profiling

LLInt

(interpreter)

Baseline

(template JIT)

DFG

(less optimizing JIT)

FTL

(optimizing JIT)
slide-26
SLIDE 26

Speculation and OSR

LLInt

(interpreter)

Baseline

(template JIT)

DFG

(less optimizing JIT)

FTL

(optimizing JIT)
slide-27
SLIDE 27

FTL-to-B3 lowering DFG Optimizer DFG Backend Extended DFG Optimizer B3 Optimizer Instruction Selection Air Optimizer Air Backend Parser Bytecompiler Generatorification Bytecode Linker LLInt Bytecode Template JIT DFG Bytecode Parser DFG Bytecode Parser

AST unlinked bytecode bytecode

DFG FTL Baseline

DFG IR B3 IR Air

slide-28
SLIDE 28

function foo(a, b) { return a + b; }

slide-29
SLIDE 29

[ 0] enter [ 1] get_scope loc3 [ 3] mov loc4, loc3 [ 6] check_traps [ 7] add loc6, arg1, arg2 [ 12] ret loc6

slide-30
SLIDE 30

[ 0] enter [ 1] get_scope loc3 [ 3] mov loc4, loc3 [ 6] check_traps [ 7] add loc6, arg1, arg2 [ 12] ret loc6

slide-31
SLIDE 31

23: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 24: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 25: ArithAdd(Int32:@23, Int32:@24, CheckOverflow, Exits, bc#7) 26: MovHint(Untyped:@25, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid) 28: Return(Untyped:@25, W:SideState, Exits, bc#12)

arg1 arg2 Return Add

slide-32
SLIDE 32

[ 7] add loc6, arg1, arg2

23: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 24: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 25: ArithAdd(Int32:@23, Int32:@24, CheckOverflow, Exits, bc#7) 26: MovHint(Untyped:@25, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid)

slide-33
SLIDE 33

[ 7] add loc6, arg1, arg2

23: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 24: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 25: ArithAdd(Int32:@23, Int32:@24, CheckOverflow, Exits, bc#7) 26: MovHint(Untyped:@25, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid)

slide-34
SLIDE 34

[ 7] add loc6, arg1, arg2

23: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 24: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 25: ArithAdd(Int32:@23, Int32:@24, CheckOverflow, Exits, bc#7) 26: MovHint(Untyped:@25, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid)

slide-35
SLIDE 35

[ 7] add loc6, arg1, arg2

23: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 24: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 25: ArithAdd(Int32:@23, Int32:@24, CheckOverflow, Exits, bc#7) 26: MovHint(Untyped:@25, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid)

slide-36
SLIDE 36

[ 7] add loc6, arg1, arg2

23: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 24: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 25: ArithAdd(Int32:@23, Int32:@24, CheckOverflow, Exits, bc#7) 26: MovHint(Untyped:@25, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid)

slide-37
SLIDE 37

[ 7] add loc6, arg1, arg2

23: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 24: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 25: ArithAdd(Int32:@23, Int32:@24, CheckOverflow, Exits, bc#7) 26: MovHint(Untyped:@25, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid)

slide-38
SLIDE 38

[ 7] add loc6, arg1, arg2

23: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 24: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 25: ArithAdd(Int32:@23, Int32:@24, CheckOverflow, Exits, bc#7) 26: MovHint(Untyped:@25, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid)

slide-39
SLIDE 39

[ 7] add loc6, arg1, arg2

23: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 24: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 25: ArithAdd(Int32:@23, Int32:@24, CheckOverflow, Exits, bc#7) 26: MovHint(Untyped:@25, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid)

slide-40
SLIDE 40

DFG SSA state

arg1 arg2 Add Return

slide-41
SLIDE 41

DFG SSA state

arg1 arg2 Add Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6

slide-42
SLIDE 42

DFG SSA state

arg1 arg2 Add Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6

slide-43
SLIDE 43

DFG SSA state

arg1 arg2 Add Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6 MovHint

slide-44
SLIDE 44

DFG SSA state

arg1 arg2 Add Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6 MovHint

slide-45
SLIDE 45

DFG SSA state

arg1 arg2 Add Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6 MovHint

25:

slide-46
SLIDE 46

DFG SSA state

arg1 arg2 Add Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6 MovHint

loc6 := @25 25:

slide-47
SLIDE 47
  • OSR exit
slide-48
SLIDE 48

Deoptimization

  • OSR exit
  • Invalidation
  • Jettison
slide-49
SLIDE 49

Int32 @37 = Trunc(@27, DFG:@25) Int32 @38 = Trunc(@22, DFG:@25) Int32 @39 = CheckAdd(@37:WarmAny, @38:WarmAny, generator = 0x109ec5b90, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@25) Int64 @40 = ZExt32(@39, DFG:@28) Int64 @41 = Add(@40, $-281474976710656(@13), DFG:@28) Void @42 = Return(@41, Terminal, DFG:@28)

slide-50
SLIDE 50

Patch &BranchAdd32, Overflow, %tmp4, %tmp5, %tmp3, @39 Move32 %tmp3, %tmp1, @40 Add64 %tmp1, %tmp2, %tmp0, @41 Move %tmp0, %rax, @42 Ret64 %rax, @42

slide-51
SLIDE 51

Patch &BranchAdd32, Overflow, %rcx, %rdx, %rdx, @39 Add64 %rdx, %rax, %rax, @41 Ret64 %rax, @42

slide-52
SLIDE 52

add %ecx, %edx jo 0x267160c025ed add %rdx, %rax

slide-53
SLIDE 53

Optimizations

  • Generatorification
  • Inlining
  • Strength Reduction
  • CSE (local and global)
  • LICM
  • Type/Bounds/Overflow Check Removal
  • Object Allocation Sinking
  • Arguments/Varargs Elimination
  • Sparse Conditional Constant

Propagation

  • Barrier Placement
  • Strength Reduction
  • Tail Duplication
  • Switch Inference
  • Float Inference
  • DCE
  • Register Allocation
  • Linear Scan
  • Briggs
  • Iterated Register Coalescing
  • Stack Allocation
slide-54
SLIDE 54

Interpreters and JITs

  • Optimized for breadth
  • Four tiers
  • Many optimizations in many IRs
  • Speculative
slide-55
SLIDE 55

Object Model

slide-56
SLIDE 56

{x: 1, y: 2} {x: 42, y: 3} {x: -5, y: 7}

slide-57
SLIDE 57

{1, 2} {42, 3} {-5, 7} {x, y}

slide-58
SLIDE 58

{1, 2} {42, 3} {-5, 7} {x, y} prototype global

  • bject
slide-59
SLIDE 59

{1, 2} {42, 3} {-5, 7} {x, y} prototype global

  • bject

structure

slide-60
SLIDE 60

{1, 2} {42, 3} {-5, 7} {x, y} proto

global

  • bject

Mono Proto

{1, 2} {42, 3} {-5, 7} {x, y}

global

  • bject

Poly Proto

proto 1 proto 2

poly proto just landed last Thursday @saambarati and I have been working on it for ~2 months

slide-61
SLIDE 61

Structures

  • Fast property access
  • Property type inference
  • Immutable property inference
  • Prototype optimizations
slide-62
SLIDE 62

JSC Object Model

indexing type flags cell state

structure ID

butterfly pointer inline slot 0 inline slot 1

public length vector length

  • ut of line slot 0

array slot 0

… … …

slide-63
SLIDE 63

JSC Object Model

indexing type flags cell state

structure ID

butterfly pointer inline slot 0 inline slot 1

public length vector length

  • ut of line slot 0

array slot 0

… … …

64 bits 64 bits 64 bits 64 bits 64 bits 64 bits 64 bits

slide-64
SLIDE 64

JSC Object Model

indexing type flags cell state

structure ID

butterfly pointer inline slot 0 inline slot 1

public length vector length

  • ut of line slot 0

array slot 0

… … …

slide-65
SLIDE 65

JSC Object Model

indexing type flags cell state

structure ID

butterfly pointer inline slot 0 inline slot 1

public length vector length

  • ut of line slot 0

array slot 0

… … … statically configurable

slide-66
SLIDE 66

JSC Object Model

indexing type flags cell state

structure ID

butterfly pointer inline slot 0 inline slot 1

public length vector length

  • ut of line slot 0

array slot 0

… … … statically configurable dynamically configurable

slide-67
SLIDE 67

Empty JSObject

indexing type flags cell state

structure ID

null

slide-68
SLIDE 68

Fast JSObject

indexing type flags cell state

structure ID

null 0xffff000000000005

var o = {f: 5, g: 6};

0xffff000000000006

slide-69
SLIDE 69

JSObject with dynamically added fields

indexing type flags cell state

structure ID

butterfly 0xffff000000000005

var o = {f: 5, g: 6};

  • .h = 7;

0xffff000000000006 0xffff000000000007

slide-70
SLIDE 70

JSArray with room for 3 array elements

indexing type flags cell state

structure ID

butterfly

var a = [];

3

<hole> <hole> <hole>

slide-71
SLIDE 71

Object with fast properties and array elements

indexing type flags cell state

structure ID

butterfly

var o = {f: 5, g: 6};

  • [0] = 7;

1 3

0xffff000000000007 <hole> <hole> 0xffff000000000005 0xffff000000000006

slide-72
SLIDE 72

Object with fast and dynamic properties and array elements

indexing type flags cell state

structure ID

butterfly

var o = {f: 5, g: 6};

  • [0] = 7;
  • .h = 8;

1 2

0xffff000000000007 <hole> 0xffff000000000005 0xffff000000000006 0xffff000000000008

slide-73
SLIDE 73

Exotic object with dynamic properties and array elements

indexing type flags cell state

structure ID

butterfly

var o = new Date();

  • [0] = 7;
  • .h = 8;

1 2

0xffff000000000007 <hole> <C++ state> <C++ state> 0xffff000000000008

slide-74
SLIDE 74

Object Model

  • Structures
  • Cells
  • Butterflies
slide-75
SLIDE 75

Type Inference

slide-76
SLIDE 76

Type Inference

  • Watchpoints
  • Value Profiles
  • Polymorphic Inline Caches
slide-77
SLIDE 77

Type Inference

  • Watchpoints
  • Value Profiles
  • Polymorphic Inline Caches
slide-78
SLIDE 78

Watchpoints

slide-79
SLIDE 79

Watchpoint

class Watchpoint { public: virtual void fire() = 0; };

slide-80
SLIDE 80

numberToStringWatchpoint

slide-81
SLIDE 81

numberToStringWatchpoint

  • 1. Compiler wants to optimize 42.toString() to “42”
  • 2. Check if already invalidated
  • If invalid, don’t do the optimization.
  • If valid, register watchpoint and do the
  • ptimization.
slide-82
SLIDE 82

Many watchpoints

  • haveABadTime
  • Structure transition
  • InferredValue
  • InferredType
  • many others
slide-83
SLIDE 83

Garbage Collector

slide-84
SLIDE 84

Garbage Collector

  • No copying
  • Conservative on the stack
slide-85
SLIDE 85

Garbage Collector

  • Constraint-based
  • Generational
  • Concurrent
  • Parallel
slide-86
SLIDE 86

Garbage Collector

  • Constraint-based
  • Generational
  • Concurrent
  • Parallel
slide-87
SLIDE 87

Constraint-Based Marking

  • Transitive reachability is not always enough
  • Common examples:
  • Soft references
  • Weak map
slide-88
SLIDE 88

Constraint-Based Marking

  • Transitive reachability is not always enough
  • WebKit examples:
  • Type inference
  • Weak map
  • DOM
  • Native code
slide-89
SLIDE 89

Constraint-Based Marking

  • Transitive reachability is not always enough
  • WebKit examples:
  • Type inference
  • Weak map
  • DOM
  • Native code
slide-90
SLIDE 90

Type Inference

slide-91
SLIDE 91

{1, 2} {42, 3} {-5, 7} {x, y} prototype global

  • bject

Objects Structure

slide-92
SLIDE 92

{1, 2} {42, 3} {-5, 7} {x, y} prototype global

  • bject
slide-93
SLIDE 93

{1, 2} {42, 3} {-5, 7} {x, y} prototype global

  • bject

JIT code

slide-94
SLIDE 94

{1, 2} {42, 3} {-5, 7} {x, y} prototype global

  • bject

JIT code

Is this a weak reference?

slide-95
SLIDE 95

JIT code references a structure

  • Strong reference?
  • Weak reference?
  • Marking constraint?
slide-96
SLIDE 96

Strong reference?

{x, y} {1, 2} {42, 3} {-5, 7} prototype global

  • bject

JIT code

slide-97
SLIDE 97

Strong reference?

{x, y} prototype global

  • bject

JIT code

slide-98
SLIDE 98

Strong reference?

{x, y} prototype global

  • bject

JIT code

slide-99
SLIDE 99

Strong reference?

{x, y} prototype global

  • bject

JIT code

so many leaks

slide-100
SLIDE 100

JIT code

Weak reference?

{x, y} {1, 2} {42, 3} {-5, 7} prototype global

  • bject
slide-101
SLIDE 101

JIT code

Weak reference?

{x, y} prototype global

  • bject
slide-102
SLIDE 102

JIT code

Weak reference?

{x, y} prototype global

  • bject
slide-103
SLIDE 103

JIT code

Weak reference?

{x, y} prototype global

  • bject

recomp storm

slide-104
SLIDE 104

structure prototype global

  • bject

JIT code

Marking Constraint

slide-105
SLIDE 105
  • JIT code references the structure weakly.

structure prototype global

  • bject

JIT code

Marking Constraint

slide-106
SLIDE 106
  • JIT code references the structure weakly.
  • JIT code also registers the above marking

constraint.

if (isMarked(structure->globalObject()) && isMarked(structure->storedPrototype())) mark(structure);

structure prototype global

  • bject

JIT code

Marking Constraint

slide-107
SLIDE 107

JIT code

Marking Constraint!

{x, y} {1, 2} {42, 3} {-5, 7} prototype global

  • bject
slide-108
SLIDE 108

JIT code

Marking Constraint!

{x, y} prototype global

  • bject
slide-109
SLIDE 109

JIT code

Marking Constraint!

{x, y} prototype global

  • bject

It’s cool - the prototype and global object are long-lived.

slide-110
SLIDE 110

JIT code

Marking Constraint!

{x, y}

slide-111
SLIDE 111

{x, y} JIT code

Marking Constraint!

slide-112
SLIDE 112

{x, y} JIT code

Marking Constraint!

We want the JIT code to die in this case.

slide-113
SLIDE 113

Marking Constraint!

  • If the objects that use the structure die, then:
  • Keep structure alive if the user objects it points

to are alive anyway.

  • Kill the structure (and the JIT code) if keeping

it alive would not be safe-for-space.

slide-114
SLIDE 114

Marking Constraints

  • Constraints can query which objects are

marked.

  • Constraints can mark objects.
  • GC executes constraints to fixpoint.
slide-115
SLIDE 115

Garbage Collector

  • Constraint-based
  • Generational
  • Concurrent
  • Parallel
slide-116
SLIDE 116

Conclusion

  • JavaScriptCore Architecture:
  • Interpreters and Multiple JITs
  • Cells, Structures, and Butterflies
  • Watchpoints, Value Profiles, and Inline Caches
  • Constraint-Based GC