Commit f717e7f5 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Don't put interpreter entries in the code table

For serialization we are using the code table to find the code of all
functions. We want to serialize compiled code though, not interpreter
entries (we currently fail a DCHECK there).
This CL changes the logic to not update the code table with interpreter
entries but instead keeps a separate bit set of interpreted functions.

R=mstarzinger@chromium.org

Bug: v8:8177, chromium:735509
Change-Id: I69c59f92712135ddef667b54114614fad94cc6fc
Reviewed-on: https://chromium-review.googlesource.com/c/1278794Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56644}
parent dda3f136
......@@ -427,11 +427,13 @@ WasmCode* NativeModule::AddOwnedCode(
return code;
}
WasmCode* NativeModule::AddInterpreterEntry(Handle<Code> code, uint32_t index) {
WasmCode* NativeModule::AddInterpreterEntry(Handle<Code> code,
uint32_t func_index) {
WasmCode* ret = AddAnonymousCode(code, WasmCode::kInterpreterEntry);
ret->index_ = index;
ret->index_ = func_index;
base::MutexGuard lock(&allocation_mutex_);
InstallCode(ret);
SetInterpreterRedirection(func_index);
return ret;
}
......@@ -608,10 +610,8 @@ void NativeModule::PublishCode(WasmCode* code) {
base::MutexGuard lock(&allocation_mutex_);
// Skip publishing code if there is an active redirection to the interpreter
// for the given function index, in order to preserve the redirection.
if (has_code(code->index()) &&
this->code(code->index())->kind() == WasmCode::kInterpreterEntry) {
return;
}
if (has_interpreter_redirection(code->index())) return;
if (!code->protected_instructions_.is_empty()) {
code->RegisterTrapHandlerData();
}
......@@ -649,8 +649,10 @@ void NativeModule::InstallCode(WasmCode* code) {
DCHECK_LT(code->index(), num_functions());
DCHECK_LE(module_->num_imported_functions, code->index());
// Update code table.
code_table_[code->index() - module_->num_imported_functions] = code;
// Update code table, except for interpreter entries.
if (code->kind() != WasmCode::kInterpreterEntry) {
code_table_[code->index() - module_->num_imported_functions] = code;
}
// Patch jump table.
uint32_t slot_idx = code->index() - module_->num_imported_functions;
......
......@@ -378,6 +378,30 @@ class V8_EXPORT_PRIVATE NativeModule final {
return {code_table_.get(), module_->num_declared_functions};
}
// Hold the {mutex_} when calling this method.
bool has_interpreter_redirection(uint32_t func_index) {
DCHECK_LT(func_index, num_functions());
DCHECK_LE(module_->num_imported_functions, func_index);
if (!interpreter_redirections_) return false;
uint32_t bitset_idx = func_index - module_->num_imported_functions;
uint8_t byte = interpreter_redirections_[bitset_idx / kBitsPerByte];
return byte & (1 << (bitset_idx % kBitsPerByte));
}
// Hold the {mutex_} when calling this method.
void SetInterpreterRedirection(uint32_t func_index) {
DCHECK_LT(func_index, num_functions());
DCHECK_LE(module_->num_imported_functions, func_index);
if (!interpreter_redirections_) {
interpreter_redirections_.reset(
new uint8_t[RoundUp<kBitsPerByte>(module_->num_declared_functions) /
kBitsPerByte]);
}
uint32_t bitset_idx = func_index - module_->num_imported_functions;
uint8_t& byte = interpreter_redirections_[bitset_idx / kBitsPerByte];
byte |= 1 << (bitset_idx % kBitsPerByte);
}
// Features enabled for this module. We keep a copy of the features that
// were enabled at the time of the creation of this native module,
// to be consistent across asynchronous compilations later.
......@@ -414,6 +438,10 @@ class V8_EXPORT_PRIVATE NativeModule final {
std::unique_ptr<WasmCode* []> code_table_;
// Null if no redirections exist, otherwise a bitset over all functions in
// this module marking those functions that have been redirected.
std::unique_ptr<uint8_t[]> interpreter_redirections_;
DisjointAllocationPool free_code_space_;
DisjointAllocationPool allocated_code_space_;
std::list<VirtualMemory> owned_code_space_;
......
......@@ -545,3 +545,26 @@ function checkStack(stack, expected_lines) {
assertThrows(
() => instance0.exports.main(0), WebAssembly.RuntimeError, 'unreachable');
})();
(function testSerializeInterpreted() {
print(arguments.callee.name);
const builder = new WasmModuleBuilder();
builder.addFunction('main', kSig_i_i)
.addBody([kExprGetLocal, 0, kExprI32Const, 7, kExprI32Add])
.exportFunc();
const wire_bytes = builder.toBuffer();
var module = new WebAssembly.Module(wire_bytes);
const i1 = new WebAssembly.Instance(module);
assertEquals(11, i1.exports.main(4));
const buff = %SerializeWasmModule(module);
module = null;
gc();
module = %DeserializeWasmModule(buff, wire_bytes);
const i2 = new WebAssembly.Instance(module);
assertEquals(11, i2.exports.main(4));
})();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment