Skip to content

Commit

Permalink
Add in place interpreter optimizations
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=259798
rdar://113358427

Reviewed by Justin Michaud.

Added a variety of optimizations to improve the performance of the in-place interpreter:
- Added new mini-interpreters (mINT, uINT, and argumINT) to optimize the calling convention by not loading/storing registers pessimistically.
  - argumINT also allows locals to index directly using their original index.
- Added a "condensing" behavior that allows long runs of block/loop and end instructions to be skipped when interpreting by modifying metadata entries to jump past these groups of instructions.
- Transitioned to unaligned metadata, allowing almost all instructions to save bytes by compacting their metadata.
- Added compact forms for i32.const and local.get/set, which allow IPInt to read directly from the bytecode if the index is <128, saving 4B of metadata.

Scores 37.755 on JS2's Wasm tests, versus 34.926 for LLInt.

Startup time on UE4 Zen Garden: starts up 7.2% faster (220 ms vs 237 ms), while utilizing 9.1% less memory (421 MB vs 463 MB)

* JSTests/wasm/ipint-tests/ipint-test-nesting.js: Added.
(from.string_appeared_here.import.as.assert.from.string_appeared_here.let.wat.module.func.export.string_appeared_here.result.i32.block.result.i32.block.result.i32.block.result.i32.block.result.i32.block.result.i32.block.result.i32.block.result.i32.block.result.i32.block.result.i32.block.result.i32.block.result.i32.i32.const.3.br.5.block.param.i32.result.i32.block.result.i32.i32.const.2.i32.add.return.func.export.string_appeared_here.param.i32.result.i32.block.block.block.loop.block.loop.block.local.0.i32.const.1.i32.add.local.0.loop.block.nop.loop.loop.loop.local.0.local.0.local.0.return.async test):
* Source/JavaScriptCore/llint/InPlaceInterpreter.asm:
* Source/JavaScriptCore/wasm/WasmFunctionIPIntMetadataGenerator.cpp:
(JSC::Wasm::FunctionIPIntMetadataGenerator::addBlankSpace):
(JSC::Wasm::FunctionIPIntMetadataGenerator::addRawValue):
(JSC::Wasm::FunctionIPIntMetadataGenerator::addLEB128ConstantInt32AndLength):
(JSC::Wasm::FunctionIPIntMetadataGenerator::addLEB128ConstantAndLengthForType):
(JSC::Wasm::FunctionIPIntMetadataGenerator::addReturnData):
* Source/JavaScriptCore/wasm/WasmFunctionIPIntMetadataGenerator.h:
* Source/JavaScriptCore/wasm/WasmIPIntGenerator.cpp:
(JSC::Wasm::IPIntGenerator::condenseControlFlowInstructions):
(JSC::Wasm::IPIntGenerator::addBlock):
(JSC::Wasm::IPIntGenerator::addLoop):

Canonical link: https://commits.webkit.org/266826@main
  • Loading branch information
danlliu authored and Justin Michaud committed Aug 11, 2023
1 parent 81f1c23 commit 6f23b5f
Show file tree
Hide file tree
Showing 10 changed files with 1,101 additions and 532 deletions.
2 changes: 1 addition & 1 deletion JSTests/wasm/ipint-tests/ipint-test-call-add12.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ let wat = `
async function test() {
const instance = await instantiate(wat, {});
const { test, add } = instance.exports
// assert.eq(add(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), 12);
assert.eq(add(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), 12);
assert.eq(test(1), 12)
}

Expand Down
47 changes: 47 additions & 0 deletions JSTests/wasm/ipint-tests/ipint-test-local-large.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { instantiate } from "../wabt-wrapper.js"
import * as assert from "../assert.js"

let wat = `
(module
(func (export "test") (param i32) (result i32)
(local
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32
)
(local.get 0)
(local.set 199)
(i32.const 15)
(local.set 200)
(i32.const 16)
(local.tee 201)
(local.get 201)
(local.get 200)
(i32.add)
(local.tee 206)
(return)
)
)
`

async function test() {
const instance = await instantiate(wat, {});
const { test } = instance.exports
assert.eq(test(5), 31)
}

assert.asyncTest(test())
84 changes: 84 additions & 0 deletions JSTests/wasm/ipint-tests/ipint-test-nesting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { instantiate } from "../wabt-wrapper.js"
import * as assert from "../assert.js"

let wat = `
(module
(func (export "test") (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(block (result i32)
(i32.const 3)
(br 5)
)
)
)
)
)
)
)
)
)
)
)
(block (param i32) (result i32)
(block (result i32)
(i32.const 2)
)
(i32.add)
)
(return)
)
(func (export "test2") (param i32) (result i32)
(block
(block
(block
(loop
(block
(loop
(block
(local.get 0)
(i32.const 1)
(i32.add)
(local.set 0)
)
)
)
(loop
(block
(nop)
)
)
)
)
)
(loop
(loop
(loop
(local.get 0)
(local.set 0)
)
)
)
)
(local.get 0)
(return)
)
)
`

async function test() {
const instance = await instantiate(wat, {});
const { test, test2 } = instance.exports
assert.eq(test(), 5)
assert.eq(test2(5), 6)
}

assert.asyncTest(test())
19 changes: 19 additions & 0 deletions JSTests/wasm/ipint-tests/ipint-test-return-minus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { instantiate } from "../wabt-wrapper.js"
import * as assert from "../assert.js"

let wat = `
(module
(func (export "test") (result i32)
(i32.const -1)
(return)
)
)
`

async function test() {
const instance = await instantiate(wat, {});
const { test } = instance.exports
assert.eq(test(), -1)
}

assert.asyncTest(test())
Loading

0 comments on commit 6f23b5f

Please sign in to comment.