Top Banner
Speculation in JavaScriptCore Filip Pizlo Apple Inc.
542

Pizlo Speculation in JSC Slides - filpizlo.com

Dec 05, 2021

Download

Documents

dariahiddleston
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation in JavaScriptCore

Filip PizloApple Inc.

Page 2: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation• Is ideal for…

- JavaScript

- Java

- Smalltalk

- Python

- Ruby

- Scheme

- …many dynamic languages…

Page 3: Pizlo Speculation in JSC Slides - filpizlo.com

Agenda• Speculation Overview

• JavaScriptCore Overview

• Speculation

- Bytecode (Common IR)

- Control

- Profiling

- Compilation

- OSR (On Stack Replacement)

Page 4: Pizlo Speculation in JSC Slides - filpizlo.com

Agenda• Speculation Overview

• JavaScriptCore Overview

• Speculation

- Bytecode (Common IR)

- Control

- Profiling

- Compilation

- OSR (On Stack Replacement)

Page 5: Pizlo Speculation in JSC Slides - filpizlo.com

Intuition

Leverage traditional compiler technology to make dynamic languages as fast as possible.

Page 6: Pizlo Speculation in JSC Slides - filpizlo.com

Traditional Compiler

C code

Type Checker

Optimizer

Page 7: Pizlo Speculation in JSC Slides - filpizlo.com

C function

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

Page 8: Pizlo Speculation in JSC Slides - filpizlo.com

C function

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

Page 9: Pizlo Speculation in JSC Slides - filpizlo.com

JS function

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

Page 10: Pizlo Speculation in JSC Slides - filpizlo.com

Type Checker

JS code

Optimizing Tier

Page 11: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

JS code

Optimizing Tier

Page 12: Pizlo Speculation in JSC Slides - filpizlo.com

time

Page 13: Pizlo Speculation in JSC Slides - filpizlo.com

C code

time

Page 14: Pizlo Speculation in JSC Slides - filpizlo.com

Compiler

C code

time

Page 15: Pizlo Speculation in JSC Slides - filpizlo.com

Compiler

C code Type Checker

time

Page 16: Pizlo Speculation in JSC Slides - filpizlo.com

Compiler

C code Type Checker Optimizer

time

Page 17: Pizlo Speculation in JSC Slides - filpizlo.com

Compiler

C code Type Checker Optimizer Program Execution

time

Page 18: Pizlo Speculation in JSC Slides - filpizlo.com

Compiler

C code Type Checker Optimizer Program Execution

JS code

time

Page 19: Pizlo Speculation in JSC Slides - filpizlo.com

Compiler

C code Type Checker Optimizer Program Execution

JS code Program Execution

time

Page 20: Pizlo Speculation in JSC Slides - filpizlo.com

Compiler

C code Type Checker Optimizer Program Execution

JS code Program ExecutionProfiled Unoptimized Execution

time

Page 21: Pizlo Speculation in JSC Slides - filpizlo.com

Compiler

C code Type Checker Optimizer Program Execution

JS code Program ExecutionProfiled Unoptimized Execution

Optimizer

time

Page 22: Pizlo Speculation in JSC Slides - filpizlo.com

Compiler

C code Type Checker Optimizer Program Execution

JS code Program ExecutionProfiled Unoptimized Execution

Optimizer

Optimized Execution

time

Page 23: Pizlo Speculation in JSC Slides - filpizlo.com

Compiler

C code Type Checker Optimizer Program Execution

JS code Program ExecutionProfiled Unoptimized Execution

Optimizer

Optimized Execution

time

Page 24: Pizlo Speculation in JSC Slides - filpizlo.com

Optimized JS function

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

Page 25: Pizlo Speculation in JSC Slides - filpizlo.com

Branch(isInt32(value))

… fast int32 add … Call(slow path)

… things …

Branch(isInt32(value))

… fast int32 add … Call(slow path)

… more things …

Speculation with Control Flow Diamond

Page 26: Pizlo Speculation in JSC Slides - filpizlo.com

Branch(isInt32(value))

… fast int32 add … Call(slow path)

… things …

Branch(isInt32(value))

… fast int32 add … Call(slow path)

… more things …

not redundant!

Speculation with Control Flow Diamond

Page 27: Pizlo Speculation in JSC Slides - filpizlo.com

Branch(isInt32(value))

… fast int32 add … Call(slow path)

… things …

Branch(isInt32(value))

… fast int32 add … Call(slow path)

… more things …

Branch(isInt32(value)) OSR exit

… fast int32 add …

… things …

Branch(isInt32(value))

… fast int32 add …

… more things …

OSR exit

Speculation with Control Flow Diamond Speculation with OSR

Page 28: Pizlo Speculation in JSC Slides - filpizlo.com

Branch(isInt32(value))

… fast int32 add … Call(slow path)

… things …

Branch(isInt32(value))

… fast int32 add … Call(slow path)

… more things …

Branch(isInt32(value)) OSR exit

… fast int32 add …

… things …

… fast int32 add …

… more things …

Speculation with Control Flow Diamond Speculation with OSR

Page 29: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Page 30: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Unoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

Page 31: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

Page 32: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculateOSR exit

Page 33: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculatespeculate

OSR exit

Page 34: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculate

speculatespeculate

OSR exit

Page 35: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculatespeculate

speculatespeculate

OSR exit

Page 36: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculatespeculate

speculate

speculatespeculate

OSR exit

Page 37: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculatespeculate

speculate

speculate

speculatespeculate

OSR exit

Page 38: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculatespeculate

speculate

speculatespeculate

speculatespeculate

OSR exit

Page 39: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculatespeculate

speculate

speculatespeculate

speculate

speculatespeculate

OSR exit

Page 40: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculatespeculate

speculate

speculatespeculate

speculate

speculatespeculate

OSR exit

Traditional Compiler + Enhancements

Page 41: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculatespeculate

speculate

speculatespeculate

speculate

speculatespeculate

OSR exit

Traditional Compiler + Enhancements

OSR entry

Page 42: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation with OSR

Optimized CodeUnoptimized Profiled Code

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

[ 0] enter

[ 1] add

[ 5] mov

[ 8] get_by_val

[ 13] call

speculatespeculate

speculate

speculatespeculate

speculate

speculatespeculate

OSR exit

Traditional Compiler + Enhancements

OSR entry

Page 43: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation Has A Function Granularity Bias

• Compiler sees single-entrypoint function + inlines.

• Speculations exit the function and rarely reenter.

Page 44: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 45: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 46: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 47: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 48: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 49: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 50: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 51: Pizlo Speculation in JSC Slides - filpizlo.com

Agenda• Speculation Overview

• JavaScriptCore Overview

• Speculation

- Bytecode (Common IR)

- Control

- Profiling

- Compilation

- OSR (On Stack Replacement)

Page 52: Pizlo Speculation in JSC Slides - filpizlo.com

JSC’s Four Tiers

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

latency throughput

Page 53: Pizlo Speculation in JSC Slides - filpizlo.com

JSC’s Four Tiers

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

latency throughput

profiling and OSR

Page 54: Pizlo Speculation in JSC Slides - filpizlo.com

JSC’s Four Tiers

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

latency throughput

profiling and OSR

speculation and OSR

Page 55: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

Page 56: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

LLInt

Page 57: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

LLInt

trigg

er

Page 58: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

LLInt

baseline compiler

trigg

er

Page 59: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

LLInt

baseline compiler

trigg

er

LLInt

Page 60: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

LLInt

baseline compiler

trigg

er

LLInt OSR

Page 61: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

LLInt

baseline compiler

trigg

er

LLInt OSR Baseline

DFG compiler

trigg

er

Baseline OSR DFG

trigg

er

FTL compiler

DFG OSR FTL

Page 62: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

LLInt

baseline compiler

trigg

er

LLInt OSR Baseline

DFG compiler

trigg

er

Baseline OSR DFG

trigg

er

FTL compiler

DFG OSR FTL

0.12ms

Page 63: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

LLInt

baseline compiler

trigg

er

LLInt OSR Baseline

DFG compiler

trigg

er

Baseline OSR DFG

trigg

er

FTL compiler

DFG OSR FTL

0.12ms 0.48ms

Page 64: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

LLInt

baseline compiler

trigg

er

LLInt OSR Baseline

DFG compiler

trigg

er

Baseline OSR DFG

trigg

er

FTL compiler

DFG OSR FTL

0.12ms 0.48ms 2.86ms

Page 65: Pizlo Speculation in JSC Slides - filpizlo.com
Page 66: Pizlo Speculation in JSC Slides - filpizlo.com

Parser

Page 67: Pizlo Speculation in JSC Slides - filpizlo.com

Parser

Bytecompiler

Page 68: Pizlo Speculation in JSC Slides - filpizlo.com

Parser

Bytecompiler

Generatorification

Page 69: Pizlo Speculation in JSC Slides - filpizlo.com

Parser

Bytecompiler

Generatorification

Bytecode Linker

Page 70: Pizlo Speculation in JSC Slides - filpizlo.com

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt

Page 71: Pizlo Speculation in JSC Slides - filpizlo.com

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

Page 72: Pizlo Speculation in JSC Slides - filpizlo.com

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG

Page 73: Pizlo Speculation in JSC Slides - filpizlo.com

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG Bytecode Parser

DFG

Page 74: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Optimizer

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG Bytecode Parser

DFG

Page 75: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Optimizer

DFG Backend

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG Bytecode Parser

DFG

Page 76: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Optimizer

DFG Backend

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG Bytecode Parser

DFG FTL

Page 77: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Optimizer

DFG Backend

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

Page 78: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Optimizer

DFG Backend

Extended DFG Optimizer

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

Page 79: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

Extended DFG Optimizer

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

Page 80: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

Extended DFG Optimizer

B3 Optimizer

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

Page 81: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

Extended DFG Optimizer

B3 Optimizer

Instruction Selection

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

Page 82: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

Extended DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Parser

Bytecompiler

Generatorification

Bytecode Linker

LLInt Bytecode Template JIT

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

Page 83: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-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

DFG FTL

Page 84: Pizlo Speculation in JSC Slides - filpizlo.com

JetStream 2 Score

LLInt

LLInt+Baseline

LLInt+Baseline+DFG

LLInt+Baseline+DFG+FTL

Score (higher is better)0 15 30 45 60 75 90 105 120 135 150

on my computer one day

Page 85: Pizlo Speculation in JSC Slides - filpizlo.com

JetStream 2 Score

LLInt

LLInt+Baseline

LLInt+Baseline+DFG

LLInt+Baseline+DFG+FTL

Score (higher is better)0 15 30 45 60 75 90 105 120 135 150

on my computer one day

>2× LLInt

Page 86: Pizlo Speculation in JSC Slides - filpizlo.com

JetStream 2 Score

LLInt

LLInt+Baseline

LLInt+Baseline+DFG

LLInt+Baseline+DFG+FTL

Score (higher is better)0 15 30 45 60 75 90 105 120 135 150

on my computer one day

>2× LLInt

>2× Baseline

Page 87: Pizlo Speculation in JSC Slides - filpizlo.com

JetStream 2 Score

LLInt

LLInt+Baseline

LLInt+Baseline+DFG

LLInt+Baseline+DFG+FTL

Score (higher is better)0 15 30 45 60 75 90 105 120 135 150

on my computer one day

>2× LLInt

>2× Baseline

~1.1× DFG

Page 88: Pizlo Speculation in JSC Slides - filpizlo.com

JetStream 2 “gaussian-blur”

LLInt

LLInt+Baseline

LLInt+Baseline+DFG

LLInt+Baseline+DFG+FTL

Milliseconds (lower is better)0 10000 20000 30000 40000 50000

1,450 ms

2,276 ms

14,091 ms

41,948 ms

on my computer one day

Page 89: Pizlo Speculation in JSC Slides - filpizlo.com

JetStream 2 “gaussian-blur”

LLInt

LLInt+Baseline

LLInt+Baseline+DFG

LLInt+Baseline+DFG+FTL

Milliseconds (lower is better)0 10000 20000 30000 40000 50000

1,450 ms

2,276 ms

14,091 ms

41,948 ms

on my computer one day

~1.6× DFG

Page 90: Pizlo Speculation in JSC Slides - filpizlo.com

Execution Time = (3.97 ns) × (Bytecodes in LLInt)

+ (1.71 ns) × (Bytecodes in Baseline)

+ (0.349 ns) × (Bytecodes in DFG)

+ (0.225 ns) × (Bytecodes in FTL)

Page 91: Pizlo Speculation in JSC Slides - filpizlo.com

Agenda• Speculation Overview

• JavaScriptCore Overview

• Speculation

- Bytecode (Common IR)

- Control

- Profiling

- Compilation

- OSR (On Stack Replacement)

Page 92: Pizlo Speculation in JSC Slides - filpizlo.com

Common IR

• Frame of reference for profiling

• Frame of reference for OSR

Page 93: Pizlo Speculation in JSC Slides - filpizlo.com

Bytecode

Page 94: Pizlo Speculation in JSC Slides - filpizlo.com

JSC Bytecode• Register-based

• Compact

• Untyped

• High-level

• Directly interpretable

• Transformable

Page 95: Pizlo Speculation in JSC Slides - filpizlo.com

Register-based

add result, left, right

result = left + right

Page 96: Pizlo Speculation in JSC Slides - filpizlo.com

Compact

add result, left, right

8 bits 8 bits 8 bits 8 bits

result = left + right

Page 97: Pizlo Speculation in JSC Slides - filpizlo.com

Untyped

add result, left, right

result = left + right

Page 98: Pizlo Speculation in JSC Slides - filpizlo.com

High-level

add result, left, right

result = left + right

Page 99: Pizlo Speculation in JSC Slides - filpizlo.com

Directly Interpretable

add result, left, right

result = left + right

Page 100: Pizlo Speculation in JSC Slides - filpizlo.com

Transformable

add result, left, right

result = left + right

Page 101: Pizlo Speculation in JSC Slides - filpizlo.com

JSC Bytecode• Register-based

• Compact

• Untyped

• High-level

• Directly interpretable

• Transformable

Page 102: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 103: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 104: Pizlo Speculation in JSC Slides - filpizlo.com

time

"use strict";

let result = 0;for (let i = 0; i < 10000000; ++i) { let o = {f: i}; result += o.f;}

print(result);

conc

urre

ncy

LLInt

baseline compiler

trigg

er

LLInt OSR Baseline

DFG compiler

trigg

er

Baseline OSR DFG

trigg

er

FTL compiler

DFG OSR FTL

0.12ms 0.48ms 2.86ms

Page 105: Pizlo Speculation in JSC Slides - filpizlo.com

Control

• Execution Counting

• Exit Counting

• Recompilation

Page 106: Pizlo Speculation in JSC Slides - filpizlo.com

Execution Counting

Page 107: Pizlo Speculation in JSC Slides - filpizlo.com

Case Execution Count Increment Amount

Function Call 15

Loop Back Edge 1

Page 108: Pizlo Speculation in JSC Slides - filpizlo.com

Execution Count Thresholds for Tier-up

Tier-up Case Required Count for Tier-up

LLInt → Baseline 500

Baseline → DFG 1000

DFG → FTL 100000

Page 109: Pizlo Speculation in JSC Slides - filpizlo.com

Execution Count Thresholds for Tier-up

Tier-up Case Required Count for Tier-up

LLInt → Baseline

Baseline → DFG 1000

DFG → FTL 100000

Was Optimized?

Don’t Know Yes No

Count 500 250 2000

Page 110: Pizlo Speculation in JSC Slides - filpizlo.com

Execution Count Thresholds for Tier-up

Tier-up Case Required Count for Tier-up

LLInt → Baseline

Baseline → DFG1000 × (0.825914 +

0.061504 √S + 1.02406) ×2R × M/(M-U)

DFG → FTL 100000

Was Optimized?

Don’t Know Yes No

Count 500 250 2000

Page 111: Pizlo Speculation in JSC Slides - filpizlo.com

Execution Count Thresholds for Tier-up

Tier-up Case Required Count for Tier-up

LLInt → Baseline

Baseline → DFG1000 × (0.825914 +

0.061504 √S + 1.02406) ×2R × M/(M-U)

DFG → FTL 100000

Was Optimized?

Don’t Know Yes No

Count 500 250 2000

Page 112: Pizlo Speculation in JSC Slides - filpizlo.com

Execution Count Thresholds for Tier-up

Tier-up Case Required Count for Tier-up

LLInt → Baseline

Baseline → DFG1000 × (0.825914 +

0.061504 √S + 1.02406) ×2R × M/(M-U)

DFG → FTL 100000

Was Optimized?

Don’t Know Yes No

Count 500 250 2000

Page 113: Pizlo Speculation in JSC Slides - filpizlo.com

Execution Count Thresholds for Tier-up

Tier-up Case Required Count for Tier-up

LLInt → Baseline

Baseline → DFG1000 × (0.825914 +

0.061504 √S + 1.02406) ×2R × M/(M-U)

DFG → FTL 100000

Was Optimized?

Don’t Know Yes No

Count 500 250 2000

Page 114: Pizlo Speculation in JSC Slides - filpizlo.com

Execution Count Thresholds for Tier-up

Tier-up Case Required Count for Tier-up

LLInt → Baseline

Baseline → DFG1000 × (0.825914 +

0.061504 √S + 1.02406) ×2R × M/(M-U)

DFG → FTL100000 × (0.825914 +

0.061504 √S + 1.02406) ×2R × M/(M-U)

Was Optimized?

Don’t Know Yes No

Count 500 250 2000

Page 115: Pizlo Speculation in JSC Slides - filpizlo.com

Exit Count Thresholds for Jettison

Exit Case Required Count for Jettison

Normal Exit 100 × 2R

Exit that gets stuck in a loop 5 × 2R

Page 116: Pizlo Speculation in JSC Slides - filpizlo.com

Jettison and

Recompile

Page 117: Pizlo Speculation in JSC Slides - filpizlo.com

Another Example: _handlePropertyAccessExpression#D5n0Sd

Page 118: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

function (result, node){ result.possibleGetOverloads = node.possibleGetOverloads; result.possibleSetOverloads = node.possibleSetOverloads; result.possibleAndOverloads = node.possibleAndOverloads; result.baseType = Node.visit(node.baseType, this); result.callForGet = Node.visit(node.callForGet, this); result.resultTypeForGet = Node.visit(node.resultTypeForGet, this); result.callForAnd = Node.visit(node.callForAnd, this); result.resultTypeForAnd = Node.visit(node.resultTypeForAnd, this); result.callForSet = Node.visit(node.callForSet, this); result.errorForSet = node.errorForSet; result.updateCalls();}

Page 119: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Page 120: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

Page 121: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

neDFG

Page 122: Pizlo Speculation in JSC Slides - filpizlo.com

function (result, node){ checkType(this, 𝛕) …}

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

neDFG

exit 1

01 tim

es at

bc#0

Page 123: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

onDFG

Page 124: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

onDFG

DFG

Page 125: Pizlo Speculation in JSC Slides - filpizlo.com

function (result, node){ … checkType(result, 𝛔) …}

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

onDFG

exit 2

times

at bc#

18

DFG

Page 126: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

on

exit 2

times

at bc#

18

FTLDFG

DFG

Page 127: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

on

exit 2

times

at bc#

18

jettis

on due

to w

atchp

oint

DFGFTL

DFG

Page 128: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

on

exit 2

times

at bc#

18

jettis

on due

to w

atchp

oint

DFGDFG

FTLDFG

Page 129: Pizlo Speculation in JSC Slides - filpizlo.com

function (result, node){ … checkType(result, 𝛔) …}

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

on

exit 2

times

at bc#

18

jettis

on due

to w

atchp

oint

DFG

exit 7

times

at bc#

18

DFGFTL

DFG

Page 130: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

on

exit 2

times

at bc#

18

jettis

on due

to w

atchp

oint

exit 7

times

at bc#

18

FTLDFG

FTLDFG

DFG

Page 131: Pizlo Speculation in JSC Slides - filpizlo.com

function (result, node){ … checkType(node, 𝛖) …}

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

on

exit 2

times

at bc#

18

jettis

on due

to w

atchp

oint

exit 7

times

at bc#

18

FTL

exit 4

02 tim

es at

bc#13

DFGFTL

DFGDFG

Page 132: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

on

exit 2

times

at bc#

18

jettis

on due

to w

atchp

oint

exit 7

times

at bc#

18

exit 4

02 tim

es at

bc#13

jettis

onDFG

FTLFTL

DFGDFG

Page 133: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

on

exit 2

times

at bc#

18

jettis

on due

to w

atchp

oint

exit 7

times

at bc#

18

exit 4

02 tim

es at

bc#13

jettis

onDFG

DFGFTL

FTLDFG

DFG

Page 134: Pizlo Speculation in JSC Slides - filpizlo.com

_handlePropertyAccessExpression#D5n0Sd

time

Baseli

ne

exit 1

01 tim

es at

bc#0

jettis

on

exit 2

times

at bc#

18

jettis

on due

to w

atchp

oint

exit 7

times

at bc#

18

exit 4

02 tim

es at

bc#13

jettis

onFTL

DFGFTL

FTLDFG

DFGDFG

Page 135: Pizlo Speculation in JSC Slides - filpizlo.com

Control

• Execution Counting

• Exit Counting

• Recompilation

Page 136: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 137: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 138: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

• Non-speculative execution engine(s)

• Profiling

Page 139: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

latency throughput

Page 140: Pizlo Speculation in JSC Slides - filpizlo.com

Low Level Interpretermacro llintJumpTrueOrFalseOp(name, op, conditionOp) llintOpWithJump(op_%name%, op, macro (size, get, jump, dispatch) get(condition, t1) loadConstantOrVariable(size, t1, t0) btqnz t0, ~0xf, .slow conditionOp(t0, .target) dispatch()

.target: jump(target)

.slow: callSlowPath(_llint_slow_path_%name%) nextInstruction() end)end

Page 141: Pizlo Speculation in JSC Slides - filpizlo.com

Low Level Interpretermacro llintJumpTrueOrFalseOp(name, op, conditionOp) llintOpWithJump(op_%name%, op, macro (size, get, jump, dispatch) get(condition, t1) loadConstantOrVariable(size, t1, t0) btqnz t0, ~0xf, .slow conditionOp(t0, .target) dispatch()

.target: jump(target)

.slow: callSlowPath(_llint_slow_path_%name%) nextInstruction() end)end

Page 142: Pizlo Speculation in JSC Slides - filpizlo.com

Baseline JIT [ 7] add loc6, arg1, arg2 0x2f8084601a65: mov 0x30(%rbp), %rsi 0x2f8084601a69: mov 0x38(%rbp), %rdx 0x2f8084601a6d: cmp %r14, %rsi 0x2f8084601a70: jb 0x2f8084601af2 0x2f8084601a76: cmp %r14, %rdx 0x2f8084601a79: jb 0x2f8084601af2 0x2f8084601a7f: mov %esi, %eax 0x2f8084601a81: add %edx, %eax 0x2f8084601a83: jo 0x2f8084601af2 0x2f8084601a89: or %r14, %rax 0x2f8084601a8c: mov %rax, -0x38(%rbp)

Page 143: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Goals

• Cheap

• Useful

Page 144: Pizlo Speculation in JSC Slides - filpizlo.com

Useful Profiling

• Speculation is a bet.

• Profiling makes it a value bet.

Page 145: Pizlo Speculation in JSC Slides - filpizlo.com

Winning in the Average

Variable Meaning

p Probability of Winning

B Benefit of winning (positive)

C Cost of losing (positive)

Expected Value of Bet = p × B - (1 - p) × C

Page 146: Pizlo Speculation in JSC Slides - filpizlo.com

Winning in the Average

Good bet iff p × B - (1 - p) × C > 0

Variable Meaning

p Probability of Winning

B Benefit of winning (positive)

C Cost of losing (positive)

Page 147: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Page 148: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

Page 149: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Execution Time = (3.97 ns) × (Bytecodes in LLInt)

+ (1.71 ns) × (Bytecodes in Baseline)

+ (0.349 ns) × (Bytecodes in DFG)

+ (0.225 ns) × (Bytecodes in FTL)

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

Page 150: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Execution Time = (3.97 ns) × (Bytecodes in LLInt)

+ (1.71 ns) × (Bytecodes in Baseline)

+ (0.349 ns) × (Bytecodes in DFG)

+ (0.225 ns) × (Bytecodes in FTL)

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

B < 1.71 - 0.225 = 1.48 ns

Page 151: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Execution Time = (3.97 ns) × (Bytecodes in LLInt)

+ (1.71 ns) × (Bytecodes in Baseline)

+ (0.349 ns) × (Bytecodes in DFG)

+ (0.225 ns) × (Bytecodes in FTL)

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

B < 1.71 - 0.225 = 1.48 ns

Page 152: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Execution Time = (3.97 ns) × (Bytecodes in LLInt)

+ (1.71 ns) × (Bytecodes in Baseline)

+ (0.349 ns) × (Bytecodes in DFG)

+ (0.225 ns) × (Bytecodes in FTL)

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

B < 1.71 - 0.225 = 1.48 ns

Page 153: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Execution Time = (3.97 ns) × (Bytecodes in LLInt)

+ (1.71 ns) × (Bytecodes in Baseline)

+ (0.349 ns) × (Bytecodes in DFG)

+ (0.225 ns) × (Bytecodes in FTL)

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

B < 1.71 - 0.225 = 1.48 ns

< 1.48 ns

Page 154: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

C = (OSR exit cost) + (Bytecodes before reentry) × B + (Recompile Cost) / (exits to recompile)

< 1.48 ns

Page 155: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

C = (OSR exit cost) + (Bytecodes before reentry) × B + (Recompile Cost) / (exits to recompile)

< 1.48 ns

DFG ~ 2499 ns

Page 156: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

C = (OSR exit cost) + (Bytecodes before reentry) × B + (Recompile Cost) / (exits to recompile)

< 1.48 ns

DFG ~ 2499 nsFTL ~ 9998 ns

Page 157: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

C = (OSR exit cost) + (Bytecodes before reentry) × B + (Recompile Cost) / (exits to recompile)

< 1.48 ns

DFG ~ 2499 nsFTL ~ 9998 ns

Good speculation iff p > 0.9994

Page 158: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at SpeculationGood speculation iff p × B - (1 - p) × C > 0

Variable Meaning Likely Value

p Probability of Winning

B Time Saved by Speculation

C Time Lost by Speculation Failure

C = (OSR exit cost) + (Bytecodes before reentry) × B + (Recompile Cost) / (exits to recompile)

< 1.48 ns

DFG ~ 2499 ns

Good speculation iff p ~ 1

FTL ~ 9998 ns

Page 159: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at Speculation

Only speculate if we believe that we will win every time.

Page 160: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at Speculation

Profiling should record counterexamples to useful speculations.

Page 161: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at Speculation

Profiling should run for a long time.

Page 162: Pizlo Speculation in JSC Slides - filpizlo.com

Winning at Speculation

Don’t stress when speculation fails, unless it fails in the average.

Page 163: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Sources in JSC• Case Flags — branch speculation

• Case Counts — branch speculation

• Value Profiling — type inference of values

• Inline Caches — flow-sensitive type inference

• Watchpoints — heap speculation

• Exit Flags — speculation backoff

Page 164: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Sources in JSC• Case Flags — branch speculation

• Case Counts — branch speculation

• Value Profiling — type inference of values

• Inline Caches — type inference of object structure

• Watchpoints — heap speculation

• Exit Flags — speculation backoff

Page 165: Pizlo Speculation in JSC Slides - filpizlo.com

Case Flags

Case flag = tells if a counterexample to a speculation ever happened.

Page 166: Pizlo Speculation in JSC Slides - filpizlo.com

