Commit 553e70b9 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[wasm] Merge function table and signature table

Both tables are always updated together and are always accessed
together. Thus merge them, reducing code complexity, but also code
space and overhead for accessing them during runtime. Instead of two
weak global handles, we only need one, which also means one less load
for each indirect call.
Merging them also improves cache locality, since signature and code
address are not stored next to each other in memory, so they will very
likely end up in the same cache line.

R=titzer@chromium.org

Change-Id: I862df7de93a98aa602a3895796610c2c520d6f21
Reviewed-on: https://chromium-review.googlesource.com/866868
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50623}
parent 0dddc6fd
...@@ -88,9 +88,7 @@ WasmGraphBuilder::WasmGraphBuilder( ...@@ -88,9 +88,7 @@ WasmGraphBuilder::WasmGraphBuilder(
jsgraph_(jsgraph), jsgraph_(jsgraph),
centry_stub_node_(jsgraph_->HeapConstant(centry_stub)), centry_stub_node_(jsgraph_->HeapConstant(centry_stub)),
env_(env), env_(env),
signature_tables_(zone),
function_tables_(zone), function_tables_(zone),
function_table_sizes_(zone),
cur_buffer_(def_buffer_), cur_buffer_(def_buffer_),
cur_bufsize_(kDefaultBufferSize), cur_bufsize_(kDefaultBufferSize),
has_simd_(ContainsSimd(sig)), has_simd_(ContainsSimd(sig)),
...@@ -2425,45 +2423,39 @@ Node* WasmGraphBuilder::CallIndirect(uint32_t sig_index, Node** args, ...@@ -2425,45 +2423,39 @@ Node* WasmGraphBuilder::CallIndirect(uint32_t sig_index, Node** args,
Node* key = args[0]; Node* key = args[0];
// Bounds check against the table size. // Bounds check against the table size.
Node* size = function_table_sizes_[table_index]; Node* size = function_tables_[table_index].size;
Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size); Node* in_bounds = graph()->NewNode(machine->Uint32LessThan(), key, size);
TrapIfFalse(wasm::kTrapFuncInvalid, in_bounds, position); TrapIfFalse(wasm::kTrapFuncInvalid, in_bounds, position);
Node* table_address = function_tables_[table_index]; Node* table_address = function_tables_[table_index].table_addr;
Node* table = graph()->NewNode( Node* table = graph()->NewNode(
jsgraph()->machine()->Load(MachineType::AnyTagged()), table_address, jsgraph()->machine()->Load(MachineType::AnyTagged()), table_address,
jsgraph()->IntPtrConstant(0), *effect_, *control_); jsgraph()->IntPtrConstant(0), *effect_, *control_);
Node* signatures_address = signature_tables_[table_index];
Node* signatures = graph()->NewNode(
jsgraph()->machine()->Load(MachineType::AnyTagged()), signatures_address,
jsgraph()->IntPtrConstant(0), *effect_, *control_);
// Load signature from the table and check. // Load signature from the table and check.
// The table is a FixedArray; signatures are encoded as SMIs. // The table is a FixedArray; signatures are encoded as SMIs.
// [sig1, sig2, sig3, ...., code1, code2, code3 ...] // [sig1, code1, sig2, code2, sig3, code3, ...]
static_assert(compiler::kFunctionTableEntrySize == 2, "consistency");
static_assert(compiler::kFunctionTableSignatureOffset == 0, "consistency");
static_assert(compiler::kFunctionTableCodeOffset == 1, "consistency");
ElementAccess access = AccessBuilder::ForFixedArrayElement(); ElementAccess access = AccessBuilder::ForFixedArrayElement();
const int fixed_offset = access.header_size - access.tag(); const int fixed_offset = access.header_size - access.tag();
{ Node* key_offset = graph()->NewNode(machine->Word32Shl(), key,
Node* load_sig = graph()->NewNode( Int32Constant(kPointerSizeLog2 + 1));
machine->Load(MachineType::AnyTagged()), signatures, Node* load_sig =
graph()->NewNode(machine->Int32Add(), graph()->NewNode(machine->Load(MachineType::AnyTagged()), table,
graph()->NewNode(machine->Word32Shl(), key, graph()->NewNode(machine->Int32Add(), key_offset,
Int32Constant(kPointerSizeLog2)), Int32Constant(fixed_offset)),
Int32Constant(fixed_offset)), *effect_, *control_);
*effect_, *control_); int32_t canonical_sig_num = env_->module->signature_ids[sig_index];
int32_t canonical_sig_num = env_->module->signature_ids[sig_index]; CHECK_GE(sig_index, 0);
CHECK_GE(sig_index, 0); Node* sig_match = graph()->NewNode(machine->WordEqual(), load_sig,
Node* sig_match = jsgraph()->SmiConstant(canonical_sig_num));
graph()->NewNode(machine->WordEqual(), load_sig, TrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match, position);
jsgraph()->SmiConstant(canonical_sig_num));
TrapIfFalse(wasm::kTrapFuncSigMismatch, sig_match, position);
}
// Load code object from the table. It is held by a Foreign. // Load code object from the table. It is held by a Foreign.
Node* entry = graph()->NewNode( Node* entry = graph()->NewNode(
machine->Load(MachineType::AnyTagged()), table, machine->Load(MachineType::AnyTagged()), table,
graph()->NewNode(machine->Int32Add(), graph()->NewNode(machine->Int32Add(), key_offset,
graph()->NewNode(machine->Word32Shl(), key, Uint32Constant(fixed_offset + kPointerSize)),
Int32Constant(kPointerSizeLog2)),
Uint32Constant(fixed_offset)),
*effect_, *control_); *effect_, *control_);
if (FLAG_wasm_jit_to_native) { if (FLAG_wasm_jit_to_native) {
Node* address = graph()->NewNode( Node* address = graph()->NewNode(
...@@ -3426,18 +3418,14 @@ void WasmGraphBuilder::EnsureFunctionTableNodes() { ...@@ -3426,18 +3418,14 @@ void WasmGraphBuilder::EnsureFunctionTableNodes() {
for (size_t i = 0; i < tables_size; ++i) { for (size_t i = 0; i < tables_size; ++i) {
wasm::GlobalHandleAddress function_handle_address = wasm::GlobalHandleAddress function_handle_address =
env_->function_tables[i]; env_->function_tables[i];
wasm::GlobalHandleAddress signature_handle_address = Node* table_addr = jsgraph()->RelocatableIntPtrConstant(
env_->signature_tables[i];
function_tables_.push_back(jsgraph()->RelocatableIntPtrConstant(
reinterpret_cast<intptr_t>(function_handle_address), reinterpret_cast<intptr_t>(function_handle_address),
RelocInfo::WASM_GLOBAL_HANDLE)); RelocInfo::WASM_GLOBAL_HANDLE);
signature_tables_.push_back(jsgraph()->RelocatableIntPtrConstant(
reinterpret_cast<intptr_t>(signature_handle_address),
RelocInfo::WASM_GLOBAL_HANDLE));
uint32_t table_size = env_->module->function_tables[i].initial_size; uint32_t table_size = env_->module->function_tables[i].initial_size;
function_table_sizes_.push_back(jsgraph()->RelocatableInt32Constant( Node* size = jsgraph()->RelocatableInt32Constant(
static_cast<uint32_t>(table_size), static_cast<uint32_t>(table_size),
RelocInfo::WASM_FUNCTION_TABLE_SIZE_REFERENCE)); RelocInfo::WASM_FUNCTION_TABLE_SIZE_REFERENCE);
function_tables_.push_back({table_addr, size});
} }
} }
...@@ -4451,14 +4439,11 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module, ...@@ -4451,14 +4439,11 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::WasmModule* module,
Node* effect = nullptr; Node* effect = nullptr;
// TODO(titzer): compile JS to WASM wrappers without a {ModuleEnv}. // TODO(titzer): compile JS to WASM wrappers without a {ModuleEnv}.
ModuleEnv env = {module, ModuleEnv env(module,
std::vector<Address>(), // function_tables // TODO(mtrofin): remove the Illegal builtin when we don't need
std::vector<Address>(), // signature_tables // FLAG_wasm_jit_to_native
// TODO(mtrofin): remove these 2 lines when we don't need BUILTIN_CODE(isolate, Illegal), // default_function_code
// FLAG_wasm_jit_to_native use_trap_handler);
std::vector<Handle<Code>>(), // function_code
BUILTIN_CODE(isolate, Illegal), // default_function_code
use_trap_handler};
WasmGraphBuilder builder(&env, &zone, &jsgraph, WasmGraphBuilder builder(&env, &zone, &jsgraph,
CEntryStub(isolate, 1).GetCode(), func->sig); CEntryStub(isolate, 1).GetCode(), func->sig);
...@@ -4571,12 +4556,7 @@ Handle<Code> CompileWasmToJSWrapper( ...@@ -4571,12 +4556,7 @@ Handle<Code> CompileWasmToJSWrapper(
origin == wasm::kAsmJsOrigin ? new (&zone) SourcePositionTable(&graph) origin == wasm::kAsmJsOrigin ? new (&zone) SourcePositionTable(&graph)
: nullptr; : nullptr;
ModuleEnv env = {nullptr, ModuleEnv env(nullptr, Handle<Code>::null(), use_trap_handler);
std::vector<Address>(),
std::vector<Address>(),
std::vector<Handle<Code>>(),
Handle<Code>(),
use_trap_handler};
WasmGraphBuilder builder(&env, &zone, &jsgraph, WasmGraphBuilder builder(&env, &zone, &jsgraph,
CEntryStub(isolate, 1).GetCode(), sig, CEntryStub(isolate, 1).GetCode(), sig,
source_position_table); source_position_table);
...@@ -4663,13 +4643,9 @@ Handle<Code> CompileWasmToWasmWrapper(Isolate* isolate, WasmCodeWrapper target, ...@@ -4663,13 +4643,9 @@ Handle<Code> CompileWasmToWasmWrapper(Isolate* isolate, WasmCodeWrapper target,
Node* control = nullptr; Node* control = nullptr;
Node* effect = nullptr; Node* effect = nullptr;
ModuleEnv env = { ModuleEnv env(
nullptr, nullptr, Handle<Code>::null(),
std::vector<Address>(), !target.IsCodeObject() && target.GetWasmCode()->HasTrapHandlerIndex());
std::vector<Address>(),
std::vector<Handle<Code>>(),
Handle<Code>(),
!target.IsCodeObject() && target.GetWasmCode()->HasTrapHandlerIndex()};
WasmGraphBuilder builder(&env, &zone, &jsgraph, Handle<Code>(), sig); WasmGraphBuilder builder(&env, &zone, &jsgraph, Handle<Code>(), sig);
builder.set_control_ptr(&control); builder.set_control_ptr(&control);
builder.set_effect_ptr(&effect); builder.set_effect_ptr(&effect);
...@@ -4856,13 +4832,6 @@ Handle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig, ...@@ -4856,13 +4832,6 @@ Handle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig,
SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction( SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction(
double* decode_ms) { double* decode_ms) {
#if DEBUG
if (env_) {
size_t tables_size = env_->module->function_tables.size();
DCHECK_EQ(tables_size, env_->function_tables.size());
DCHECK_EQ(tables_size, env_->signature_tables.size());
}
#endif
base::ElapsedTimer decode_timer; base::ElapsedTimer decode_timer;
if (FLAG_trace_wasm_decode_time) { if (FLAG_trace_wasm_decode_time) {
......
...@@ -43,25 +43,34 @@ class WasmCode; ...@@ -43,25 +43,34 @@ class WasmCode;
namespace compiler { namespace compiler {
// Indirect function tables contain a <smi(sig), code> pair for each entry.
enum FunctionTableEntries : int {
kFunctionTableSignatureOffset = 0,
kFunctionTableCodeOffset = 1,
kFunctionTableEntrySize = 2
};
constexpr inline int FunctionTableSigOffset(int i) {
return kFunctionTableEntrySize * i + kFunctionTableSignatureOffset;
}
constexpr inline int FunctionTableCodeOffset(int i) {
return kFunctionTableEntrySize * i + kFunctionTableCodeOffset;
}
// The {ModuleEnv} encapsulates the module data that is used by the // The {ModuleEnv} encapsulates the module data that is used by the
// {WasmGraphBuilder} during graph building. It represents the parameters to // {WasmGraphBuilder} during graph building. It represents the parameters to
// which the compiled code should be specialized, including which code to call // which the compiled code should be specialized, including which code to call
// for direct calls {function_code}, which tables to use for indirect calls // for direct calls {function_code}, which tables to use for indirect calls
// {function_tables}, memory start address and size {mem_start, mem_size}, // {function_tables}, memory start address and size {mem_start, mem_size},
// as well as signature maps {signature_maps} and the module itself {module}. // as well as the module itself {module}.
// ModuleEnvs are shareable across multiple compilations. // ModuleEnvs are shareable across multiple compilations.
struct ModuleEnv { struct ModuleEnv {
// A pointer to the decoded module's static representation. // A pointer to the decoded module's static representation.
const wasm::WasmModule* module; const wasm::WasmModule* module;
// The function tables are FixedArrays of code used to dispatch indirect // The function tables are FixedArrays of <smi, code> pairs used to signature
// calls. (the same length as module.function_tables). We use the address // check and dispatch indirect calls. It has the same length as
// to a global handle to the FixedArray. // module.function_tables. We use the address to a global handle to the
// FixedArray.
const std::vector<Address> function_tables; const std::vector<Address> function_tables;
// The signatures tables are FixedArrays of SMIs used to check signatures
// match at runtime.
// (the same length as module.function_tables)
// We use the address to a global handle to the FixedArray.
const std::vector<Address> signature_tables;
// TODO(mtrofin): remove these 2 once we don't need FLAG_wasm_jit_to_native // TODO(mtrofin): remove these 2 once we don't need FLAG_wasm_jit_to_native
// Contains the code objects to call for each direct call. // Contains the code objects to call for each direct call.
...@@ -72,6 +81,22 @@ struct ModuleEnv { ...@@ -72,6 +81,22 @@ struct ModuleEnv {
// True if trap handling should be used in compiled code, rather than // True if trap handling should be used in compiled code, rather than
// compiling in bounds checks for each memory access. // compiling in bounds checks for each memory access.
const bool use_trap_handler; const bool use_trap_handler;
ModuleEnv(const wasm::WasmModule* module, Handle<Code> default_function_code,
bool use_trap_handler)
: module(module),
default_function_code(default_function_code),
use_trap_handler(use_trap_handler) {}
ModuleEnv(const wasm::WasmModule* module,
std::vector<Address> function_tables,
std::vector<Handle<Code>> function_code,
Handle<Code> default_function_code, bool use_trap_handler)
: module(module),
function_tables(std::move(function_tables)),
function_code(std::move(function_code)),
default_function_code(default_function_code),
use_trap_handler(use_trap_handler) {}
}; };
enum RuntimeExceptionSupport : bool { enum RuntimeExceptionSupport : bool {
...@@ -432,9 +457,11 @@ class WasmGraphBuilder { ...@@ -432,9 +457,11 @@ class WasmGraphBuilder {
// wrappers or interpreter stubs. // wrappers or interpreter stubs.
ModuleEnv* const env_ = nullptr; ModuleEnv* const env_ = nullptr;
SetOncePointer<Node> wasm_context_; SetOncePointer<Node> wasm_context_;
NodeVector signature_tables_; struct FunctionTableNodes {
NodeVector function_tables_; Node* table_addr;
NodeVector function_table_sizes_; Node* size;
};
ZoneVector<FunctionTableNodes> function_tables_;
Node** control_ = nullptr; Node** control_ = nullptr;
Node** effect_ = nullptr; Node** effect_ = nullptr;
WasmContextCacheNodes* context_cache_ = nullptr; WasmContextCacheNodes* context_cache_ = nullptr;
......
This diff is collapsed.
...@@ -248,16 +248,10 @@ class V8_EXPORT_PRIVATE NativeModule final { ...@@ -248,16 +248,10 @@ class V8_EXPORT_PRIVATE NativeModule final {
std::vector<wasm::GlobalHandleAddress>& function_tables() { std::vector<wasm::GlobalHandleAddress>& function_tables() {
return specialization_data_.function_tables; return specialization_data_.function_tables;
} }
std::vector<wasm::GlobalHandleAddress>& signature_tables() {
return specialization_data_.signature_tables;
}
std::vector<wasm::GlobalHandleAddress>& empty_function_tables() { std::vector<wasm::GlobalHandleAddress>& empty_function_tables() {
return specialization_data_.empty_function_tables; return specialization_data_.empty_function_tables;
} }
std::vector<wasm::GlobalHandleAddress>& empty_signature_tables() {
return specialization_data_.empty_signature_tables;
}
uint32_t num_imported_functions() const { return num_imported_functions_; } uint32_t num_imported_functions() const { return num_imported_functions_; }
size_t num_function_tables() const { size_t num_function_tables() const {
...@@ -337,9 +331,7 @@ class V8_EXPORT_PRIVATE NativeModule final { ...@@ -337,9 +331,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
// elements a 1 line copy. // elements a 1 line copy.
struct { struct {
std::vector<wasm::GlobalHandleAddress> function_tables; std::vector<wasm::GlobalHandleAddress> function_tables;
std::vector<wasm::GlobalHandleAddress> signature_tables;
std::vector<wasm::GlobalHandleAddress> empty_function_tables; std::vector<wasm::GlobalHandleAddress> empty_function_tables;
std::vector<wasm::GlobalHandleAddress> empty_signature_tables;
} specialization_data_; } specialization_data_;
}; };
......
...@@ -2558,63 +2558,57 @@ class ThreadImpl { ...@@ -2558,63 +2558,57 @@ class ThreadImpl {
if (!FLAG_wasm_jit_to_native) { if (!FLAG_wasm_jit_to_native) {
// Check signature. // Check signature.
FixedArray* sig_tables = compiled_module->signature_tables(); FixedArray* fun_tables = compiled_module->function_tables();
if (table_index >= static_cast<uint32_t>(sig_tables->length())) { if (table_index >= static_cast<uint32_t>(fun_tables->length())) {
return {ExternalCallResult::INVALID_FUNC}; return {ExternalCallResult::INVALID_FUNC};
} }
// Reconstitute the global handle to sig_table, and, further below, // Reconstitute the global handle to the function table, from the
// to the function table, from the address stored in the // address stored in the respective table of tables.
// respective table of tables.
int table_index_as_int = static_cast<int>(table_index); int table_index_as_int = static_cast<int>(table_index);
Handle<FixedArray> sig_table(reinterpret_cast<FixedArray**>( FixedArray* fun_table = *reinterpret_cast<FixedArray**>(
WasmCompiledModule::GetTableValue(sig_tables, table_index_as_int))); WasmCompiledModule::GetTableValue(fun_tables, table_index_as_int));
if (entry_index >= static_cast<uint32_t>(sig_table->length())) { // Function tables store <smi, code> pairs.
int num_funcs_in_table =
fun_table->length() / compiler::kFunctionTableEntrySize;
if (entry_index >= static_cast<uint32_t>(num_funcs_in_table)) {
return {ExternalCallResult::INVALID_FUNC}; return {ExternalCallResult::INVALID_FUNC};
} }
int found_sig = int found_sig = Smi::ToInt(fun_table->get(
Smi::ToInt(sig_table->get(static_cast<int>(entry_index))); compiler::FunctionTableSigOffset(static_cast<int>(entry_index))));
if (static_cast<uint32_t>(found_sig) != canonical_sig_index) { if (static_cast<uint32_t>(found_sig) != canonical_sig_index) {
return {ExternalCallResult::SIGNATURE_MISMATCH}; return {ExternalCallResult::SIGNATURE_MISMATCH};
} }
// Get code object. // Get code object.
FixedArray* fun_tables = compiled_module->function_tables(); target_gc = Code::cast(fun_table->get(
DCHECK_EQ(sig_tables->length(), fun_tables->length()); compiler::FunctionTableCodeOffset(static_cast<int>(entry_index))));
Handle<FixedArray> fun_table(reinterpret_cast<FixedArray**>(
WasmCompiledModule::GetTableValue(fun_tables, table_index_as_int)));
DCHECK_EQ(sig_table->length(), fun_table->length());
target_gc = Code::cast(fun_table->get(static_cast<int>(entry_index)));
} else { } else {
// Check signature. // Check signature.
std::vector<GlobalHandleAddress>& sig_tables = std::vector<GlobalHandleAddress>& fun_tables =
compiled_module->GetNativeModule()->signature_tables(); compiled_module->GetNativeModule()->function_tables();
if (table_index >= sig_tables.size()) { if (table_index >= fun_tables.size()) {
return {ExternalCallResult::INVALID_FUNC}; return {ExternalCallResult::INVALID_FUNC};
} }
// Reconstitute the global handle to sig_table, and, further below, // Reconstitute the global handle to the function table, from the
// to the function table, from the address stored in the // address stored in the respective table of tables.
// respective table of tables. FixedArray* fun_table =
int table_index_as_int = static_cast<int>(table_index); *reinterpret_cast<FixedArray**>(fun_tables[table_index]);
Handle<FixedArray> sig_table( // Function tables store <smi, code> pairs.
reinterpret_cast<FixedArray**>(sig_tables[table_index_as_int])); int num_funcs_in_table =
if (entry_index >= static_cast<uint32_t>(sig_table->length())) { fun_table->length() / compiler::kFunctionTableEntrySize;
if (entry_index >= static_cast<uint32_t>(num_funcs_in_table)) {
return {ExternalCallResult::INVALID_FUNC}; return {ExternalCallResult::INVALID_FUNC};
} }
int found_sig = int found_sig = Smi::ToInt(fun_table->get(
Smi::ToInt(sig_table->get(static_cast<int>(entry_index))); compiler::FunctionTableSigOffset(static_cast<int>(entry_index))));
if (static_cast<uint32_t>(found_sig) != canonical_sig_index) { if (static_cast<uint32_t>(found_sig) != canonical_sig_index) {
return {ExternalCallResult::SIGNATURE_MISMATCH}; return {ExternalCallResult::SIGNATURE_MISMATCH};
} }
// Get code object. // Get code object.
std::vector<GlobalHandleAddress>& fun_tables =
compiled_module->GetNativeModule()->function_tables();
DCHECK_EQ(sig_tables.size(), fun_tables.size());
Handle<FixedArray> fun_table(
reinterpret_cast<FixedArray**>(fun_tables[table_index_as_int]));
DCHECK_EQ(sig_table->length(), fun_table->length());
Address first_instr = Address first_instr =
Foreign::cast(fun_table->get(static_cast<int>(entry_index))) Foreign::cast(fun_table->get(compiler::FunctionTableCodeOffset(
static_cast<int>(entry_index))))
->foreign_address(); ->foreign_address();
target = target =
isolate->wasm_engine()->code_manager()->GetCodeFromStartAddress( isolate->wasm_engine()->code_manager()->GetCodeFromStartAddress(
......
...@@ -56,8 +56,6 @@ OPTIONAL_ACCESSORS(WasmInstanceObject, table_object, WasmTableObject, ...@@ -56,8 +56,6 @@ OPTIONAL_ACCESSORS(WasmInstanceObject, table_object, WasmTableObject,
kTableObjectOffset) kTableObjectOffset)
OPTIONAL_ACCESSORS(WasmInstanceObject, function_tables, FixedArray, OPTIONAL_ACCESSORS(WasmInstanceObject, function_tables, FixedArray,
kFunctionTablesOffset) kFunctionTablesOffset)
OPTIONAL_ACCESSORS(WasmInstanceObject, signature_tables, FixedArray,
kSignatureTablesOffset)
ACCESSORS(WasmInstanceObject, directly_called_instances, FixedArray, ACCESSORS(WasmInstanceObject, directly_called_instances, FixedArray,
kDirectlyCalledInstancesOffset) kDirectlyCalledInstancesOffset)
ACCESSORS(WasmInstanceObject, js_imports_table, FixedArray, ACCESSORS(WasmInstanceObject, js_imports_table, FixedArray,
......
This diff is collapsed.
...@@ -132,14 +132,12 @@ class WasmTableObject : public JSObject { ...@@ -132,14 +132,12 @@ class WasmTableObject : public JSObject {
static void AddDispatchTable(Isolate* isolate, Handle<WasmTableObject> table, static void AddDispatchTable(Isolate* isolate, Handle<WasmTableObject> table,
Handle<WasmInstanceObject> instance, Handle<WasmInstanceObject> instance,
int table_index, int table_index,
Handle<FixedArray> function_table, Handle<FixedArray> function_table);
Handle<FixedArray> signature_table);
static void Set(Isolate* isolate, Handle<WasmTableObject> table, static void Set(Isolate* isolate, Handle<WasmTableObject> table,
int32_t index, Handle<JSFunction> function); int32_t index, Handle<JSFunction> function);
static void UpdateDispatchTables(Isolate* isolate, static void UpdateDispatchTables(Handle<WasmTableObject> table, int index,
Handle<WasmTableObject> table, int index,
wasm::FunctionSig* sig, wasm::FunctionSig* sig,
Handle<Object> code_or_foreign); Handle<Object> code_or_foreign);
}; };
...@@ -196,7 +194,6 @@ class WasmInstanceObject : public JSObject { ...@@ -196,7 +194,6 @@ class WasmInstanceObject : public JSObject {
DECL_OPTIONAL_ACCESSORS(debug_info, WasmDebugInfo) DECL_OPTIONAL_ACCESSORS(debug_info, WasmDebugInfo)
DECL_OPTIONAL_ACCESSORS(table_object, WasmTableObject) DECL_OPTIONAL_ACCESSORS(table_object, WasmTableObject)
DECL_OPTIONAL_ACCESSORS(function_tables, FixedArray) DECL_OPTIONAL_ACCESSORS(function_tables, FixedArray)
DECL_OPTIONAL_ACCESSORS(signature_tables, FixedArray)
// FixedArray of all instances whose code was imported // FixedArray of all instances whose code was imported
DECL_OPTIONAL_ACCESSORS(directly_called_instances, FixedArray) DECL_OPTIONAL_ACCESSORS(directly_called_instances, FixedArray)
...@@ -211,7 +208,6 @@ class WasmInstanceObject : public JSObject { ...@@ -211,7 +208,6 @@ class WasmInstanceObject : public JSObject {
kDebugInfoIndex, kDebugInfoIndex,
kTableObjectIndex, kTableObjectIndex,
kFunctionTablesIndex, kFunctionTablesIndex,
kSignatureTablesIndex,
kDirectlyCalledInstancesIndex, kDirectlyCalledInstancesIndex,
kJsImportsTableIndex, kJsImportsTableIndex,
kFieldCount kFieldCount
...@@ -226,7 +222,6 @@ class WasmInstanceObject : public JSObject { ...@@ -226,7 +222,6 @@ class WasmInstanceObject : public JSObject {
DEF_OFFSET(DebugInfo) DEF_OFFSET(DebugInfo)
DEF_OFFSET(TableObject) DEF_OFFSET(TableObject)
DEF_OFFSET(FunctionTables) DEF_OFFSET(FunctionTables)
DEF_OFFSET(SignatureTables)
DEF_OFFSET(DirectlyCalledInstances) DEF_OFFSET(DirectlyCalledInstances)
DEF_OFFSET(JsImportsTable) DEF_OFFSET(JsImportsTable)
...@@ -519,7 +514,6 @@ class WasmCompiledModule : public FixedArray { ...@@ -519,7 +514,6 @@ class WasmCompiledModule : public FixedArray {
Isolate* isolate, wasm::WasmModule* module, Handle<FixedArray> code_table, Isolate* isolate, wasm::WasmModule* module, Handle<FixedArray> code_table,
Handle<FixedArray> export_wrappers, Handle<FixedArray> export_wrappers,
const std::vector<wasm::GlobalHandleAddress>& function_tables, const std::vector<wasm::GlobalHandleAddress>& function_tables,
const std::vector<wasm::GlobalHandleAddress>& signature_tables,
bool use_trap_hander); bool use_trap_hander);
static Handle<WasmCompiledModule> Clone(Isolate* isolate, static Handle<WasmCompiledModule> Clone(Isolate* isolate,
......
...@@ -213,8 +213,8 @@ size_t NativeModuleSerializer::MeasureHeader() const { ...@@ -213,8 +213,8 @@ size_t NativeModuleSerializer::MeasureHeader() const {
sizeof( sizeof(
uint32_t) + // imported fcts - i.e. index of first wasm function uint32_t) + // imported fcts - i.e. index of first wasm function
sizeof(uint32_t) + // table count sizeof(uint32_t) + // table count
native_module_->specialization_data_.function_tables.size() * native_module_->specialization_data_.function_tables.size()
2 // 2 same-sized tables, containing pointers // function table, containing pointers
* sizeof(GlobalHandleAddress); * sizeof(GlobalHandleAddress);
} }
...@@ -231,7 +231,6 @@ void NativeModuleSerializer::BufferHeader() { ...@@ -231,7 +231,6 @@ void NativeModuleSerializer::BufferHeader() {
e = native_module_->specialization_data_.function_tables.size(); e = native_module_->specialization_data_.function_tables.size();
i < e; ++i) { i < e; ++i) {
writer.Write(native_module_->specialization_data_.function_tables[i]); writer.Write(native_module_->specialization_data_.function_tables[i]);
writer.Write(native_module_->specialization_data_.signature_tables[i]);
} }
} }
...@@ -558,18 +557,14 @@ bool NativeModuleDeserializer::ReadHeader() { ...@@ -558,18 +557,14 @@ bool NativeModuleDeserializer::ReadHeader() {
if (!ok) return false; if (!ok) return false;
size_t table_count = reader.Read<uint32_t>(); size_t table_count = reader.Read<uint32_t>();
std::vector<GlobalHandleAddress> sigs(table_count);
std::vector<GlobalHandleAddress> funcs(table_count); std::vector<GlobalHandleAddress> funcs(table_count);
for (size_t i = 0; i < table_count; ++i) { for (size_t i = 0; i < table_count; ++i) {
funcs[i] = reader.Read<GlobalHandleAddress>(); funcs[i] = reader.Read<GlobalHandleAddress>();
sigs[i] = reader.Read<GlobalHandleAddress>();
} }
native_module_->signature_tables() = sigs;
native_module_->function_tables() = funcs; native_module_->function_tables() = funcs;
// resize, so that from here on the native module can be // resize, so that from here on the native module can be
// asked about num_function_tables(). // asked about num_function_tables().
native_module_->empty_function_tables().resize(table_count); native_module_->empty_function_tables().resize(table_count);
native_module_->empty_signature_tables().resize(table_count);
unread_ = unread_ + (start_size - reader.current_buffer().size()); unread_ = unread_ + (start_size - reader.current_buffer().size());
return true; return true;
...@@ -739,9 +734,8 @@ MaybeHandle<WasmCompiledModule> DeserializeNativeModule( ...@@ -739,9 +734,8 @@ MaybeHandle<WasmCompiledModule> DeserializeNativeModule(
static_cast<int>(export_wrappers_size), TENURED); static_cast<int>(export_wrappers_size), TENURED);
Handle<WasmCompiledModule> compiled_module = WasmCompiledModule::New( Handle<WasmCompiledModule> compiled_module = WasmCompiledModule::New(
isolate, shared->module(), isolate->factory()->NewFixedArray(0, TENURED), isolate, shared->module(), isolate->factory()->empty_fixed_array(),
export_wrappers, std::vector<wasm::GlobalHandleAddress>(), export_wrappers, std::vector<wasm::GlobalHandleAddress>(),
std::vector<wasm::GlobalHandleAddress>(),
trap_handler::IsTrapHandlerEnabled()); trap_handler::IsTrapHandlerEnabled());
compiled_module->OnWasmModuleDecodingComplete(shared); compiled_module->OnWasmModuleDecodingComplete(shared);
NativeModuleDeserializer deserializer(isolate, NativeModuleDeserializer deserializer(isolate,
......
...@@ -144,8 +144,8 @@ Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) { ...@@ -144,8 +144,8 @@ Handle<JSFunction> TestingModuleBuilder::WrapCode(uint32_t index) {
return ret; return ret;
} }
void TestingModuleBuilder::AddIndirectFunctionTable(uint16_t* function_indexes, void TestingModuleBuilder::AddIndirectFunctionTable(
uint32_t table_size) { const uint16_t* function_indexes, uint32_t table_size) {
test_module_.function_tables.emplace_back(); test_module_.function_tables.emplace_back();
WasmIndirectFunctionTable& table = test_module_.function_tables.back(); WasmIndirectFunctionTable& table = test_module_.function_tables.back();
table.initial_size = table_size; table.initial_size = table_size;
...@@ -155,14 +155,10 @@ void TestingModuleBuilder::AddIndirectFunctionTable(uint16_t* function_indexes, ...@@ -155,14 +155,10 @@ void TestingModuleBuilder::AddIndirectFunctionTable(uint16_t* function_indexes,
table.values.push_back(function_indexes[i]); table.values.push_back(function_indexes[i]);
} }
FixedArray* func_table = *isolate_->factory()->NewFixedArray(
table_size * compiler::kFunctionTableEntrySize);
function_tables_.push_back( function_tables_.push_back(
isolate_->global_handles() isolate_->global_handles()->Create(func_table).address());
->Create(*isolate_->factory()->NewFixedArray(table_size))
.address());
signature_tables_.push_back(
isolate_->global_handles()
->Create(*isolate_->factory()->NewFixedArray(table_size))
.address());
} }
void TestingModuleBuilder::PopulateIndirectFunctionTable() { void TestingModuleBuilder::PopulateIndirectFunctionTable() {
...@@ -172,22 +168,23 @@ void TestingModuleBuilder::PopulateIndirectFunctionTable() { ...@@ -172,22 +168,23 @@ void TestingModuleBuilder::PopulateIndirectFunctionTable() {
WasmIndirectFunctionTable& table = test_module_.function_tables[i]; WasmIndirectFunctionTable& table = test_module_.function_tables[i];
Handle<FixedArray> function_table( Handle<FixedArray> function_table(
reinterpret_cast<FixedArray**>(function_tables_[i])); reinterpret_cast<FixedArray**>(function_tables_[i]));
Handle<FixedArray> signature_table(
reinterpret_cast<FixedArray**>(signature_tables_[i]));
int table_size = static_cast<int>(table.values.size()); int table_size = static_cast<int>(table.values.size());
for (int j = 0; j < table_size; j++) { for (int j = 0; j < table_size; j++) {
WasmFunction& function = test_module_.functions[table.values[j]]; WasmFunction& function = test_module_.functions[table.values[j]];
signature_table->set( function_table->set(
j, Smi::FromInt(test_module_.signature_map.Find(function.sig))); compiler::FunctionTableSigOffset(j),
Smi::FromInt(test_module_.signature_map.Find(function.sig)));
if (FLAG_wasm_jit_to_native) { if (FLAG_wasm_jit_to_native) {
Handle<Foreign> foreign_holder = isolate_->factory()->NewForeign( Handle<Foreign> foreign_holder = isolate_->factory()->NewForeign(
native_module_->GetCode(function.func_index) native_module_->GetCode(function.func_index)
->instructions() ->instructions()
.start(), .start(),
TENURED); TENURED);
function_table->set(j, *foreign_holder); function_table->set(compiler::FunctionTableCodeOffset(j),
*foreign_holder);
} else { } else {
function_table->set(j, *function_code_[function.func_index]); function_table->set(compiler::FunctionTableCodeOffset(j),
*function_code_[function.func_index]);
} }
} }
} }
...@@ -211,9 +208,8 @@ uint32_t TestingModuleBuilder::AddBytes(Vector<const byte> bytes) { ...@@ -211,9 +208,8 @@ uint32_t TestingModuleBuilder::AddBytes(Vector<const byte> bytes) {
} }
compiler::ModuleEnv TestingModuleBuilder::CreateModuleEnv() { compiler::ModuleEnv TestingModuleBuilder::CreateModuleEnv() {
return {&test_module_, function_tables_, return {&test_module_, function_tables_, function_code_, Handle<Code>::null(),
signature_tables_, function_code_, trap_handler::IsTrapHandlerEnabled()};
Handle<Code>::null(), trap_handler::IsTrapHandlerEnabled()};
} }
const WasmGlobal* TestingModuleBuilder::AddGlobal(ValueType type) { const WasmGlobal* TestingModuleBuilder::AddGlobal(ValueType type) {
...@@ -244,7 +240,7 @@ Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() { ...@@ -244,7 +240,7 @@ Handle<WasmInstanceObject> TestingModuleBuilder::InitInstanceObject() {
Handle<FixedArray> export_wrappers = isolate_->factory()->NewFixedArray(0); Handle<FixedArray> export_wrappers = isolate_->factory()->NewFixedArray(0);
Handle<WasmCompiledModule> compiled_module = WasmCompiledModule::New( Handle<WasmCompiledModule> compiled_module = WasmCompiledModule::New(
isolate_, test_module_ptr_, code_table, export_wrappers, function_tables_, isolate_, test_module_ptr_, code_table, export_wrappers, function_tables_,
signature_tables_, trap_handler::IsTrapHandlerEnabled()); trap_handler::IsTrapHandlerEnabled());
compiled_module->OnWasmModuleDecodingComplete(shared_module_data); compiled_module->OnWasmModuleDecodingComplete(shared_module_data);
// This method is called when we initialize TestEnvironment. We don't // This method is called when we initialize TestEnvironment. We don't
// have a memory yet, so we won't create it here. We'll update the // have a memory yet, so we won't create it here. We'll update the
......
...@@ -191,7 +191,7 @@ class TestingModuleBuilder { ...@@ -191,7 +191,7 @@ class TestingModuleBuilder {
function_code_[index] = code; function_code_[index] = code;
} }
void AddIndirectFunctionTable(uint16_t* function_indexes, void AddIndirectFunctionTable(const uint16_t* function_indexes,
uint32_t table_size); uint32_t table_size);
void PopulateIndirectFunctionTable(); void PopulateIndirectFunctionTable();
...@@ -244,7 +244,6 @@ class TestingModuleBuilder { ...@@ -244,7 +244,6 @@ class TestingModuleBuilder {
uint32_t mem_size_; uint32_t mem_size_;
std::vector<Handle<Code>> function_code_; std::vector<Handle<Code>> function_code_;
std::vector<GlobalHandleAddress> function_tables_; std::vector<GlobalHandleAddress> function_tables_;
std::vector<GlobalHandleAddress> signature_tables_;
V8_ALIGNED(16) byte globals_data_[kMaxGlobalsSize]; V8_ALIGNED(16) byte globals_data_[kMaxGlobalsSize];
WasmInterpreter* interpreter_; WasmInterpreter* interpreter_;
WasmExecutionMode execution_mode_; WasmExecutionMode execution_mode_;
......
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