Case Flagsclass StructureStubInfo { …

ALWAYS_INLINE bool considerCaching( CodeBlock* codeBlock, Structure* structure) { // We never cache non-cells. if (!structure) { sawNonCell = true; return false; } …

Page 167: Pizlo Speculation in JSC Slides - filpizlo.com

Case Flags

void ArithProfile::emitSetDouble(CCallHelpers& jit) const{ if (shouldEmitSetDouble()) jit.or32( CCallHelpers::TrustedImm32( ArithProfile::Int32Overflow | ArithProfile::Int52Overflow | ArithProfile::NegZeroDouble | ArithProfile::NonNegZeroDouble), CCallHelpers::AbsoluteAddress(addressOfBits()));}

Page 168: Pizlo Speculation in JSC Slides - filpizlo.com

Why infer int32?

Page 169: Pizlo Speculation in JSC Slides - filpizlo.com

template<typename T, typename U>void multiply(Mat<T>& result, const Mat<T>& left, const Mat<T>& right){ for (U resultColumn = result.numColumns(); resultColumn--;) { for (U resultRow = result.numRows(); resultRow--;) { T& resultCell = result.at(resultRow, resultColumn); resultCell = T(); for (U i = left.numColumns(); i--;) { resultCell += left.at(resultRow, i) * right.at(i, resultColumn); } } }}

Page 170: Pizlo Speculation in JSC Slides - filpizlo.com

template<typename T, typename U>void multiply(Mat<T>& result, const Mat<T>& left, const Mat<T>& right){ for (U resultColumn = result.numColumns(); resultColumn--;) { for (U resultRow = result.numRows(); resultRow--;) { T& resultCell = result.at(resultRow, resultColumn); resultCell = T(); for (U i = left.numColumns(); i--;) { resultCell += left.at(resultRow, i) * right.at(i, resultColumn); } } }}

10x10 matrix multiply with different element types

Nan

osec

onds

to m

ultip

ly

10x1

0 m

atrix

0

200

400

600

800

1000

1200

int double CheckedInt

Page 171: Pizlo Speculation in JSC Slides - filpizlo.com

template<typename T, typename U>void multiply(Mat<T>& result, const Mat<T>& left, const Mat<T>& right){ for (U resultColumn = result.numColumns(); resultColumn--;) { for (U resultRow = result.numRows(); resultRow--;) { T& resultCell = result.at(resultRow, resultColumn); resultCell = T(); for (U i = left.numColumns(); i--;) { resultCell += left.at(resultRow, i) * right.at(i, resultColumn); } } }}

10x10 matrix multiply with different element types

Nan

osec

onds

to m

ultip

ly

10x1

0 m

atrix

0

200

400

600

800

1000

1200

int double CheckedInt

10x10 int matrix multiply with different index types

Nan

osec

onds

to m

ultip

ly

10x1

0 m

atrix

0

250

500

750

1000

1250

1500

1750

2000

int double CheckedInt

Page 172: Pizlo Speculation in JSC Slides - filpizlo.com

template<typename T, typename U>void multiply(Mat<T>& result, const Mat<T>& left, const Mat<T>& right){ for (U resultColumn = result.numColumns(); resultColumn--;) { for (U resultRow = result.numRows(); resultRow--;) { T& resultCell = result.at(resultRow, resultColumn); resultCell = T(); for (U i = left.numColumns(); i--;) { resultCell += left.at(resultRow, i) * right.at(i, resultColumn); } } }}

10x10 matrix multiply with different element types

Nan

osec

onds

to m

ultip

ly

10x1

0 m

atrix

0

200

400

600

800

1000

1200

int double CheckedInt

10x10 int matrix multiply with different index types

Nan

osec

onds

to m

ultip

ly

10x1

0 m

atrix

0

250

500

750

1000

1250

1500

1750

2000

int double CheckedInt

Page 173: Pizlo Speculation in JSC Slides - filpizlo.com

Use Int32 whenever possible to avoid future double→int conversions

Page 174: Pizlo Speculation in JSC Slides - filpizlo.com

Case Flags Example: AddProfiling Tier

int32_t left = …;int32_t right = …;ArithProfile* profile = …;int32_t intResult;JSValue result;if (UNLIKELY(addOverflowed( left, right, &intResult))) { result = jsNumber( double(left) + double(right)); profile->setObservedInt32Overflow();} else result = jsNumber(intResult);

Page 175: Pizlo Speculation in JSC Slides - filpizlo.com

Case Flags Example: AddProfiling Tier

int32_t left = …;int32_t right = …;ArithProfile* profile = …;int32_t intResult;JSValue result;if (UNLIKELY(addOverflowed( left, right, &intResult))) { result = jsNumber( double(left) + double(right)); profile->setObservedInt32Overflow();} else result = jsNumber(intResult);

Page 176: Pizlo Speculation in JSC Slides - filpizlo.com

Case Flags Example: AddProfiling Tier

int32_t left = …;int32_t right = …;ArithProfile* profile = …;int32_t intResult;JSValue result;if (UNLIKELY(addOverflowed( left, right, &intResult))) { result = jsNumber( double(left) + double(right)); profile->setObservedInt32Overflow();} else result = jsNumber(intResult);

Page 177: Pizlo Speculation in JSC Slides - filpizlo.com

Case Flags Example: AddProfiling Tier

int32_t left = …;int32_t right = …;ArithProfile* profile = …;int32_t intResult;JSValue result;if (UNLIKELY(addOverflowed( left, right, &intResult))) { result = jsNumber( double(left) + double(right)); profile->setObservedInt32Overflow();} else result = jsNumber(intResult);

Page 178: Pizlo Speculation in JSC Slides - filpizlo.com

Case Flags Example: AddProfiling Tier Optimizing Tier

int32_t left = …;int32_t right = …;ArithProfile* profile = …;int32_t intResult;JSValue result;if (UNLIKELY(addOverflowed( left, right, &intResult))) { result = jsNumber( double(left) + double(right)); profile->setObservedInt32Overflow();} else result = jsNumber(intResult);

// if !profile->didObserveInt32Overflow()

int32_t left = …;int32_t right = …;int32_t result;speculate(!addOverflowed( left, right, &result));

Page 179: Pizlo Speculation in JSC Slides - filpizlo.com

Case Flags Example: AddProfiling Tier Optimizing Tier

int32_t left = …;int32_t right = …;ArithProfile* profile = …;int32_t intResult;JSValue result;if (UNLIKELY(addOverflowed( left, right, &intResult))) { result = jsNumber( double(left) + double(right)); profile->setObservedInt32Overflow();} else result = jsNumber(intResult);

// if profile->didObserveInt32Overflow()

double left =…;double right = …;double result = left + right;

Page 180: Pizlo Speculation in JSC Slides - filpizlo.com

Case Counts

RareCaseProfile* rareCaseProfile = 0;if (shouldEmitProfiling()) { rareCaseProfile = m_codeBlock->addRareCaseProfile(m_bytecodeOffset);}…if (shouldEmitProfiling()) { add32( TrustedImm32(1), AbsoluteAddress(&rareCaseProfile->m_counter));}

Page 181: Pizlo Speculation in JSC Slides - filpizlo.com

Rare Case Count Thresholds

Case Count Threshold Action

this conversion 10 Assume this is exotic.

arithmetic slow path 20 Assume integer math overflowed to double.

Page 182: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Sources in JSC• Case Flags — branch speculation

• Case Counts — branch speculation

• Value Profiling — type inference of values

• Inline Caches — type inference of object structure

• Watchpoints — heap speculation

• Exit Flags — speculation backoff

Page 183: Pizlo Speculation in JSC Slides - filpizlo.com

Value Profiling

macro valueProfile(op, metadata, value) storeq value, %op%::Metadata::profile.m_buckets[metadata]end

Page 184: Pizlo Speculation in JSC Slides - filpizlo.com

Value Profiling Idea

• Use static analysis whenever possible.

• Value profiling fills in the blanks:

- loads

- calls

- etc

Page 185: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

Add

left right

Page 186: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

Add

left rightInt32 Int32

Page 187: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

Add

left rightInt32 Int32

Int32

Page 188: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

Add

left rightDouble Double

Page 189: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

Add

left rightDouble Double

Double

Page 190: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

Add

left rightInt32 Double

Page 191: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

Add

left rightInt32 Double

Double

Page 192: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

GetByVal

array index Int32

Page 193: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

GetByVal

array index Int32Int32Array

Page 194: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

GetByVal

array index Int32

Int32

Int32Array

Page 195: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

GetByVal

array index Int32Float64Array

Page 196: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

GetByVal

array index Int32Float64Array

Double

Page 197: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

GetByVal

array index Int32JSObject

Page 198: Pizlo Speculation in JSC Slides - filpizlo.com

Prediction Propagation

GetByVal

array index Int32JSObject

???

Page 199: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

Page 200: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

Page 201: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

predictionNone

Page 202: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

predictionNone

42

Page 203: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

predictionNone

100

Page 204: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

predictionNone

25

Page 205: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

predictionNone

7

Page 206: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

predictionNone

7

CodeBlock::updateAllPredictions()ValueProfile::computeUpdatedPrediction()

Page 207: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

prediction

7

CodeBlock::updateAllPredictions()ValueProfile::computeUpdatedPrediction()

Int32

Page 208: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

prediction

CodeBlock::updateAllPredictions()ValueProfile::computeUpdatedPrediction()

Int32

Page 209: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

prediction

CodeBlock::updateAllPredictions()ValueProfile::computeUpdatedPrediction()

Int32

643

Page 210: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

prediction

CodeBlock::updateAllPredictions()ValueProfile::computeUpdatedPrediction()

Int32

92

Page 211: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

prediction

CodeBlock::updateAllPredictions()ValueProfile::computeUpdatedPrediction()

Int32

98.23

Page 212: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

prediction

CodeBlock::updateAllPredictions()ValueProfile::computeUpdatedPrediction()

Int32

98.23

Page 213: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

prediction

CodeBlock::updateAllPredictions()ValueProfile::computeUpdatedPrediction()

98.23

Int32|Double

Page 214: Pizlo Speculation in JSC Slides - filpizlo.com

llintOpWithMetadata( op_get_by_val, OpGetByVal, macro (size, get, dispatch, metadata, return) macro finishGetByVal(result, scratch) get(dst, scratch) storeq result, [cfr, scratch, 8] valueProfile(OpGetByVal, t5, result) dispatch() end

Value Profiling Example

ValueProfile

bucket

prediction

CodeBlock::updateAllPredictions()ValueProfile::computeUpdatedPrediction()

Int32|Double

Page 215: Pizlo Speculation in JSC Slides - filpizlo.com

Value Profiling

• Combined with prediction propagation

• Provides predicted type inference

Page 216: Pizlo Speculation in JSC Slides - filpizlo.com

Speculated TypesFinalObject Array FunctionWithDefault

HasInstanceFunctionWithNon

DefaultHasInstance Int8Array

Int16Array Int32Array Uint8Array Uint8ClampedArray Uint16Array

Uint32Array Float32Array Float64Array DirectArguments ScopedArguments

StringObject RegExpObject MapObject SetObject WeakMapObject

WeakSetObject ProxyObject DerivedArray ObjectOther StringIdent

StringVar Symbol CellOther BoolInt32 NonBoolInt32

Int52Only AnyIntAsDouble NonIntAsDouble DoublePureNaN DoubleImpureNaN

Boolean Other Empty BigInt DataViewObject

Page 217: Pizlo Speculation in JSC Slides - filpizlo.com

Speculated TypesFinalObject Array FunctionWithDefault

HasInstanceFunctionWithNon

DefaultHasInstance Int8Array

Int16Array Int32Array Uint8Array Uint8ClampedArray Uint16Array

Uint32Array Float32Array Float64Array DirectArguments ScopedArguments

StringObject RegExpObject MapObject SetObject WeakMapObject

WeakSetObject ProxyObject DerivedArray ObjectOther StringIdent

StringVar Symbol CellOther BoolInt32 NonBoolInt32

Int52Only AnyIntAsDouble NonIntAsDouble DoublePureNaN DoubleImpureNaN

Boolean Other Empty BigInt DataViewObject

Page 218: Pizlo Speculation in JSC Slides - filpizlo.com

Speculated TypesFinalObject Array FunctionWithDefault

HasInstanceFunctionWithNon

DefaultHasInstance Int8Array

Int16Array Int32Array Uint8Array Uint8ClampedArray Uint16Array

Uint32Array Float32Array Float64Array DirectArguments ScopedArguments

StringObject RegExpObject MapObject SetObject WeakMapObject

WeakSetObject ProxyObject DerivedArray ObjectOther StringIdent

StringVar Symbol CellOther BoolInt32 NonBoolInt32

Int52Only AnyIntAsDouble NonIntAsDouble DoublePureNaN DoubleImpureNaN

Boolean Other Empty BigInt DataViewObject

Page 219: Pizlo Speculation in JSC Slides - filpizlo.com

Speculated TypesFinalObject Array FunctionWithDefault

HasInstanceFunctionWithNon

DefaultHasInstance Int8Array

Int16Array Int32Array Uint8Array Uint8ClampedArray Uint16Array

Uint32Array Float32Array Float64Array DirectArguments ScopedArguments

StringObject RegExpObject MapObject SetObject WeakMapObject

WeakSetObject ProxyObject DerivedArray ObjectOther StringIdent

StringVar Symbol CellOther BoolInt32 NonBoolInt32

Int52Only AnyIntAsDouble NonIntAsDouble DoublePureNaN DoubleImpureNaN

Boolean Other Empty BigInt DataViewObject

Page 220: Pizlo Speculation in JSC Slides - filpizlo.com

Speculated TypesFinalObject Array FunctionWithDefault

HasInstanceFunctionWithNon

DefaultHasInstance Int8Array

Int16Array Int32Array Uint8Array Uint8ClampedArray Uint16Array

Uint32Array Float32Array Float64Array DirectArguments ScopedArguments

StringObject RegExpObject MapObject SetObject WeakMapObject

WeakSetObject ProxyObject DerivedArray ObjectOther StringIdent

StringVar Symbol CellOther BoolInt32 NonBoolInt32

Int52Only AnyIntAsDouble NonIntAsDouble DoublePureNaN DoubleImpureNaN

Boolean Other Empty BigInt DataViewObject

Page 221: Pizlo Speculation in JSC Slides - filpizlo.com

Speculating On Speculated Type

CompareEq(Boolean:@left, Boolean:@right)CompareEq(Int32:@left, Int32:@right)CompareEq(Int32:BooleanToNumber(Boolean:@left), Int32:@right)CompareEq(Int32:BooleanToNumber(Untyped:@left), Int32:@right)CompareEq(Int32:@left, Int32:BooleanToNumber(Boolean:@right))CompareEq(Int32:@left, Int32:BooleanToNumber(Untyped:@right))CompareEq(Int52Rep:@left, Int52Rep:@right)CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Int52:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Number:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(NotCell:@right))CompareEq(DoubleRep:DoubleRep(RealNumber:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:…, DoubleRep:…)CompareEq(StringIdent:@left, StringIdent:@right)CompareEq(String:@left, String:@right)CompareEq(Symbol:@left, Symbol:@right)CompareEq(Object:@left, Object:@right)CompareEq(Other:@left, Untyped:@right)CompareEq(Untyped:@left, Other:@right)CompareEq(Object:@left, ObjectOrOther:@right)CompareEq(ObjectOrOther:@left, Object:@right)CompareEq(Untyped:@left, Untyped:@right)

Page 222: Pizlo Speculation in JSC Slides - filpizlo.com

Speculating On Speculated Type

CompareEq(Boolean:@left, Boolean:@right)CompareEq(Int32:@left, Int32:@right)CompareEq(Int32:BooleanToNumber(Boolean:@left), Int32:@right)CompareEq(Int32:BooleanToNumber(Untyped:@left), Int32:@right)CompareEq(Int32:@left, Int32:BooleanToNumber(Boolean:@right))CompareEq(Int32:@left, Int32:BooleanToNumber(Untyped:@right))CompareEq(Int52Rep:@left, Int52Rep:@right)CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Int52:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Number:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(NotCell:@right))CompareEq(DoubleRep:DoubleRep(RealNumber:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:…, DoubleRep:…)CompareEq(StringIdent:@left, StringIdent:@right)CompareEq(String:@left, String:@right)CompareEq(Symbol:@left, Symbol:@right)CompareEq(Object:@left, Object:@right)CompareEq(Other:@left, Untyped:@right)CompareEq(Untyped:@left, Other:@right)CompareEq(Object:@left, ObjectOrOther:@right)CompareEq(ObjectOrOther:@left, Object:@right)CompareEq(Untyped:@left, Untyped:@right)

Page 223: Pizlo Speculation in JSC Slides - filpizlo.com

Speculating On Speculated Type

CompareEq(Boolean:@left, Boolean:@right)CompareEq(Int32:@left, Int32:@right)CompareEq(Int32:BooleanToNumber(Boolean:@left), Int32:@right)CompareEq(Int32:BooleanToNumber(Untyped:@left), Int32:@right)CompareEq(Int32:@left, Int32:BooleanToNumber(Boolean:@right))CompareEq(Int32:@left, Int32:BooleanToNumber(Untyped:@right))CompareEq(Int52Rep:@left, Int52Rep:@right)CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Int52:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Number:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(NotCell:@right))CompareEq(DoubleRep:DoubleRep(RealNumber:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:…, DoubleRep:…)CompareEq(StringIdent:@left, StringIdent:@right)CompareEq(String:@left, String:@right)CompareEq(Symbol:@left, Symbol:@right)CompareEq(Object:@left, Object:@right)CompareEq(Other:@left, Untyped:@right)CompareEq(Untyped:@left, Other:@right)CompareEq(Object:@left, ObjectOrOther:@right)CompareEq(ObjectOrOther:@left, Object:@right)CompareEq(Untyped:@left, Untyped:@right)

Page 224: Pizlo Speculation in JSC Slides - filpizlo.com

Speculating On Speculated Type

CompareEq(Boolean:@left, Boolean:@right)CompareEq(Int32:@left, Int32:@right)CompareEq(Int32:BooleanToNumber(Boolean:@left), Int32:@right)CompareEq(Int32:BooleanToNumber(Untyped:@left), Int32:@right)CompareEq(Int32:@left, Int32:BooleanToNumber(Boolean:@right))CompareEq(Int32:@left, Int32:BooleanToNumber(Untyped:@right))CompareEq(Int52Rep:@left, Int52Rep:@right)CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Int52:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Number:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(NotCell:@right))CompareEq(DoubleRep:DoubleRep(RealNumber:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:…, DoubleRep:…)CompareEq(StringIdent:@left, StringIdent:@right)CompareEq(String:@left, String:@right)CompareEq(Symbol:@left, Symbol:@right)CompareEq(Object:@left, Object:@right)CompareEq(Other:@left, Untyped:@right)CompareEq(Untyped:@left, Other:@right)CompareEq(Object:@left, ObjectOrOther:@right)CompareEq(ObjectOrOther:@left, Object:@right)CompareEq(Untyped:@left, Untyped:@right)

Page 225: Pizlo Speculation in JSC Slides - filpizlo.com

Speculating On Speculated Type

CompareEq(Boolean:@left, Boolean:@right)CompareEq(Int32:@left, Int32:@right)CompareEq(Int32:BooleanToNumber(Boolean:@left), Int32:@right)CompareEq(Int32:BooleanToNumber(Untyped:@left), Int32:@right)CompareEq(Int32:@left, Int32:BooleanToNumber(Boolean:@right))CompareEq(Int32:@left, Int32:BooleanToNumber(Untyped:@right))CompareEq(Int52Rep:@left, Int52Rep:@right)CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Int52:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Number:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(NotCell:@right))CompareEq(DoubleRep:DoubleRep(RealNumber:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:…, DoubleRep:…)CompareEq(StringIdent:@left, StringIdent:@right)CompareEq(String:@left, String:@right)CompareEq(Symbol:@left, Symbol:@right)CompareEq(Object:@left, Object:@right)CompareEq(Other:@left, Untyped:@right)CompareEq(Untyped:@left, Other:@right)CompareEq(Object:@left, ObjectOrOther:@right)CompareEq(ObjectOrOther:@left, Object:@right)CompareEq(Untyped:@left, Untyped:@right)

Page 226: Pizlo Speculation in JSC Slides - filpizlo.com

Speculating On Speculated Type

CompareEq(Boolean:@left, Boolean:@right)CompareEq(Int32:@left, Int32:@right)CompareEq(Int32:BooleanToNumber(Boolean:@left), Int32:@right)CompareEq(Int32:BooleanToNumber(Untyped:@left), Int32:@right)CompareEq(Int32:@left, Int32:BooleanToNumber(Boolean:@right))CompareEq(Int32:@left, Int32:BooleanToNumber(Untyped:@right))CompareEq(Int52Rep:@left, Int52Rep:@right)CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Int52:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Number:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(NotCell:@right))CompareEq(DoubleRep:DoubleRep(RealNumber:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:…, DoubleRep:…)CompareEq(StringIdent:@left, StringIdent:@right)CompareEq(String:@left, String:@right)CompareEq(Symbol:@left, Symbol:@right)CompareEq(Object:@left, Object:@right)CompareEq(Other:@left, Untyped:@right)CompareEq(Untyped:@left, Other:@right)CompareEq(Object:@left, ObjectOrOther:@right)CompareEq(ObjectOrOther:@left, Object:@right)CompareEq(Untyped:@left, Untyped:@right)

Page 227: Pizlo Speculation in JSC Slides - filpizlo.com

Speculating On Speculated Type

CompareEq(Boolean:@left, Boolean:@right)CompareEq(Int32:@left, Int32:@right)CompareEq(Int32:BooleanToNumber(Boolean:@left), Int32:@right)CompareEq(Int32:BooleanToNumber(Untyped:@left), Int32:@right)CompareEq(Int32:@left, Int32:BooleanToNumber(Boolean:@right))CompareEq(Int32:@left, Int32:BooleanToNumber(Untyped:@right))CompareEq(Int52Rep:@left, Int52Rep:@right)CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Int52:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(Number:@right))CompareEq(DoubleRep:DoubleRep(Int52:@left), DoubleRep:DoubleRep(NotCell:@right))CompareEq(DoubleRep:DoubleRep(RealNumber:@left), DoubleRep:DoubleRep(RealNumber:@right))CompareEq(DoubleRep:…, DoubleRep:…)CompareEq(StringIdent:@left, StringIdent:@right)CompareEq(String:@left, String:@right)CompareEq(Symbol:@left, Symbol:@right)CompareEq(Object:@left, Object:@right)CompareEq(Other:@left, Untyped:@right)CompareEq(Untyped:@left, Other:@right)CompareEq(Object:@left, ObjectOrOther:@right)CompareEq(ObjectOrOther:@left, Object:@right)CompareEq(Untyped:@left, Untyped:@right)

Page 228: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Sources in JSC• Case Flags — branch speculation

• Case Counts — branch speculation

• Value Profiling — type inference of values

• Inline Caches — type inference of object structure

• Watchpoints — heap speculation

• Exit Flags — speculation backoff

Page 229: Pizlo Speculation in JSC Slides - filpizlo.com

{x: 1, y: 2}

{x: 42, y: 3}

{x: -5, y: 7}

Page 230: Pizlo Speculation in JSC Slides - filpizlo.com

{x: 1, y: 2}

{x: 42, y: 3}

{x: -5, y: 7}

var x = o.x;

Page 231: Pizlo Speculation in JSC Slides - filpizlo.com

{x: 1, y: 2}

{x: 42, y: 3}

{x: -5, y: 7}

o.x = x;

Page 232: Pizlo Speculation in JSC Slides - filpizlo.com

{1, 2}

{42, 3}

{-5, 7}

{x, y}

Page 233: Pizlo Speculation in JSC Slides - filpizlo.com

{1, 2}

{42, 3}

{-5, 7}

{x, y}

structure

Page 234: Pizlo Speculation in JSC Slides - filpizlo.com

{1, 2}

{42, 3}

{-5, 7}

{x, y}

structure

‣ hashtable

Page 235: Pizlo Speculation in JSC Slides - filpizlo.com

{1, 2}

{42, 3}

{-5, 7}

{x, y}

structure

‣ hashtable

‣ maps name to offset

Page 236: Pizlo Speculation in JSC Slides - filpizlo.com

{1, 2}

{42, 3}

{-5, 7}

{x, y}

structure

‣ hashtable

‣ maps name to offset

‣ hash-consed

Page 237: Pizlo Speculation in JSC Slides - filpizlo.com

Fast JSObject

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Page 238: Pizlo Speculation in JSC Slides - filpizlo.com

Fast JSObject

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Structure Table

Page 239: Pizlo Speculation in JSC Slides - filpizlo.com

Fast JSObject

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Structure Table

Structure

Page 240: Pizlo Speculation in JSC Slides - filpizlo.com

Fast JSObject

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Structure Table

Property Table

Structure

Page 241: Pizlo Speculation in JSC Slides - filpizlo.com

Fast JSObject

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Structure Table

Property Table

Structure

f: inline(0)

Page 242: Pizlo Speculation in JSC Slides - filpizlo.com

Fast JSObject

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Structure Table

Property Table

Structure

f: inline(0)

g: inline(1)

Page 243: Pizlo Speculation in JSC Slides - filpizlo.com

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Structure Table

Property Table

Structure

f: inline(0)

g: inline(1)

Page 244: Pizlo Speculation in JSC Slides - filpizlo.com

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Structure Table

Property Table

Structure

f: inline(0)

g: inline(1)

Page 245: Pizlo Speculation in JSC Slides - filpizlo.com

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Structure Table

Property Table

Structure

f: inline(0)

g: inline(1)

var v = o.f;

Page 246: Pizlo Speculation in JSC Slides - filpizlo.com

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Structure Table

Property Table

Structure

f: inline(0)

g: inline(1)

var v = o.f;

if (o->structureID == 42) v = o->inlineStorage[0]else v = slowGet(o, “f”)

Page 247: Pizlo Speculation in JSC Slides - filpizlo.com

“Inline Cache”

indexingtypeflags

cell state

structure ID: 42 null 0xffff000000000005

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

0xffff000000000006

Structure Table

Property Table

Structure

f: inline(0)

g: inline(1)

var v = o.f;

if (o->structureID == 42) v = o->inlineStorage[0]else v = slowGet(o, “f”)

Page 248: Pizlo Speculation in JSC Slides - filpizlo.com

Interpreter Inline Cache

get_by_id <result>, <base>, <properyName>

Page 249: Pizlo Speculation in JSC Slides - filpizlo.com

Interpreter Inline Cache

get_by_id <result>, <base>, <properyName>, <cachedStructureID>, <cachedOffset>

Page 250: Pizlo Speculation in JSC Slides - filpizlo.com

Interpreter Inline Cache

get_by_id loc42, loc43, “g”, 0, 0

Page 251: Pizlo Speculation in JSC Slides - filpizlo.com

Interpreter Inline Cache

get_by_id loc42, loc43, “g”, 0, 0

indexingtypeflags

cell state

structure ID: 42 null

f:0xffff000000000005

g:0xffff000000000006

Page 252: Pizlo Speculation in JSC Slides - filpizlo.com

Interpreter Inline Cache

get_by_id loc42, loc43, “g”, 42, 1

indexingtypeflags

cell state

structure ID: 42 null

f:0xffff000000000005

g:0xffff000000000006

Page 253: Pizlo Speculation in JSC Slides - filpizlo.com

JIT Inline Cache

0x46f8c30b9b0: mov 0x30(%rbp), %rax0x46f8c30b9b4: test %rax, %r150x46f8c30b9b7: jnz 0x46f8c30ba2c0x46f8c30b9bd: jmp 0x46f8c30ba2c0x46f8c30b9c2: o16 nop %cs:0x200(%rax,%rax)0x46f8c30b9d1: nop (%rax)0x46f8c30b9d4: mov %rax, -0x38(%rbp)

Page 254: Pizlo Speculation in JSC Slides - filpizlo.com

JIT Inline Cache

0x46f8c30b9b0: mov 0x30(%rbp), %rax0x46f8c30b9b4: test %rax, %r150x46f8c30b9b7: jnz 0x46f8c30ba2c0x46f8c30b9bd: jmp 0x46f8c30ba2c0x46f8c30b9c2: o16 nop %cs:0x200(%rax,%rax)0x46f8c30b9d1: nop (%rax)0x46f8c30b9d4: mov %rax, -0x38(%rbp)

Page 255: Pizlo Speculation in JSC Slides - filpizlo.com

JIT Inline Cache

0x46f8c30b9b0: mov 0x30(%rbp), %rax0x46f8c30b9b4: test %rax, %r150x46f8c30b9b7: jnz 0x46f8c30ba2c0x46f8c30b9bd: jmp 0x46f8c30ba2c0x46f8c30b9c2: o16 nop %cs:0x200(%rax,%rax)0x46f8c30b9d1: nop (%rax)0x46f8c30b9d4: mov %rax, -0x38(%rbp)

Page 256: Pizlo Speculation in JSC Slides - filpizlo.com

JIT Inline Cache

0x46f8c30b9b0: mov 0x30(%rbp), %rax0x46f8c30b9b4: test %rax, %r150x46f8c30b9b7: jnz 0x46f8c30ba2c0x46f8c30b9bd: cmp $0x125, (%rax)0x46f8c30b9c3: jnz 0x46f8c30ba2c0x46f8c30b9c9: mov 0x18(%rax), %rax0x46f8c30b9cd: nop 0x200(%rax)0x46f8c30b9d4: mov %rax, -0x38(%rbp)

Page 257: Pizlo Speculation in JSC Slides - filpizlo.com

Inline caches implicitly collect profiling information.

Page 258: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

get_by_idjmp Lslow jmp Lslow jmp Lslow

tmp = o.fS1:

{f, g}

Page 259: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

jmp Lslow jmp Lslow jmp Lslow

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

Page 260: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

jmp Lslow jmp Lslow

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

Page 261: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

jmp Lslow

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

Page 262: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

Page 263: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

get_by_id

tmp = o.fS1:

{f, g}

Page 264: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

Page 265: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

jmp Lslow

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

Page 266: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

Page 267: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

Page 268: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

Page 269: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

Page 270: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.f

get_by_id…, S1, 0

S1: {f, g}

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

Page 271: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

get_by_id

tmp = o.ftmp2 = o.g

S1: {f, g}

get_by_id

Page 272: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

get_by_id

Page 273: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

get_by_id…, S1, 1

Page 274: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

jmp Lslow

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

jmp Lslowget_by_id…, S1, 1

Page 275: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

jmp Lslowget_by_id…, S1, 1

Page 276: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

get_by_id…, S1, 1

cmp S1, (%rax)jnz Lslowmov 18(%rax), %rax

Page 277: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

get_by_id…, S1, 1

cmp S1, (%rax)jnz Lslowmov 18(%rax), %rax

Page 278: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

get_by_id…, S1, 1

CheckStructure(@o, S1)GetByOffset(@o, “g”, 1)

cmp S1, (%rax)jnz Lslowmov 18(%rax), %rax

Page 279: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

get_by_id…, S1, 1

CheckStructure(@o, S1)GetByOffset(@o, “g”, 1)

cmp S1, (%rax)jnz Lslowmov 18(%rax), %rax

Page 280: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

get_by_id…, S1, 1

CheckStructure(@o, S1)GetByOffset(@o, “g”, 1)

cmp S1, (%rax)jnz Lslowmov 18(%rax), %rax

Page 281: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

get_by_id…, S1, 1

CheckStructure(@o, S1)GetByOffset(@o, “g”, 1)

cmp S1, (%rax)jnz Lslowmov 18(%rax), %rax

Page 282: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

get_by_id…, S1, 1

CheckStructure(@o, S1)GetByOffset(@o, “g”, 1)

CheckStructure(@o, S1)GetByOffset(@o, “g”, 1)

cmp S1, (%rax)jnz Lslowmov 18(%rax), %rax

Page 283: Pizlo Speculation in JSC Slides - filpizlo.com

LLInt (interpreter)

Baseline (template JIT)

DFG (less optimizing JIT)

FTL (optimizing JIT)

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

tmp = o.ftmp2 = o.g

get_by_id…, S1, 0

S1: {f, g}

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

CheckStructure(@o, S1)GetByOffset(@o, “f”, 0)

get_by_id…, S1, 1

CheckStructure(@o, S1)GetByOffset(@o, “g”, 1)

CheckStructure(@o, S1)GetByOffset(@o, “g”, 1)

cmp S1, (%rax)jnz Lslowmov 18(%rax), %rax

Page 284: Pizlo Speculation in JSC Slides - filpizlo.com

Branch(Equal( @structure, $S1))

Load(@object, offset = 0x10) Call(slow path)

… things …

Branch(Equal( @structure, $S1))

Load(@object, offset = 0x18) Call(slow path)

… more things …

Inline Cache Control Flow

Page 285: Pizlo Speculation in JSC Slides - filpizlo.com

Branch(Equal( @structure, $S1))

Load(@object, offset = 0x10) Call(slow path)

… things …

Branch(Equal( @structure, $S1))

Load(@object, offset = 0x18) Call(slow path)

… more things …

not redundant!

Inline Cache Control Flow

Page 286: Pizlo Speculation in JSC Slides - filpizlo.com

Branch(Equal( @structure, $S1))

Load(@object, offset = 0x10) Call(slow path)

… things …

Branch(Equal( @structure, $S1))

Load(@object, offset = 0x18) Call(slow path)

… more things …

Branch(Equal( @structure, $S1))

OSR exit

Load(@object, offset = 0x10)

… things …

Branch(Equal( @structure, $S1))

Load(@object, offset = 0x18)

… more things …

OSR exit

Inline Cache Control Flow Inlined with OSR exits

Page 287: Pizlo Speculation in JSC Slides - filpizlo.com

Branch(Equal( @structure, $S1))

Load(@object, offset = 0x10) Call(slow path)

… things …

Branch(Equal( @structure, $S1))

Load(@object, offset = 0x18) Call(slow path)

… more things …

Branch(Equal( @structure, $S1))

OSR exit

Load(@object, offset = 0x10)

… things …

Load(@object, offset = 0x18)

… more things …

Inline Cache Control Flow Inlined with OSR exits

Page 288: Pizlo Speculation in JSC Slides - filpizlo.com

Minimorphic IC Inlining

var tmp = o.f;

Page 289: Pizlo Speculation in JSC Slides - filpizlo.com

Minimorphic IC Inlining

var tmp = o.f;

{f: 64, g:75}

S1: {f, g}

Page 290: Pizlo Speculation in JSC Slides - filpizlo.com

Minimorphic IC Inlining

var tmp = o.f;

{f: 64, g:75} {f: 54, g:75, h:389}

S1: {f, g}

S2: {f, g, h}

Page 291: Pizlo Speculation in JSC Slides - filpizlo.com

Minimorphic IC Inlining

var tmp = o.f;

{f: 64, g:75} {f: 54, g:75, h:389}

S1: {f, g}

S2: {f, g, h}

CheckStructure(@o, [S1, S2])GetByOffset(@o, “f”, 0)

Page 292: Pizlo Speculation in JSC Slides - filpizlo.com

Polymorphic IC Inlining

var tmp = o.f;

Page 293: Pizlo Speculation in JSC Slides - filpizlo.com

Polymorphic IC Inlining

var tmp = o.f;

{f: 64, g:75} {f: 54, g:75, h:389} {g: 37, f: 30}

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

Page 294: Pizlo Speculation in JSC Slides - filpizlo.com

Polymorphic IC Inlining

var tmp = o.f;

{f: 64, g:75} {f: 54, g:75, h:389} {g: 37, f: 30}

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

MultiGetByOffset(@o, “f”, [S1, S2] => 0, [S3] => 1)DFG IR:

Page 295: Pizlo Speculation in JSC Slides - filpizlo.com

Polymorphic IC Inlining

var tmp = o.f;

{f: 64, g:75} {f: 54, g:75, h:389} {g: 37, f: 30}

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

MultiGetByOffset(@o, “f”, [S1, S2] => 0, [S3] => 1)

if (o->structureID == S1 || o->structureID == S2) result = o->inlineStorage[0]else result = o->inlineStorage[1]

DFG IR:

B3 IR:

Page 296: Pizlo Speculation in JSC Slides - filpizlo.com
Page 297: Pizlo Speculation in JSC Slides - filpizlo.com

function foo(o) { return o.f; }

Page 298: Pizlo Speculation in JSC Slides - filpizlo.com

function foo(o) { return o.f; }

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

Page 299: Pizlo Speculation in JSC Slides - filpizlo.com

function foo(o) { return o.f; }

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

function bar(p) { return foo(p.g); }

Page 300: Pizlo Speculation in JSC Slides - filpizlo.com

function foo(o) { return o.f; }

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

function bar(p) { return foo(p.g); }

S1: {f, g}

Page 301: Pizlo Speculation in JSC Slides - filpizlo.com

function foo(o) { return o.f; }

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

function bar(p) { return foo(p.g); }

S1: {f, g}

DFG (less optimizing JIT)

Page 302: Pizlo Speculation in JSC Slides - filpizlo.com

function foo(o) { return o.f; }

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

function bar(p) { return foo(p.g); }

S1: {f, g}

DFG (less optimizing JIT)

…—> foo

<- foo

jmp Lslow

Page 303: Pizlo Speculation in JSC Slides - filpizlo.com

function foo(o) { return o.f; }

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

function bar(p) { return foo(p.g); }

S1: {f, g}

DFG (less optimizing JIT)

…—> foo

<- foo

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

Page 304: Pizlo Speculation in JSC Slides - filpizlo.com

function foo(o) { return o.f; }

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

function bar(p) { return foo(p.g); }

S1: {f, g}

DFG (less optimizing JIT)

…—> foo

<- foo

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

FTL (optimizing JIT)

Page 305: Pizlo Speculation in JSC Slides - filpizlo.com

function foo(o) { return o.f; }

S1: {f, g}

S2: {f, g, h}

S3: {g, f}

function bar(p) { return foo(p.g); }

S1: {f, g}

DFG (less optimizing JIT)

…—> foo

<- foo

cmp S1, (%rax)jnz Lslowmov 10(%rax), %rax

FTL (optimizing JIT)

…—> foo CheckStructure GetByOffset<- foo

Page 306: Pizlo Speculation in JSC Slides - filpizlo.com

Inline Caches

• Great optimization

• Implicitly provides profiling data

• Polyvariant

Page 307: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Sources in JSC• Case Flags — branch speculation

• Case Counts — branch speculation

• Value Profiling — type inference of values

• Inline Caches — type inference of object structure

• Watchpoints — heap speculation

• Exit Flags — speculation backoff

Page 308: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints

Math.pow(42, 2)

Page 309: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints

Math.pow(42, 2)

resolve_scopeget_from_scope

Page 310: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints

Math.pow(42, 2)

resolve_scopeget_from_scopeget_by_id

Page 311: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints

Math.pow(42, 2)

resolve_scopeget_from_scopeget_by_idcall

Page 312: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints

Math.pow(42, 2)

resolve_scopeget_from_scopeget_by_idcall

Page 313: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints

powfunc(42, 2)

const(powfunc)call

Page 314: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints

powfunc(42, 2)

const(powfunc)call

Math = “wat”;

Page 315: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints

powfunc(42, 2)

const(powfunc)call

Math = “wat”;

Math.pow

resolve_scopeget_from_scopeget_by_id

Page 316: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints Example #2

Strength.REQUIRED = new Strength(0, "required");Strength.STONG_PREFERRED = new Strength(1, "strongPreferred");Strength.PREFERRED = new Strength(2, "preferred");Strength.STRONG_DEFAULT = new Strength(3, "strongDefault");Strength.NORMAL = new Strength(4, "normal");Strength.WEAK_DEFAULT = new Strength(5, "weakDefault");Strength.WEAKEST = new Strength(6, "weakest");

Source: deltablue benchmark

Page 317: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints Example #3

AST.prototype.typeCheck = function (typeFlow) { switch(this.nodeType) { case TypeScript.NodeType.Error: case TypeScript.NodeType.EmptyExpr: { this.type = typeFlow.anyType; break; …

Source: typescript compiler

Page 318: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints Example #3

AST.prototype.typeCheck = function (typeFlow) { switch(this.nodeType) { case TypeScript.NodeType.Error: case TypeScript.NodeType.EmptyExpr: { this.type = typeFlow.anyType; break; …

Source: typescript compiler

Page 319: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints

• Object Property Conditions (equality, presence, absence, etc)

- relies on structures and ICs

• Lots of exotic watchpoints

Page 320: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Sources in JSC• Case Flags — branch speculation

• Case Counts — branch speculation

• Value Profiling — type inference of values

• Inline Caches — type inference of object structure

• Watchpoints — heap speculation

• Exit Flags — speculation backoff

Page 321: Pizlo Speculation in JSC Slides - filpizlo.com

Exit FlagsProfiling Speculation

bool Graph::canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin){ if (hasExitSite( codeOrigin, NotStringObject)) return false;

void LowerDFGToB3::speculateStringObjectForStructureID(Edge edge, LValue structureID){ …

speculate( NotStringObject, noValue(), 0, m_out.notEqual(…));}

Page 322: Pizlo Speculation in JSC Slides - filpizlo.com

Exit FlagsProfiling Speculation

bool Graph::canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin){ if (hasExitSite( codeOrigin, NotStringObject)) return false;

void LowerDFGToB3::speculateStringObjectForStructureID(Edge edge, LValue structureID){ …

speculate( NotStringObject, noValue(), 0, m_out.notEqual(…));}

Page 323: Pizlo Speculation in JSC Slides - filpizlo.com

Exit FlagsProfiling Speculation

bool Graph::canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin){ if (hasExitSite( codeOrigin, NotStringObject)) return false;

void LowerDFGToB3::speculateStringObjectForStructureID(Edge edge, LValue structureID){ …

speculate( NotStringObject, noValue(), 0, m_out.notEqual(…));}

Page 324: Pizlo Speculation in JSC Slides - filpizlo.com

Exit FlagsProfiling Speculation

bool Graph::canOptimizeStringObjectAccess(const CodeOrigin& codeOrigin){ if (hasExitSite( codeOrigin, NotStringObject)) return false;

void LowerDFGToB3::speculateStringObjectForStructureID(Edge edge, LValue structureID){ …

speculate( NotStringObject, noValue(), 0, m_out.notEqual(…));}

Page 325: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Sources in JSC• Case Flags — branch speculation

• Case Counts — branch speculation

• Value Profiling — type inference of values

• Inline Caches — type inference of object structure

• Watchpoints — heap speculation

• Exit Flags — speculation backoff

Page 326: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 327: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 328: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 329: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

Page 330: Pizlo Speculation in JSC Slides - filpizlo.com

Source

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

Page 331: Pizlo Speculation in JSC Slides - filpizlo.com

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

Page 332: Pizlo Speculation in JSC Slides - filpizlo.com

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

Page 333: Pizlo Speculation in JSC Slides - filpizlo.com

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

Page 334: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTLFast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

Page 335: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

DFG IR

Fast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

Page 336: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

DFG IR DFG IR

Fast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

Page 337: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

DFG IR DFG IR

Fast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

DFG SSA IR

Page 338: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

DFG IR DFG IR

B3 IR

Fast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

DFG SSA IR

Page 339: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

DFG IR DFG IR

B3 IR

Assembly IR

Fast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

DFG SSA IR

Page 340: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

DFG IR DFG IR

B3 IR

Assembly IR

Fast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

DFG SSA IR

Page 341: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

DFG IR DFG IR

B3 IR

Assembly IR

Fast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

DFG SSA IR

Page 342: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Goal

Remove lots of type checks quickly.

Page 343: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Goals

• Speculation

• Static Analysis

• Fast Compilation

Page 344: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Goals

• Speculation

• Static Analysis

• Fast Compilation

Page 345: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

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)

Page 346: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

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)

profiling

Page 347: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

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)

profilingspeculation

Page 348: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

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)

profilingspeculation

OSR

Page 349: Pizlo Speculation in JSC Slides - filpizlo.com

OSR flattens control flow

Page 350: Pizlo Speculation in JSC Slides - filpizlo.com

OSR is hard

Page 351: Pizlo Speculation in JSC Slides - filpizlo.com

int foo(int* ptr){ int w, x, y, z;

w = … // lots of stuff

x = is_ok(ptr) ? *ptr : slow_path(ptr);

y = … // lots of stuff

z = is_ok(ptr) ? *ptr : slow_path(ptr);

return w + x + y + z; }

Page 352: Pizlo Speculation in JSC Slides - filpizlo.com

int foo(int* ptr){ int w, x, y, z;

w = … // lots of stuff

if (!is_ok(ptr)) return foo_base1(ptr, w); x = *ptr;

y = … // lots of stuff

z = *ptr;

return w + x + y + z; }

Page 353: Pizlo Speculation in JSC Slides - filpizlo.com

int foo(int* ptr){ int w, x, y, z;

w = … // lots of stuff

if (!is_ok(ptr)) return foo_base1(ptr, w); x = *ptr;

y = … // lots of stuff

z = *ptr;

return w + x + y + z; }

Page 354: Pizlo Speculation in JSC Slides - filpizlo.com

• Must know where to exit.

• Must know what is live-at-exit.

Page 355: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Page 356: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Profiling Tier Stack Frame

at bc#42

loc3

loc4

loc5

loc6

loc7

loc8

Page 357: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Profiling Tier Stack Frame

at bc#42

loc3

loc4

loc5

loc6

loc7

loc8

frame layout matches bytecode

Page 358: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Profiling Tier Stack Frame

at bc#42

loc3

loc4

loc5

loc6

loc7

loc8

Optimizing Tier Stack Frame

at bc#42

tmp

tmp

dead

loc3

dead

loc4 → const(42)loc8 → %rdxframe layout

matches bytecode

Page 359: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Profiling Tier Stack Frame

at bc#42

loc3

loc4

loc5

loc6

loc7

loc8

Optimizing Tier Stack Frame

at bc#42

tmp

tmp

dead

loc3

dead

loc4 → const(42)loc8 → %rdxframe layout

matches bytecode frame layout selected by complex

process

Page 360: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Profiling Tier Stack Frame

at bc#42

loc3

loc4

loc5

loc6

loc7

loc8

Optimizing Tier Stack Frame

at bc#42

tmp

tmp

dead

loc3

dead

loc4 → const(42)loc8 → %rdx

OSR

frame layout matches bytecode frame layout

selected by complex process

Page 361: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Profiling Tier Stack Frame

at bc#42

loc3

loc4

loc5

loc6

loc7

loc8

Optimizing Tier Stack Frame

at bc#42

tmp

tmp

dead

loc3

dead

loc4 → const(42)loc8 → %rdx

OSR

stack/register shuffle

frame layout matches bytecode frame layout

selected by complex process

Page 362: Pizlo Speculation in JSC Slides - filpizlo.com

How?

Page 363: Pizlo Speculation in JSC Slides - filpizlo.com

Leverage Bytecode→SSA Conversion

Page 364: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Page 365: Pizlo Speculation in JSC Slides - filpizlo.com

case op_add: { VirtualRegister result = instruction->result(); VirtualRegister left = instruction->left(); VirtualRegister right = instruction->right();

stackMap[result] = createAdd( stackMap[left], stackMap[right]); break;}

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Page 366: Pizlo Speculation in JSC Slides - filpizlo.com

case op_add: { VirtualRegister result = instruction->result(); VirtualRegister left = instruction->left(); VirtualRegister right = instruction->right();

stackMap[result] = createAdd( stackMap[left], stackMap[right]); break;}

Virtual Register Value

loc3 GetScopeloc4 JSConstant(42)

loc5 deadloc6 dead

loc7 deadloc8 GetByOffset

stackMap before bc#42

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Page 367: Pizlo Speculation in JSC Slides - filpizlo.com

case op_add: { VirtualRegister result = instruction->result(); VirtualRegister left = instruction->left(); VirtualRegister right = instruction->right();

stackMap[result] = createAdd( stackMap[left], stackMap[right]); break;}

Virtual Register Value

loc3 GetScopeloc4 JSConstant(42)

loc5 deadloc6 dead

loc7 Addloc8 dead

stackMap after bc#42

[ 42] add loc7, loc4, loc8 live after: loc3, loc4, loc7

Page 368: Pizlo Speculation in JSC Slides - filpizlo.com

JSConstant

GetByOffset

Return

Add

[ 13] mov loc4, 42

[ 29] get_by_id loc8, …

[ 42] add loc7, loc4, loc8

Page 369: Pizlo Speculation in JSC Slides - filpizlo.com

case op_add: { VirtualRegister result = instruction->result(); VirtualRegister left = instruction->left(); VirtualRegister right = instruction->right();

Map<VirtualRegister, Value*> environment; for (VirtualRegister reg : liveNow()) environment[reg] = stackMap[reg];

stackMap[reg] = createAdd( stackMap[left], stackMap[right], environment); break;}

Page 370: Pizlo Speculation in JSC Slides - filpizlo.com

JSConstant GetByOffset

Return

Add

Environment

loc3

loc4

loc8

Page 371: Pizlo Speculation in JSC Slides - filpizlo.com

Exit Environment

Page 372: Pizlo Speculation in JSC Slides - filpizlo.com

Exit Environment

• The obvious solution.

Page 373: Pizlo Speculation in JSC Slides - filpizlo.com

Exit Environment

• The obvious solution.

• Super widespread.

Page 374: Pizlo Speculation in JSC Slides - filpizlo.com

Exit Environment

• The obvious solution.

• Super widespread.

• But it’s awful for JavaScript!

Page 375: Pizlo Speculation in JSC Slides - filpizlo.com
Page 376: Pizlo Speculation in JSC Slides - filpizlo.com

Exit Frequency Environments Work?

Page 377: Pizlo Speculation in JSC Slides - filpizlo.com

Exit Frequency Environments Work?

Seldom (like inlined calls in Java)

Yes, they work great!

O(live variables) cost is incurred seldom, so it’s not a big deal.

Page 378: Pizlo Speculation in JSC Slides - filpizlo.com

Exit Frequency Environments Work?

Seldom (like inlined calls in Java)

Yes, they work great!

O(live variables) cost is incurred seldom, so it’s not a big deal.

Multiple Exits Per Bytecode Instruction (like JavaScript)

Not really.

O(live variables) per instruction is a lot of:- data flow edges- memory

Page 379: Pizlo Speculation in JSC Slides - filpizlo.com

Observation: environments hardly change between

instructions.

Page 380: Pizlo Speculation in JSC Slides - filpizlo.com

Use delta encoding!

Page 381: Pizlo Speculation in JSC Slides - filpizlo.com

Use imperative delta encoding!

Page 382: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

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)

Page 383: Pizlo Speculation in JSC Slides - filpizlo.com

[ 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)

Page 384: Pizlo Speculation in JSC Slides - filpizlo.com

[ 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)

Page 385: Pizlo Speculation in JSC Slides - filpizlo.com

[ 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)

Page 386: Pizlo Speculation in JSC Slides - filpizlo.com

[ 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)

Page 387: Pizlo Speculation in JSC Slides - filpizlo.com

[ 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)

Page 388: Pizlo Speculation in JSC Slides - filpizlo.com

[ 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)

Page 389: Pizlo Speculation in JSC Slides - filpizlo.com

[ 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)

Page 390: Pizlo Speculation in JSC Slides - filpizlo.com

[ 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)

Page 391: Pizlo Speculation in JSC Slides - filpizlo.com

DFG SSA state

arg1

arg2

Add

Return

Page 392: Pizlo Speculation in JSC Slides - filpizlo.com

DFG SSA state

arg1

arg2

Add

Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6

Page 393: Pizlo Speculation in JSC Slides - filpizlo.com

DFG SSA state

arg1

arg2

Add

Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6

Page 394: Pizlo Speculation in JSC Slides - filpizlo.com

DFG SSA state

arg1

arg2

Add

Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6

MovHint

Page 395: Pizlo Speculation in JSC Slides - filpizlo.com

DFG SSA state

arg1

arg2

Add

Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6

MovHint

Page 396: Pizlo Speculation in JSC Slides - filpizlo.com

DFG SSA state

arg1

arg2

Add

Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6

MovHint

25:

Page 397: Pizlo Speculation in JSC Slides - filpizlo.com

DFG SSA state

arg1

arg2

Add

Return

DFG Exit state

loc0 loc1 loc3 loc4 loc5 loc6

MovHint

loc6 := @25

25:

Page 398: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] addMovHint(…)

ArithAdd(…)

Page 399: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] addMovHint(…)

ArithAdd(…) }exit ok

Page 400: Pizlo Speculation in JSC Slides - filpizlo.com

[ 42] addMovHint(…)

ArithAdd(…) }exit ok

}exit invalid

Page 401: Pizlo Speculation in JSC Slides - filpizlo.com

[ 666] wat

… checks and readonly ops …

… more effects …

FirstEffect(…)

OSR exit state update

Page 402: Pizlo Speculation in JSC Slides - filpizlo.com

[ 666] wat

… checks and readonly ops …

… more effects …

FirstEffect(…)

OSR exit state update

}exit ok

Page 403: Pizlo Speculation in JSC Slides - filpizlo.com

[ 666] wat

… checks and readonly ops …

… more effects …

FirstEffect(…)

OSR exit state update

}exit ok

}exit invalid

Page 404: Pizlo Speculation in JSC Slides - filpizlo.com

[ 666] wat

… checks and readonly ops …

… more effects …

FirstEffect(…)

OSR exit state update

ExitOK

}exit ok

}exit invalid

Page 405: Pizlo Speculation in JSC Slides - filpizlo.com

[ 666] wat

… checks and readonly ops …

… more effects …

FirstEffect(…)

OSR exit state update

ExitOK

ExitOK

}exit ok

}exit invalid

Page 406: Pizlo Speculation in JSC Slides - filpizlo.com

[ 666] wat

… checks and readonly ops …

… more effects …

FirstEffect(…)

OSR exit state update

ExitOK

OSR exit state update

… more effects …

… checks …

FirstEffect(…)

ExitOK

}exit ok

}exit invalid

[ 661] foo

[ 683] bar

Page 407: Pizlo Speculation in JSC Slides - filpizlo.com

Watchpoints +

InvalidationPoint

Page 408: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { return Math.pow(2, 3);}

Page 409: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { return Math.pow(2, 3);}

Profiling Tier Version

slow lookup of Math.pow

Page 410: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { return Math.pow(2, 3);}

Profiling Tier Version

slow lookup of Math.pow

Global Object

Page 411: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { return Math.pow(2, 3);}

Profiling Tier Version

slow lookup of Math.pow

Global Object

foo

Page 412: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

foo

Page 413: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

foo

Page 414: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

fooMath.pow = “hahaha”;

Page 415: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { return Math.pow(2, 3);}

Profiling Tier Version

slow lookup of Math.pow

Global Object

fooMath.pow = “hahaha”;

Page 416: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Page 417: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

slow lookup of Math.pow

Page 418: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

slow lookup of Math.pow

Global Object

Page 419: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

slow lookup of Math.pow

Global Object

foo

Page 420: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

foo

Page 421: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

foo

Page 422: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

foo

function bar() { if (p) Math = 0;}

Page 423: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

foo

function bar() { if (p) Math = 0;}

Page 424: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

foo

function bar() { if (p) Math = 0;}

Page 425: Pizlo Speculation in JSC Slides - filpizlo.com

Invalidation Idea

• Walk the stack.

• Repoint return pointers to OSR exit.

• Widespread idea.

• Doesn’t work with DFG IR.

Page 426: Pizlo Speculation in JSC Slides - filpizlo.com

… some checks …

SecondEffect(…)

FirstEffect(…)

OSR exit state update

ExitOK

ExitOK

ThirdEffect(…)

Page 427: Pizlo Speculation in JSC Slides - filpizlo.com

… some checks …

SecondEffect(…)

FirstEffect(…)

OSR exit state update

ExitOK

ExitOK

ThirdEffect(…)

What if invalidation happens here

Page 428: Pizlo Speculation in JSC Slides - filpizlo.com

… some checks …

SecondEffect(…)

FirstEffect(…)

OSR exit state update

ExitOK

ExitOK

ThirdEffect(…)

What if invalidation happens here

Or here

Page 429: Pizlo Speculation in JSC Slides - filpizlo.com

… some checks …

SecondEffect(…)

FirstEffect(…)

OSR exit state update

ExitOK

ExitOK

ThirdEffect(…)

What if invalidation happens here

Or hereNowhere to

exit to!

Page 430: Pizlo Speculation in JSC Slides - filpizlo.com

… some checks …

SecondEffect(…)

FirstEffect(…)

OSR exit state update

ExitOK

ExitOK

ThirdEffect(…)

InvalidationPoint

Page 431: Pizlo Speculation in JSC Slides - filpizlo.com

InvalidationPoint

• Deferred invalidation in case an in-progress effect has nowhere to exit.

• Emits no code.

Page 432: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

foo

Page 433: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

foo

function bar() { if (p) Math = 0;}

Page 434: Pizlo Speculation in JSC Slides - filpizlo.com

function foo() { bar(); return Math.pow(2, 3);}

Profiling Tier Version

Optimizing Tier Version

slow lookup of Math.pow

Constant-folded Math.pow

Global Object

foo

function bar() { if (p) Math = 0;}

Invalidated Optimizing Tier

Version

jmp

jmp

jmp

Page 435: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Goals

• Speculation

• Static Analysis

• Fast Compilation

Page 436: Pizlo Speculation in JSC Slides - filpizlo.com

Remove type checks

Page 437: Pizlo Speculation in JSC Slides - filpizlo.com
Page 438: Pizlo Speculation in JSC Slides - filpizlo.com

Check(Int32:@foo)

Page 439: Pizlo Speculation in JSC Slides - filpizlo.com

Check(Int32:@foo)

Check(Int32:@foo)

Page 440: Pizlo Speculation in JSC Slides - filpizlo.com

Check(Int32:@foo)

Check(Int32:@foo)Check(Int32:@foo)

Page 441: Pizlo Speculation in JSC Slides - filpizlo.com

Check(Int32:@foo)

Page 442: Pizlo Speculation in JSC Slides - filpizlo.com

Check(Int32:@foo)

Check(Int32:@foo)

Page 443: Pizlo Speculation in JSC Slides - filpizlo.com

Check(Int32:@foo)

Check(Int32:@foo) Check(Int32:@foo)

Page 444: Pizlo Speculation in JSC Slides - filpizlo.com

Check(Int32:@foo) Check(Int32:@foo)

Page 445: Pizlo Speculation in JSC Slides - filpizlo.com

Abstract Interpreter• “Global” (whole compilation unit)

• Flow sensitive

• Tracks:

- variable type

- object structure

- indexing type

- constants

Page 446: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Goals

• Speculation

• Static Analysis

• Fast Compilation

Page 447: Pizlo Speculation in JSC Slides - filpizlo.com

Fast Compile

• Emphasis on block-locality.

• Template code generation.

Page 448: Pizlo Speculation in JSC Slides - filpizlo.com

Get Local Get

Local

Add

Set Local

Page 449: Pizlo Speculation in JSC Slides - filpizlo.com

Get Local Get

Local

Add

Set Local

Branch

Page 450: Pizlo Speculation in JSC Slides - filpizlo.com

Get Local Get

Local

Add

Set Local

Branch

φ φ

Page 451: Pizlo Speculation in JSC Slides - filpizlo.com

Get Local Get

Local

Add

Set Local

Branch

φ φ

Set Local

Set Local

Page 452: Pizlo Speculation in JSC Slides - filpizlo.com

Get Local Get

Local

Add

Set Local

Branch

Get Local

Get Local

φ

φ φ

φ

Set Local

Set Local

Page 453: Pizlo Speculation in JSC Slides - filpizlo.com

• Primary block-local data flow graph.

Get Local Get

Local

Add

Set Local

Branch

Get Local

Get Local

φ

φ φ

φ

Set Local

Set Local

Page 454: Pizlo Speculation in JSC Slides - filpizlo.com

• Primary block-local data flow graph.

• Secondary global data flow graph.

Get Local Get

Local

Add

Set Local

Branch

Get Local

Get Local

φ

φ φ

φ

Set Local

Set Local

Page 455: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Template Codegen

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)

Page 456: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Template Codegen

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)

Page 457: Pizlo Speculation in JSC Slides - filpizlo.com

DFG Template Codegen

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)

add %esi, %eaxjo Lexit

Page 458: Pizlo Speculation in JSC Slides - filpizlo.com

DFG optimization pipelineDFG IR

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Abstract Interpreter

Local CSE

Simplify (CFG, etc.)

Varargs Forwarding

GC Barrier Scheduling

Template Codegen

Page 459: Pizlo Speculation in JSC Slides - filpizlo.com

DFG optimization pipelineDFG IR

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Abstract Interpreter

Local CSE

Simplify (CFG, etc.)

Varargs Forwarding

GC Barrier Scheduling

Template Codegen

Page 460: Pizlo Speculation in JSC Slides - filpizlo.com

DFG optimization pipelineDFG IR

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Abstract Interpreter

Local CSE

Simplify (CFG, etc.)

Varargs Forwarding

GC Barrier Scheduling

Template Codegen

Page 461: Pizlo Speculation in JSC Slides - filpizlo.com

DFG optimization pipelineDFG IR

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Abstract Interpreter

Local CSE

Simplify (CFG, etc.)

Varargs Forwarding

GC Barrier Scheduling

Template Codegen

Page 462: Pizlo Speculation in JSC Slides - filpizlo.com

DFG optimization pipelineDFG IR

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Abstract Interpreter

Local CSE

Simplify (CFG, etc.)

Varargs Forwarding

GC Barrier Scheduling

Template Codegen

Page 463: Pizlo Speculation in JSC Slides - filpizlo.com

DFG optimization pipelineDFG IR

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Abstract Interpreter

Local CSE

Simplify (CFG, etc.)

Varargs Forwarding

GC Barrier Scheduling

Template Codegen

Page 464: Pizlo Speculation in JSC Slides - filpizlo.com

DFG optimization pipelineDFG IR

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Abstract Interpreter

Local CSE

Simplify (CFG, etc.)

Varargs Forwarding

GC Barrier Scheduling

Template Codegen

Page 465: Pizlo Speculation in JSC Slides - filpizlo.com

JetStream 2 Score

LLInt

LLInt+Baseline

LLInt+Baseline+DFG

LLInt+Baseline+DFG+FTL

Score (higher is better)0 15 30 45 60 75 90 105 120 135 150

on my computer one day

>2x LLInt

>2x Baseline

~1.1x DFG

Page 466: Pizlo Speculation in JSC Slides - filpizlo.com

JetStream 2 Score

LLInt

LLInt+Baseline

LLInt+Baseline+DFG

LLInt+Baseline+DFG+FTL

Score (higher is better)0 15 30 45 60 75 90 105 120 135 150

on my computer one day

>2x LLInt

>2x Baseline

~1.1x DFG

Page 467: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

DFG IR DFG IR

B3 IR

Assembly IR

Fast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

DFG SSA IR

Page 468: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

DFG IR DFG IR

B3 IR

Assembly IR

Fast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

DFG SSA IR

Page 469: Pizlo Speculation in JSC Slides - filpizlo.com

FTL Goal

All the optimizations.

Page 470: Pizlo Speculation in JSC Slides - filpizlo.com

FTL IRsIR Style Example

Bytecode High LevelLoad/Store bitor dst, left, right

DFG Medium LevelExotic SSA

dst: BitOr(Int32:@left, Int32:@right, …)

B3 Low LevelNormal SSA

Int32 @dst = BitOr(@left, @right)

Air ArchitecturalCISC Or32 %src, %dest

Page 471: Pizlo Speculation in JSC Slides - filpizlo.com

FTL IRsIR Style Example

Bytecode High LevelLoad/Store bitor dst, left, right

DFG Medium LevelExotic SSA

dst: BitOr(Int32:@left, Int32:@right, …)

B3 Low LevelNormal SSA

Int32 @dst = BitOr(@left, @right)

Air ArchitecturalCISC Or32 %src, %dest

Page 472: Pizlo Speculation in JSC Slides - filpizlo.com

FTL IRsIR Style Example

Bytecode High LevelLoad/Store bitor dst, left, right

DFG Medium LevelExotic SSA

dst: BitOr(Int32:@left, Int32:@right, …)

B3 Low LevelNormal SSA

Int32 @dst = BitOr(@left, @right)

Air ArchitecturalCISC Or32 %src, %dest

Page 473: Pizlo Speculation in JSC Slides - filpizlo.com

FTL IRsIR Style Example

Bytecode High LevelLoad/Store bitor dst, left, right

DFG Medium LevelExotic SSA

dst: BitOr(Int32:@left, Int32:@right, …)

B3 Low LevelNormal SSA

Int32 @dst = BitOr(@left, @right)

Air ArchitecturalCISC Or32 %src, %dest

Page 474: Pizlo Speculation in JSC Slides - filpizlo.com

FTL IRsIR Style Example

Bytecode High LevelLoad/Store bitor dst, left, right

DFG Medium LevelExotic SSA

dst: BitOr(Int32:@left, Int32:@right, …)

B3 Low LevelNormal SSA

Int32 @dst = BitOr(@left, @right)

Air ArchitecturalCISC Or32 %src, %dest

Page 475: Pizlo Speculation in JSC Slides - filpizlo.com

FTL optimization pipelineDFG IR B3 IR Air

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Simplify (CFG etc)

Abstract Interpretation

Global CSE

Escape Analysis

LICM

Integer Range Optimization

GC Barrier Scheduling

Lower to B3 IR

Double-to-Float

Simplify (folding, CFG, etc)

LICM

Global CSE

Switch Inference

Tail Duplication

Path Constants

Macro Lowering

Legalization

Constant Motion

Lower to Air (isel)

Simplify CFG

Macro Lowering

DCE

Graph Coloring Reg Alloc

Spill CSE

Graph Coloring Stack Alloc

Report Used Registers

Lower Multiple Entrypoints

Select Block Order

Emit Machine Code

Fix Partial Register Stalls

Page 476: Pizlo Speculation in JSC Slides - filpizlo.com

FTL optimization pipelineDFG IR B3 IR Air

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Simplify (CFG etc)

Abstract Interpretation

Global CSE

Escape Analysis

LICM

Integer Range Optimization

GC Barrier Scheduling

Lower to B3 IR

Double-to-Float

Simplify (folding, CFG, etc)

LICM

Global CSE

Switch Inference

Tail Duplication

Path Constants

Macro Lowering

Legalization

Constant Motion

Lower to Air (isel)

Simplify CFG

Macro Lowering

DCE

Graph Coloring Reg Alloc

Spill CSE

Graph Coloring Stack Alloc

Report Used Registers

Lower Multiple Entrypoints

Select Block Order

Emit Machine Code

Fix Partial Register Stalls

Page 477: Pizlo Speculation in JSC Slides - filpizlo.com

FTL optimization pipelineDFG IR B3 IR Air

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Simplify (CFG etc)

Abstract Interpretation

Global CSE

Escape Analysis

LICM

Integer Range Optimization

GC Barrier Scheduling

Lower to B3 IR

Double-to-Float

Simplify (folding, CFG, etc)

LICM

Global CSE

Switch Inference

Tail Duplication

Path Constants

Macro Lowering

Legalization

Constant Motion

Lower to Air (isel)

Simplify CFG

Macro Lowering

DCE

Graph Coloring Reg Alloc

Spill CSE

Graph Coloring Stack Alloc

Report Used Registers

Lower Multiple Entrypoints

Select Block Order

Emit Machine Code

Fix Partial Register Stalls

Page 478: Pizlo Speculation in JSC Slides - filpizlo.com

FTL optimization pipelineDFG IR B3 IR Air

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Simplify (CFG etc)

Abstract Interpretation

Global CSE

Escape Analysis

LICM

Integer Range Optimization

GC Barrier Scheduling

Lower to B3 IR

Double-to-Float

Simplify (folding, CFG, etc)

LICM

Global CSE

Switch Inference

Tail Duplication

Path Constants

Macro Lowering

Legalization

Constant Motion

Lower to Air (isel)

Simplify CFG

Macro Lowering

DCE

Graph Coloring Reg Alloc

Spill CSE

Graph Coloring Stack Alloc

Report Used Registers

Lower Multiple Entrypoints

Select Block Order

Emit Machine Code

Fix Partial Register Stalls

Page 479: Pizlo Speculation in JSC Slides - filpizlo.com

FTL optimization pipelineDFG IR B3 IR Air

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Simplify (CFG etc)

Abstract Interpretation

Global CSE

Escape Analysis

LICM

Integer Range Optimization

GC Barrier Scheduling

Lower to B3 IR

Double-to-Float

Simplify (folding, CFG, etc)

LICM

Global CSE

Switch Inference

Tail Duplication

Path Constants

Macro Lowering

Legalization

Constant Motion

Lower to Air (isel)

Simplify CFG

Macro Lowering

DCE

Graph Coloring Reg Alloc

Spill CSE

Graph Coloring Stack Alloc

Report Used Registers

Lower Multiple Entrypoints

Select Block Order

Emit Machine Code

Fix Partial Register Stalls

Page 480: Pizlo Speculation in JSC Slides - filpizlo.com

FTL optimization pipelineDFG IR B3 IR Air

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Simplify (CFG etc)

Abstract Interpretation

Global CSE

Escape Analysis

LICM

Integer Range Optimization

GC Barrier Scheduling

Lower to B3 IR

Double-to-Float

Simplify (folding, CFG, etc)

LICM

Global CSE

Switch Inference

Tail Duplication

Path Constants

Macro Lowering

Legalization

Constant Motion

Lower to Air (isel)

Simplify CFG

Macro Lowering

DCE

Graph Coloring Reg Alloc

Spill CSE

Graph Coloring Stack Alloc

Report Used Registers

Lower Multiple Entrypoints

Select Block Order

Emit Machine Code

Fix Partial Register Stalls

Page 481: Pizlo Speculation in JSC Slides - filpizlo.com

FTL optimization pipelineDFG IR B3 IR Air

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Simplify (CFG etc)

Abstract Interpretation

Global CSE

Escape Analysis

LICM

Integer Range Optimization

GC Barrier Scheduling

Lower to B3 IR

Double-to-Float

Simplify (folding, CFG, etc)

LICM

Global CSE

Switch Inference

Tail Duplication

Path Constants

Macro Lowering

Legalization

Constant Motion

Lower to Air (isel)

Simplify CFG

Macro Lowering

DCE

Graph Coloring Reg Alloc

Spill CSE

Graph Coloring Stack Alloc

Report Used Registers

Lower Multiple Entrypoints

Select Block Order

Emit Machine Code

Fix Partial Register Stalls

Page 482: Pizlo Speculation in JSC Slides - filpizlo.com

FTL optimization pipelineDFG IR B3 IR Air

Bytecode Parsing and Inlining

Type Inference

Check Scheduling

Simplify (CFG etc)

Abstract Interpretation

Global CSE

Escape Analysis

LICM

Integer Range Optimization

GC Barrier Scheduling

Lower to B3 IR

Double-to-Float

Simplify (folding, CFG, etc)

LICM

Global CSE

Switch Inference

Tail Duplication

Path Constants

Macro Lowering

Legalization

Constant Motion

Lower to Air (isel)

Simplify CFG

Macro Lowering

DCE

Graph Coloring Reg Alloc

Spill CSE

Graph Coloring Stack Alloc

Report Used Registers

Lower Multiple Entrypoints

Select Block Order

Emit Machine Code

Fix Partial Register Stalls

Page 483: Pizlo Speculation in JSC Slides - filpizlo.com

Source

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

Page 484: Pizlo Speculation in JSC Slides - filpizlo.com

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

Page 485: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

24: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 25: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 26: ArithAdd(Int32:@24, Int32:@25, CheckOverflow, Exits, bc#7) 27: MovHint(Untyped:@26, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid) 29: GetLocal(Untyped:@3, arg3(D<Int32>/FlushedInt32), R:Stack(8), bc#12) 30: ArithAdd(Int32:@26, Int32:@29, CheckOverflow, Exits, bc#12) 31: MovHint(Untyped:@30, loc6, W:SideState, ClobbersExit, bc#12, ExitInvalid) 33: Return(Untyped:@3, W:SideState, Exits, bc#17)

Page 486: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

24: GetLocal(Untyped:@1, arg1(B<Int32>/FlushedInt32), R:Stack(6), bc#7) 25: GetLocal(Untyped:@2, arg2(C<BoolInt32>/FlushedInt32), R:Stack(7), bc#7) 26: ArithAdd(Int32:@24, Int32:@25, CheckOverflow, Exits, bc#7) 27: MovHint(Untyped:@26, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid) 29: GetLocal(Untyped:@3, arg3(D<Int32>/FlushedInt32), R:Stack(8), bc#12) 30: ArithAdd(Int32:@26, Int32:@29, CheckOverflow, Exits, bc#12) 31: MovHint(Untyped:@30, loc6, W:SideState, ClobbersExit, bc#12, ExitInvalid) 33: Return(Untyped:@3, W:SideState, Exits, bc#17)

Page 487: Pizlo Speculation in JSC Slides - filpizlo.com

B3 IR Int32 @42 = Trunc(@32, DFG:@26) Int32 @43 = Trunc(@27, DFG:@26) Int32 @44 = CheckAdd(@42:WarmAny, @43:WarmAny, generator = 0x1052c5cd0, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@26) Int32 @45 = Trunc(@22, DFG:@30) Int32 @46 = CheckAdd(@44:WarmAny, @45:WarmAny, @44:ColdAny, generator = 0x1052c5d70, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@30) Int64 @47 = ZExt32(@46, DFG:@32) Int64 @48 = Add(@47, $-281474976710656(@13), DFG:@32) Void @49 = Return(@48, Terminal, DFG:@32)

Page 488: Pizlo Speculation in JSC Slides - filpizlo.com

B3 IR Int32 @42 = Trunc(@32, DFG:@26) Int32 @43 = Trunc(@27, DFG:@26) Int32 @44 = CheckAdd(@42:WarmAny, @43:WarmAny, generator = 0x1052c5cd0, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@26) Int32 @45 = Trunc(@22, DFG:@30) Int32 @46 = CheckAdd(@44:WarmAny, @45:WarmAny, @44:ColdAny, generator = 0x1052c5d70, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@30) Int64 @47 = ZExt32(@46, DFG:@32) Int64 @48 = Add(@47, $-281474976710656(@13), DFG:@32) Void @49 = Return(@48, Terminal, DFG:@32)

Page 489: Pizlo Speculation in JSC Slides - filpizlo.com

B3 IR Int32 @42 = Trunc(@32, DFG:@26) Int32 @43 = Trunc(@27, DFG:@26) Int32 @44 = CheckAdd(@42:WarmAny, @43:WarmAny, generator = 0x1052c5cd0, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@26) Int32 @45 = Trunc(@22, DFG:@30) Int32 @46 = CheckAdd(@44:WarmAny, @45:WarmAny, @44:ColdAny, generator = 0x1052c5d70, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@30) Int64 @47 = ZExt32(@46, DFG:@32) Int64 @48 = Add(@47, $-281474976710656(@13), DFG:@32) Void @49 = Return(@48, Terminal, DFG:@32)

Page 490: Pizlo Speculation in JSC Slides - filpizlo.com

Int32 @42 = Trunc(@32, DFG:@26) Int32 @43 = Trunc(@27, DFG:@26) Int32 @44 = CheckAdd(@42:WarmAny, @43:WarmAny, generator = 0x1052c5cd0, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@26) Int32 @45 = Trunc(@22, DFG:@30) Int32 @46 = CheckAdd(@44:WarmAny, @45:WarmAny, @44:ColdAny, generator = 0x1052c5d70, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@30) Int64 @47 = ZExt32(@46, DFG:@32) Int64 @48 = Add(@47, $-281474976710656(@13), DFG:@32) Void @49 = Return(@48, Terminal, DFG:@32)

Page 491: Pizlo Speculation in JSC Slides - filpizlo.com

Int32 @42 = Trunc(@32, DFG:@26) Int32 @43 = Trunc(@27, DFG:@26) Int32 @44 = CheckAdd(@42:WarmAny, @43:WarmAny, generator = 0x1052c5cd0, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@26) Int32 @45 = Trunc(@22, DFG:@30) Int32 @46 = CheckAdd(@44:WarmAny, @45:WarmAny, @44:ColdAny, generator = 0x1052c5d70, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@30) Int64 @47 = ZExt32(@46, DFG:@32) Int64 @48 = Add(@47, $-281474976710656(@13), DFG:@32) Void @49 = Return(@48, Terminal, DFG:@32)

Page 492: Pizlo Speculation in JSC Slides - filpizlo.com

Int32 @42 = Trunc(@32, DFG:@26) Int32 @43 = Trunc(@27, DFG:@26) Int32 @44 = CheckAdd(@42:WarmAny, @43:WarmAny, generator = 0x1052c5cd0, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@26) Int32 @45 = Trunc(@22, DFG:@30) Int32 @46 = CheckAdd(@44:WarmAny, @45:WarmAny, @44:ColdAny, generator = 0x1052c5d70, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@30) Int64 @47 = ZExt32(@46, DFG:@32) Int64 @48 = Add(@47, $-281474976710656(@13), DFG:@32) Void @49 = Return(@48, Terminal, DFG:@32)

26: ArithAdd(Int32:@24, Int32:@25, CheckOverflow, Exits, bc#7) 27: MovHint(Untyped:@26, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid) 30: ArithAdd(Int32:@26, Int32:@29, CheckOverflow, Exits, bc#12)

Page 493: Pizlo Speculation in JSC Slides - filpizlo.com

Int32 @42 = Trunc(@32, DFG:@26) Int32 @43 = Trunc(@27, DFG:@26) Int32 @44 = CheckAdd(@42:WarmAny, @43:WarmAny, generator = 0x1052c5cd0, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@26) Int32 @45 = Trunc(@22, DFG:@30) Int32 @46 = CheckAdd(@44:WarmAny, @45:WarmAny, @44:ColdAny, generator = 0x1052c5d70, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@30) Int64 @47 = ZExt32(@46, DFG:@32) Int64 @48 = Add(@47, $-281474976710656(@13), DFG:@32) Void @49 = Return(@48, Terminal, DFG:@32)

26: ArithAdd(Int32:@24, Int32:@25, CheckOverflow, Exits, bc#7) 27: MovHint(Untyped:@26, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid) 30: ArithAdd(Int32:@26, Int32:@29, CheckOverflow, Exits, bc#12)

Page 494: Pizlo Speculation in JSC Slides - filpizlo.com

Int32 @42 = Trunc(@32, DFG:@26) Int32 @43 = Trunc(@27, DFG:@26) Int32 @44 = CheckAdd(@42:WarmAny, @43:WarmAny, generator = 0x1052c5cd0, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@26) Int32 @45 = Trunc(@22, DFG:@30) Int32 @46 = CheckAdd(@44:WarmAny, @45:WarmAny, @44:ColdAny, generator = 0x1052c5d70, earlyClobbered = [], lateClobbered = [], usedRegisters = [], ExitsSideways|Reads:Top, DFG:@30) Int64 @47 = ZExt32(@46, DFG:@32) Int64 @48 = Add(@47, $-281474976710656(@13), DFG:@32) Void @49 = Return(@48, Terminal, DFG:@32)

26: ArithAdd(Int32:@24, Int32:@25, CheckOverflow, Exits, bc#7) 27: MovHint(Untyped:@26, loc6, W:SideState, ClobbersExit, bc#7, ExitInvalid) 30: ArithAdd(Int32:@26, Int32:@29, CheckOverflow, Exits, bc#12)

Page 495: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

Page 496: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

ArithAdd

Page 497: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

ArithAdd

CheckAdd

Page 498: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

ArithAdd

CheckAdd

generator

λ

Page 499: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

ArithAdd

CheckAdd

OSR Exit

Descriptor

generator

λ

Page 500: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

ArithAdd

CheckAdd

OSR Exit

Descriptor

generator

λ

Page 501: Pizlo Speculation in JSC Slides - filpizlo.com

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Page 502: Pizlo Speculation in JSC Slides - filpizlo.com

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

JSC::FTL::OSRExitDescriptor

Page 503: Pizlo Speculation in JSC Slides - filpizlo.com

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

JSC::FTL::OSRExitDescriptor

Page 504: Pizlo Speculation in JSC Slides - filpizlo.com

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

JSC::FTL::OSRExitDescriptor

Page 505: Pizlo Speculation in JSC Slides - filpizlo.com

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

JSC::FTL::OSRExitDescriptor

Page 506: Pizlo Speculation in JSC Slides - filpizlo.com

Air backend

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

JSC::FTL::OSRExitDescriptor

Patch &BranchAdd32 Overflow, %left, %right, %dst, %arg0, %arg1, %arg2, …, generator = 0x…)

Page 507: Pizlo Speculation in JSC Slides - filpizlo.com

Air backend

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

JSC::FTL::OSRExitDescriptor

Patch &BranchAdd32 Overflow, %left, %right, %dst, %arg0, %arg1, %arg2, …, generator = 0x…)

Page 508: Pizlo Speculation in JSC Slides - filpizlo.com

Air backend

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

JSC::FTL::OSRExitDescriptor

Patch &BranchAdd32 Overflow, %left, %right, %dst, %arg0, %arg1, %arg2, …, generator = 0x…)

Page 509: Pizlo Speculation in JSC Slides - filpizlo.com

Air backend

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

JSC::FTL::OSRExitDescriptor

Patch &BranchAdd32 Overflow, %left, %right, %dst, %arg0, %arg1, %arg2, …, generator = 0x…)

Page 510: Pizlo Speculation in JSC Slides - filpizlo.com

Air backend

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

JSC::FTL::OSRExitDescriptor

Patch &BranchAdd32 Overflow, %left, %right, %dst, %rcx , %r11 , %rax , …, generator = 0x…)

Page 511: Pizlo Speculation in JSC Slides - filpizlo.com

Air backend

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

%rcx

JSC::FTL::OSRExitDescriptor

Patch &BranchAdd32 Overflow, %left, %right, %dst, %rcx , %r11 , %rax , …, generator = 0x…)

Page 512: Pizlo Speculation in JSC Slides - filpizlo.com

Air backend

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

%rcx %r11

JSC::FTL::OSRExitDescriptor

Patch &BranchAdd32 Overflow, %left, %right, %dst, %rcx , %r11 , %rax , …, generator = 0x…)

Page 513: Pizlo Speculation in JSC Slides - filpizlo.com

Air backend

CheckAdd(@left, @right, @arg0, @arg1, @arg2, …, generator = 0x…)

Bytecode Variable: loc1 loc2 loc3 loc4Recovery Method: @arg2 Const: 42 @arg0 @arg1

%rcx %r11%rax

JSC::FTL::OSRExitDescriptor

Patch &BranchAdd32 Overflow, %left, %right, %dst, %rcx , %r11 , %rax , …, generator = 0x…)

Page 514: Pizlo Speculation in JSC Slides - filpizlo.com
Page 515: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

Page 516: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

lowering

phase

Page 517: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

lowering

phaselots of stuff

Machine Code

Page 518: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

lowering

phaselots of stuff

Machine Code

Add

Page 519: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

lowering

phaselots of stuff

Machine Code

Add

CheckAdd

Trunc Trunc

Page 520: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

lowering

phaselots of stuff

Machine Code

Add

CheckAdd

Trunc Trunc

addl

jo

Page 521: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

lowering

phaselots of stuff

Machine Code

Add

CheckAdd

Trunc Trunc

addl

jo

Call

Page 522: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

lowering

phaselots of stuff

Machine Code

Add

CheckAdd

Trunc Trunc

addl

jo

Call

Page 523: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

lowering

phaselots of stuff

Machine Code

Add

CheckAdd

Trunc Trunc

addl

jo

Call

patchpoint

Page 524: Pizlo Speculation in JSC Slides - filpizlo.com

DFG IR

B3 IR

lowering

phaselots of stuff

Machine Code

Add

CheckAdd

Trunc Trunc

addl

jo

Call

λ

Page 525: Pizlo Speculation in JSC Slides - filpizlo.com

inline void x86_cpuid(){ intptr_t a = 0, b, c, d; asm volatile( "cpuid" : "+a"(a), "=b"(b), "=c"(c), "=d"(d) : : "memory");}

Page 526: Pizlo Speculation in JSC Slides - filpizlo.com

if (MacroAssemblerARM64:: supportsDoubleToInt32ConversionUsingJavaScriptSemantics()) { PatchpointValue* patchpoint = m_out.patchpoint(Int32); patchpoint->appendSomeRegister(doubleValue); patchpoint->setGenerator( [=] (CCallHelpers& jit, const StackmapGenerationParams& params) { jit.convertDoubleToInt32UsingJavaScriptSemantics( params[1].fpr(), params[0].gpr()); }); patchpoint->effects = Effects::none(); return patchpoint;}

Page 527: Pizlo Speculation in JSC Slides - filpizlo.com

if (MacroAssemblerARM64:: supportsDoubleToInt32ConversionUsingJavaScriptSemantics()) { PatchpointValue* patchpoint = m_out.patchpoint(Int32); patchpoint->appendSomeRegister(doubleValue); patchpoint->setGenerator( [=] (CCallHelpers& jit, const StackmapGenerationParams& params) { jit.convertDoubleToInt32UsingJavaScriptSemantics( params[1].fpr(), params[0].gpr()); }); patchpoint->effects = Effects::none(); return patchpoint;}

Page 528: Pizlo Speculation in JSC Slides - filpizlo.com

if (MacroAssemblerARM64:: supportsDoubleToInt32ConversionUsingJavaScriptSemantics()) { PatchpointValue* patchpoint = m_out.patchpoint(Int32); patchpoint->appendSomeRegister(doubleValue); patchpoint->setGenerator( [=] (CCallHelpers& jit, const StackmapGenerationParams& params) { jit.convertDoubleToInt32UsingJavaScriptSemantics( params[1].fpr(), params[0].gpr()); }); patchpoint->effects = Effects::none(); return patchpoint;}

Page 529: Pizlo Speculation in JSC Slides - filpizlo.com

if (MacroAssemblerARM64:: supportsDoubleToInt32ConversionUsingJavaScriptSemantics()) { PatchpointValue* patchpoint = m_out.patchpoint(Int32); patchpoint->appendSomeRegister(doubleValue); patchpoint->setGenerator( [=] (CCallHelpers& jit, const StackmapGenerationParams& params) { jit.convertDoubleToInt32UsingJavaScriptSemantics( params[1].fpr(), params[0].gpr()); }); patchpoint->effects = Effects::none(); return patchpoint;}

Page 530: Pizlo Speculation in JSC Slides - filpizlo.com

if (MacroAssemblerARM64:: supportsDoubleToInt32ConversionUsingJavaScriptSemantics()) { PatchpointValue* patchpoint = m_out.patchpoint(Int32); patchpoint->appendSomeRegister(doubleValue); patchpoint->setGenerator( [=] (CCallHelpers& jit, const StackmapGenerationParams& params) { jit.convertDoubleToInt32UsingJavaScriptSemantics( params[1].fpr(), params[0].gpr()); }); patchpoint->effects = Effects::none(); return patchpoint;}

Page 531: Pizlo Speculation in JSC Slides - filpizlo.com

if (MacroAssemblerARM64:: supportsDoubleToInt32ConversionUsingJavaScriptSemantics()) { PatchpointValue* patchpoint = m_out.patchpoint(Int32); patchpoint->appendSomeRegister(doubleValue); patchpoint->setGenerator( [=] (CCallHelpers& jit, const StackmapGenerationParams& params) { jit.convertDoubleToInt32UsingJavaScriptSemantics( params[1].fpr(), params[0].gpr()); }); patchpoint->effects = Effects::none(); return patchpoint;}

Page 532: Pizlo Speculation in JSC Slides - filpizlo.com

if (MacroAssemblerARM64:: supportsDoubleToInt32ConversionUsingJavaScriptSemantics()) { PatchpointValue* patchpoint = m_out.patchpoint(Int32); patchpoint->appendSomeRegister(doubleValue); patchpoint->setGenerator( [=] (CCallHelpers& jit, const StackmapGenerationParams& params) { jit.convertDoubleToInt32UsingJavaScriptSemantics( params[1].fpr(), params[0].gpr()); }); patchpoint->effects = Effects::none(); return patchpoint;}

Page 533: Pizlo Speculation in JSC Slides - filpizlo.com

Patchpoint Use Cases

• Polymorphic inline caches

• Calls with interesting calling conventions

• Lazy slow paths

• Interesting instructions

Page 534: Pizlo Speculation in JSC Slides - filpizlo.com

Patchpoint Use Cases

FTL

B3

Page 535: Pizlo Speculation in JSC Slides - filpizlo.com

Patchpoint Use Cases

FTL

B3 B3

B3

Page 536: Pizlo Speculation in JSC Slides - filpizlo.com

Patchpoint Use Cases

FTL

B3 B3

B3

PolymorphicAccess

Snippet

Page 537: Pizlo Speculation in JSC Slides - filpizlo.com

Patchpoint Use Cases

Snippet

DFG

FTL

B3 B3

B3

PolymorphicAccess

Snippet

Page 538: Pizlo Speculation in JSC Slides - filpizlo.com

Patchpoint Use Cases

Snippet

DFG

Snippet

FTL

FTL

B3 B3

B3

PolymorphicAccess

Snippet

Page 539: Pizlo Speculation in JSC Slides - filpizlo.com

DFG-to-B3 lowering

DFG Optimizer

DFG Backend

DFG Optimizer

B3 Optimizer

Instruction Selection

Air Optimizer

Air Backend

DFG Bytecode Parser

DFG Bytecode Parser

DFG FTL

DFG IR DFG IR

B3 IR

Assembly IR

Fast JIT Powerful JIT

DFG SSA Conversion

DFG SSA Optimizer

DFG SSA IR

Page 540: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 541: Pizlo Speculation in JSC Slides - filpizlo.com

Profiling Tier

Optimizing Tier

Bytecode

OSR

Control

Page 542: Pizlo Speculation in JSC Slides - filpizlo.com

Speculation in JSC

Baseline DFG

Bytecode

OSR

Control

LLInt FTL

Control Control

OSR