| Index: src/wasm/wasm-module.cc
|
| diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc
|
| index 7d4ad83bdd2094ad5c8b9b580c2cd644a88fde5d..2470257735299c590511fb7e82f6d4f2b4152635 100644
|
| --- a/src/wasm/wasm-module.cc
|
| +++ b/src/wasm/wasm-module.cc
|
| @@ -158,19 +158,15 @@
|
|
|
| namespace {
|
| // Internal constants for the layout of the module object.
|
| -enum WasmInstanceFields {
|
| - kWasmCompiledModule = 0,
|
| - kWasmModuleFunctionTable,
|
| - kWasmModuleCodeTable,
|
| - kWasmMemArrayBuffer,
|
| - kWasmGlobalsArrayBuffer,
|
| - // TODO(clemensh): Remove function name array, extract names from module
|
| - // bytes.
|
| - kWasmFunctionNamesArray,
|
| - kWasmModuleBytesString,
|
| - kWasmDebugInfo,
|
| - kWasmModuleInternalFieldCount
|
| -};
|
| +const int kWasmModuleFunctionTable = 0;
|
| +const int kWasmModuleCodeTable = 1;
|
| +const int kWasmMemArrayBuffer = 2;
|
| +const int kWasmGlobalsArrayBuffer = 3;
|
| +// TODO(clemensh): Remove function name array, extract names from module bytes.
|
| +const int kWasmFunctionNamesArray = 4;
|
| +const int kWasmModuleBytesString = 5;
|
| +const int kWasmDebugInfo = 6;
|
| +const int kWasmModuleInternalFieldCount = 7;
|
|
|
| // TODO(mtrofin): Unnecessary once we stop using JS Heap for wasm code.
|
| // For now, each field is expected to have the type commented by its side.
|
| @@ -198,14 +194,8 @@
|
| kDataSegments, // maybe ByteArray.
|
|
|
| kGlobalsSize, // Smi. an uint32_t
|
| - kMemSize, // Smi.an uint32_t
|
| - kMemStart, // MaybeHandle<ArrayBuffer>
|
| kExportMem, // Smi. bool
|
| kOrigin, // Smi. ModuleOrigin
|
| - kNextInstance, // WeakCell. See compiled code cloning.
|
| - kPrevInstance, // WeakCell. See compiled code cloning.
|
| - kOwningInstance, // WeakCell, pointing to the owning instance.
|
| - kModuleObject, // WeakCell, pointing to the module object.
|
| kCompiledWasmObjectTableSize // Sentinel value.
|
| };
|
|
|
| @@ -339,9 +329,8 @@
|
| return buffer;
|
| }
|
|
|
| -void RelocateInstanceCode(Handle<JSObject> instance, Address old_start,
|
| - Address start, uint32_t prev_size,
|
| - uint32_t new_size) {
|
| +void RelocateInstanceCode(Handle<JSObject> instance, Address start,
|
| + uint32_t prev_size, uint32_t new_size) {
|
| Handle<FixedArray> functions = Handle<FixedArray>(
|
| FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable)));
|
| for (int i = 0; i < functions->length(); ++i) {
|
| @@ -350,7 +339,7 @@
|
| int mask = (1 << RelocInfo::WASM_MEMORY_REFERENCE) |
|
| (1 << RelocInfo::WASM_MEMORY_SIZE_REFERENCE);
|
| for (RelocIterator it(*function, mask); !it.done(); it.next()) {
|
| - it.rinfo()->update_wasm_memory_reference(old_start, start, prev_size,
|
| + it.rinfo()->update_wasm_memory_reference(nullptr, start, prev_size,
|
| new_size);
|
| }
|
| }
|
| @@ -372,8 +361,7 @@
|
| return mem_buffer;
|
| }
|
|
|
| -void RelocateGlobals(Handle<JSObject> instance, Address old_start,
|
| - Address globals_start) {
|
| +void RelocateGlobals(Handle<JSObject> instance, Address globals_start) {
|
| Handle<FixedArray> functions = Handle<FixedArray>(
|
| FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable)));
|
| uint32_t function_count = static_cast<uint32_t>(functions->length());
|
| @@ -382,7 +370,7 @@
|
| AllowDeferredHandleDereference embedding_raw_address;
|
| int mask = 1 << RelocInfo::WASM_GLOBAL_REFERENCE;
|
| for (RelocIterator it(*function, mask); !it.done(); it.next()) {
|
| - it.rinfo()->update_wasm_global_reference(old_start, globals_start);
|
| + it.rinfo()->update_wasm_global_reference(nullptr, globals_start);
|
| }
|
| }
|
| }
|
| @@ -413,35 +401,40 @@
|
| }
|
| }
|
|
|
| -bool LinkFunction(Isolate* isolate, Handle<Code> unlinked,
|
| - Handle<FixedArray> code_targets,
|
| - Code::Kind kind = Code::WASM_FUNCTION) {
|
| +bool LinkFunction(Handle<Code> unlinked,
|
| + const std::vector<Handle<Code>>& code_targets,
|
| + Code::Kind kind) {
|
| bool modified = false;
|
| - int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
|
| + int mode_mask = RelocInfo::kCodeTargetMask;
|
| AllowDeferredHandleDereference embedding_raw_address;
|
| for (RelocIterator it(*unlinked, mode_mask); !it.done(); it.next()) {
|
| - Code* target = Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
|
| - if (target->kind() == kind &&
|
| - target->constant_pool_offset() >= kPlaceholderMarker) {
|
| - // Patch direct calls to placeholder code objects.
|
| - uint32_t index = target->constant_pool_offset() - kPlaceholderMarker;
|
| - CHECK(index < static_cast<uint32_t>(code_targets->length()));
|
| - Handle<Code> new_target =
|
| - code_targets->GetValueChecked<Code>(isolate, index);
|
| - if (target != *new_target) {
|
| - it.rinfo()->set_target_address(new_target->instruction_start(),
|
| - UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
|
| - modified = true;
|
| + RelocInfo::Mode mode = it.rinfo()->rmode();
|
| + if (RelocInfo::IsCodeTarget(mode)) {
|
| + Code* target =
|
| + Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
|
| + if (target->kind() == kind &&
|
| + target->constant_pool_offset() >= kPlaceholderMarker) {
|
| + // Patch direct calls to placeholder code objects.
|
| + uint32_t index = target->constant_pool_offset() - kPlaceholderMarker;
|
| + CHECK(index < code_targets.size());
|
| + Handle<Code> new_target = code_targets[index];
|
| + if (target != *new_target) {
|
| + it.rinfo()->set_target_address(new_target->instruction_start(),
|
| + UPDATE_WRITE_BARRIER,
|
| + SKIP_ICACHE_FLUSH);
|
| + modified = true;
|
| + }
|
| }
|
| }
|
| }
|
| return modified;
|
| }
|
|
|
| -void LinkModuleFunctions(Isolate* isolate, Handle<FixedArray> functions) {
|
| - for (int i = 0; i < functions->length(); ++i) {
|
| - Handle<Code> code = functions->GetValueChecked<Code>(isolate, i);
|
| - LinkFunction(isolate, code, functions);
|
| +void LinkModuleFunctions(Isolate* isolate,
|
| + std::vector<Handle<Code>>& functions) {
|
| + for (size_t i = 0; i < functions.size(); ++i) {
|
| + Handle<Code> code = functions[i];
|
| + LinkFunction(code, functions, Code::WASM_FUNCTION);
|
| }
|
| }
|
|
|
| @@ -460,6 +453,8 @@
|
|
|
| for (int i = FLAG_skip_compiling_wasm_funcs; i < functions->length(); ++i) {
|
| Handle<Code> code = functions->GetValueChecked<Code>(isolate, i);
|
| + DCHECK(code->deoptimization_data() == nullptr ||
|
| + code->deoptimization_data()->length() == 0);
|
| Handle<FixedArray> deopt_data =
|
| isolate->factory()->NewFixedArray(2, TENURED);
|
| deopt_data->set(0, *weak_link);
|
| @@ -624,17 +619,6 @@
|
| for (int i = 0; i < functions->length(); ++i) {
|
| RecordStats(isolate, Code::cast(functions->get(i)));
|
| }
|
| -}
|
| -
|
| -Address GetGlobalStartAddressFromCodeTemplate(Object* undefined,
|
| - JSObject* owner) {
|
| - Address old_address = nullptr;
|
| - Object* stored_value = owner->GetInternalField(kWasmGlobalsArrayBuffer);
|
| - if (stored_value != undefined) {
|
| - old_address = static_cast<Address>(
|
| - JSArrayBuffer::cast(stored_value)->backing_store());
|
| - }
|
| - return old_address;
|
| }
|
|
|
| Handle<FixedArray> GetImportsMetadata(Factory* factory,
|
| @@ -928,9 +912,8 @@
|
| }
|
| }
|
|
|
| -bool SetupGlobals(Isolate* isolate, MaybeHandle<JSObject> template_owner,
|
| - Handle<FixedArray> compiled_module, Handle<JSObject> instance,
|
| - ErrorThrower* thrower) {
|
| +bool SetupGlobals(Isolate* isolate, Handle<FixedArray> compiled_module,
|
| + Handle<JSObject> instance, ErrorThrower* thrower) {
|
| uint32_t globals_size = static_cast<uint32_t>(
|
| Smi::cast(compiled_module->get(kGlobalsSize))->value());
|
| if (globals_size > 0) {
|
| @@ -940,13 +923,7 @@
|
| thrower->Error("Out of memory: wasm globals");
|
| return false;
|
| }
|
| - Address old_address =
|
| - template_owner.is_null()
|
| - ? nullptr
|
| - : GetGlobalStartAddressFromCodeTemplate(
|
| - *isolate->factory()->undefined_value(),
|
| - JSObject::cast(*template_owner.ToHandleChecked()));
|
| - RelocateGlobals(instance, old_address,
|
| + RelocateGlobals(instance,
|
| static_cast<Address>(globals_buffer->backing_store()));
|
| instance->SetInternalField(kWasmGlobalsArrayBuffer, *globals_buffer);
|
| }
|
| @@ -972,70 +949,11 @@
|
| instance->SetInternalField(kWasmMemArrayBuffer, *memory);
|
| Address mem_start = static_cast<Address>(memory->backing_store());
|
| uint32_t mem_size = static_cast<uint32_t>(memory->byte_length()->Number());
|
| - uint32_t old_mem_size = static_cast<uint32_t>(
|
| - compiled_module->GetValueChecked<HeapNumber>(isolate, kMemSize)
|
| - ->value());
|
| - MaybeHandle<JSArrayBuffer> old_mem =
|
| - compiled_module->GetValue<JSArrayBuffer>(isolate, kMemStart);
|
| - Address old_mem_start =
|
| - old_mem.is_null()
|
| - ? nullptr
|
| - : static_cast<Address>(old_mem.ToHandleChecked()->backing_store());
|
| - RelocateInstanceCode(instance, old_mem_start, mem_start, old_mem_size,
|
| - mem_size);
|
| + RelocateInstanceCode(instance, mem_start,
|
| + WasmModule::kPageSize * min_mem_pages, mem_size);
|
| LoadDataSegments(compiled_module, mem_start, mem_size);
|
| - compiled_module->GetValueChecked<HeapNumber>(isolate, kMemSize)
|
| - ->set_value(static_cast<double>(mem_size));
|
| - compiled_module->set(kMemStart, *memory);
|
| }
|
| return true;
|
| -}
|
| -
|
| -void FixupFunctionsAndImports(Handle<FixedArray> old_functions,
|
| - Handle<FixedArray> new_functions,
|
| - MaybeHandle<FixedArray> maybe_old_imports,
|
| - MaybeHandle<FixedArray> maybe_new_imports) {
|
| - DCHECK_EQ(new_functions->length(), old_functions->length());
|
| -
|
| - DisallowHeapAllocation no_gc;
|
| - std::map<Code*, Code*> old_to_new_code;
|
| - for (int i = 0; i < new_functions->length(); ++i) {
|
| - old_to_new_code.insert(std::make_pair(Code::cast(old_functions->get(i)),
|
| - Code::cast(new_functions->get(i))));
|
| - }
|
| - DCHECK_EQ(maybe_old_imports.is_null(), maybe_new_imports.is_null());
|
| - if (!maybe_old_imports.is_null()) {
|
| - Handle<FixedArray> old_imports = maybe_old_imports.ToHandleChecked();
|
| - Handle<FixedArray> new_imports = maybe_new_imports.ToHandleChecked();
|
| - DCHECK_EQ(new_imports->length(), old_imports->length());
|
| - for (int i = 0; i < new_imports->length(); ++i) {
|
| - old_to_new_code.insert(std::make_pair(Code::cast(old_imports->get(i)),
|
| - Code::cast(new_imports->get(i))));
|
| - }
|
| - }
|
| - int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
|
| - AllowDeferredHandleDereference embedding_raw_address;
|
| - for (int i = 0; i < new_functions->length(); ++i) {
|
| - Code* wasm_function = Code::cast(new_functions->get(i));
|
| - for (RelocIterator it(wasm_function, mode_mask); !it.done(); it.next()) {
|
| - Code* old_code =
|
| - Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
|
| - if (old_code->kind() == Code::WASM_TO_JS_FUNCTION ||
|
| - old_code->kind() == Code::WASM_FUNCTION) {
|
| - auto found = old_to_new_code.find(old_code);
|
| - DCHECK(found != old_to_new_code.end());
|
| - Code* new_code = found->second;
|
| - // Avoid redundant updates, expected for wasm functions, if we're at the
|
| - // first instance.
|
| - if (new_code == old_code) {
|
| - DCHECK(new_code->kind() == Code::WASM_FUNCTION);
|
| - continue;
|
| - }
|
| - it.rinfo()->set_target_address(new_code->instruction_start(),
|
| - UPDATE_WRITE_BARRIER, SKIP_ICACHE_FLUSH);
|
| - }
|
| - }
|
| - }
|
| }
|
|
|
| bool SetupImports(Isolate* isolate, Handle<FixedArray> compiled_module,
|
| @@ -1056,14 +974,49 @@
|
| }
|
|
|
| RecordStats(isolate, import_code);
|
| +
|
| if (import_code.empty()) return true;
|
|
|
| - Handle<FixedArray> new_imports =
|
| + {
|
| + DisallowHeapAllocation no_gc;
|
| + std::map<Code*, int> import_to_index;
|
| + Handle<FixedArray> mapping =
|
| + compiled_module->GetValueChecked<FixedArray>(isolate, kImportMap);
|
| + for (int i = 0; i < mapping->length(); ++i) {
|
| + import_to_index.insert(std::make_pair(Code::cast(mapping->get(i)), i));
|
| + }
|
| +
|
| + Handle<FixedArray> code_table = Handle<FixedArray>(
|
| + FixedArray::cast(instance->GetInternalField(kWasmModuleCodeTable)));
|
| +
|
| + int mode_mask = RelocInfo::ModeMask(RelocInfo::CODE_TARGET);
|
| + AllowDeferredHandleDereference embedding_raw_address;
|
| + for (int i = 0; i < code_table->length(); ++i) {
|
| + Handle<Code> wasm_function =
|
| + code_table->GetValueChecked<Code>(isolate, i);
|
| + for (RelocIterator it(*wasm_function, mode_mask); !it.done(); it.next()) {
|
| + Code* target =
|
| + Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
|
| + if (target->kind() == Code::WASM_TO_JS_FUNCTION) {
|
| + auto found_index = import_to_index.find(target);
|
| + CHECK(found_index != import_to_index.end());
|
| + int index = found_index->second;
|
| + CHECK(index < static_cast<int>(import_code.size()));
|
| + Handle<Code> new_target = import_code[index];
|
| + it.rinfo()->set_target_address(new_target->instruction_start(),
|
| + UPDATE_WRITE_BARRIER,
|
| + SKIP_ICACHE_FLUSH);
|
| + }
|
| + }
|
| + }
|
| + }
|
| + Handle<FixedArray> new_mapping =
|
| isolate->factory()->NewFixedArray(static_cast<int>(import_code.size()));
|
| - for (int i = 0; i < new_imports->length(); ++i) {
|
| - new_imports->set(i, *import_code[i]);
|
| - }
|
| - compiled_module->set(kImportMap, *new_imports);
|
| + for (int i = 0; i < new_mapping->length(); ++i) {
|
| + new_mapping->set(i, *import_code[i]);
|
| + }
|
| + compiled_module->set(kImportMap, *new_mapping);
|
| +
|
| return true;
|
| }
|
|
|
| @@ -1128,122 +1081,6 @@
|
| return true;
|
| }
|
|
|
| -#define GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(Field) \
|
| - WeakCell* Get##Field(const FixedArray* compiled_module) { \
|
| - Object* obj = compiled_module->get(k##Field); \
|
| - DCHECK_NOT_NULL(obj); \
|
| - if (obj->IsWeakCell()) { \
|
| - return WeakCell::cast(obj); \
|
| - } else { \
|
| - return nullptr; \
|
| - } \
|
| - }
|
| -
|
| -GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(NextInstance)
|
| -GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(PrevInstance)
|
| -GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(OwningInstance)
|
| -GET_COMPILED_MODULE_WEAK_RELATION_OR_NULL(ModuleObject)
|
| -
|
| -static void ResetCompiledModule(Isolate* isolate, JSObject* owner,
|
| - FixedArray* compiled_module) {
|
| - Object* undefined = *isolate->factory()->undefined_value();
|
| - Object* mem_size_obj = compiled_module->get(kMemSize);
|
| - DCHECK(mem_size_obj->IsMutableHeapNumber());
|
| - uint32_t old_mem_size =
|
| - static_cast<uint32_t>(HeapNumber::cast(mem_size_obj)->value());
|
| - Object* mem_start = compiled_module->get(kMemStart);
|
| - Address old_mem_address = nullptr;
|
| - Address globals_start =
|
| - GetGlobalStartAddressFromCodeTemplate(undefined, owner);
|
| -
|
| - if (old_mem_size > 0) {
|
| - CHECK_NE(mem_start, undefined);
|
| - old_mem_address =
|
| - static_cast<Address>(JSArrayBuffer::cast(mem_start)->backing_store());
|
| - }
|
| - int mode_mask = RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_REFERENCE) |
|
| - RelocInfo::ModeMask(RelocInfo::WASM_MEMORY_SIZE_REFERENCE) |
|
| - RelocInfo::ModeMask(RelocInfo::WASM_GLOBAL_REFERENCE);
|
| -
|
| - Object* fct_obj = compiled_module->get(kFunctions);
|
| - if (fct_obj != nullptr && fct_obj != undefined &&
|
| - (old_mem_size > 0 || globals_start != nullptr)) {
|
| - FixedArray* functions = FixedArray::cast(fct_obj);
|
| - for (int i = 0; i < functions->length(); ++i) {
|
| - Code* code = Code::cast(functions->get(i));
|
| - bool changed = false;
|
| - for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
|
| - RelocInfo::Mode mode = it.rinfo()->rmode();
|
| - if (RelocInfo::IsWasmMemoryReference(mode) ||
|
| - RelocInfo::IsWasmMemorySizeReference(mode)) {
|
| - it.rinfo()->update_wasm_memory_reference(old_mem_address, nullptr,
|
| - old_mem_size, old_mem_size);
|
| - changed = true;
|
| - } else {
|
| - CHECK(RelocInfo::IsWasmGlobalReference(mode));
|
| - it.rinfo()->update_wasm_global_reference(globals_start, nullptr);
|
| - changed = true;
|
| - }
|
| - }
|
| - if (changed) {
|
| - Assembler::FlushICache(isolate, code->instruction_start(),
|
| - code->instruction_size());
|
| - }
|
| - }
|
| - }
|
| - compiled_module->set(kOwningInstance, undefined);
|
| - compiled_module->set(kMemStart, undefined);
|
| -}
|
| -
|
| -static void InstanceFinalizer(const v8::WeakCallbackInfo<void>& data) {
|
| - JSObject** p = reinterpret_cast<JSObject**>(data.GetParameter());
|
| - JSObject* owner = *p;
|
| - FixedArray* compiled_module =
|
| - FixedArray::cast(owner->GetInternalField(kWasmCompiledModule));
|
| - Isolate* isolate = reinterpret_cast<Isolate*>(data.GetIsolate());
|
| - Object* undefined = *isolate->factory()->undefined_value();
|
| - WeakCell* weak_module_obj = GetModuleObject(compiled_module);
|
| - DCHECK_NOT_NULL(weak_module_obj);
|
| - // weak_module_obj may have been cleared, meaning the module object
|
| - // was GC-ed. In that case, there won't be any new instances created,
|
| - // and we don't need to maintain the links between instances.
|
| - if (!weak_module_obj->cleared()) {
|
| - JSObject* module_obj = JSObject::cast(weak_module_obj->value());
|
| - FixedArray* current_template =
|
| - FixedArray::cast(module_obj->GetInternalField(0));
|
| - DCHECK_NULL(GetPrevInstance(current_template));
|
| - WeakCell* next = GetNextInstance(compiled_module);
|
| - WeakCell* prev = GetPrevInstance(compiled_module);
|
| -
|
| - if (current_template == compiled_module) {
|
| - if (next == nullptr) {
|
| - ResetCompiledModule(isolate, owner, compiled_module);
|
| - } else {
|
| - DCHECK(next->value()->IsFixedArray());
|
| - module_obj->SetInternalField(0, next->value());
|
| - DCHECK_NULL(prev);
|
| - FixedArray::cast(next->value())->set(kPrevInstance, undefined);
|
| - }
|
| - } else {
|
| - DCHECK(!(prev == nullptr && next == nullptr));
|
| - // the only reason prev or next would be cleared is if the
|
| - // respective objects got collected, but if that happened,
|
| - // we would have relinked the list.
|
| - if (prev != nullptr) {
|
| - DCHECK(!prev->cleared());
|
| - FixedArray::cast(prev->value())
|
| - ->set(kNextInstance, next == nullptr ? undefined : next);
|
| - }
|
| - if (next != nullptr) {
|
| - DCHECK(!next->cleared());
|
| - FixedArray::cast(next->value())
|
| - ->set(kPrevInstance, prev == nullptr ? undefined : prev);
|
| - }
|
| - }
|
| - }
|
| - GlobalHandles::Destroy(reinterpret_cast<Object**>(p));
|
| -}
|
| -
|
| } // namespace
|
|
|
| MaybeHandle<FixedArray> WasmModule::CompileFunctions(
|
| @@ -1318,11 +1155,6 @@
|
| Code* code = *temp_instance_for_compilation.function_code[i];
|
| compiled_functions->set(static_cast<int>(i), code);
|
| }
|
| -
|
| - LinkModuleFunctions(isolate, compiled_functions);
|
| -
|
| - // TODO(mtrofin): do we need to flush the cache here?
|
| - FlushAssemblyCache(isolate, compiled_functions);
|
|
|
| // Create the compiled module object, and populate with compiled functions
|
| // and information needed at instantiation time. This object needs to be
|
| @@ -1419,10 +1251,6 @@
|
| ret->set(kGlobalsSize, Smi::FromInt(globals_size));
|
| ret->set(kExportMem, Smi::FromInt(mem_export));
|
| ret->set(kOrigin, Smi::FromInt(origin));
|
| - Handle<HeapNumber> size_as_object = factory->NewHeapNumber(
|
| - static_cast<double>(temp_instance_for_compilation.mem_size), MUTABLE,
|
| - TENURED);
|
| - ret->set(kMemSize, *size_as_object);
|
| return ret;
|
| }
|
|
|
| @@ -1447,8 +1275,7 @@
|
|
|
| Handle<FixedArray> SetupIndirectFunctionTable(
|
| Isolate* isolate, Handle<FixedArray> wasm_functions,
|
| - Handle<FixedArray> indirect_table_template,
|
| - Handle<FixedArray> tables_to_replace) {
|
| + Handle<FixedArray> indirect_table_template) {
|
| Factory* factory = isolate->factory();
|
| Handle<FixedArray> cloned_indirect_tables =
|
| factory->CopyFixedArray(indirect_table_template);
|
| @@ -1463,13 +1290,10 @@
|
| Handle<FixedArray> cloned_table = factory->CopyFixedArray(orig_table);
|
| cloned_metadata->set(kTable, *cloned_table);
|
| // Patch the cloned code to refer to the cloned kTable.
|
| - Handle<FixedArray> table_to_replace =
|
| - tables_to_replace->GetValueChecked<FixedArray>(isolate, i)
|
| - ->GetValueChecked<FixedArray>(isolate, kTable);
|
| - for (int fct_index = 0; fct_index < wasm_functions->length(); ++fct_index) {
|
| + for (int i = 0; i < wasm_functions->length(); ++i) {
|
| Handle<Code> wasm_function =
|
| - wasm_functions->GetValueChecked<Code>(isolate, fct_index);
|
| - PatchFunctionTable(wasm_function, table_to_replace, cloned_table);
|
| + wasm_functions->GetValueChecked<Code>(isolate, i);
|
| + PatchFunctionTable(wasm_function, orig_table, cloned_table);
|
| }
|
| }
|
| return cloned_indirect_tables;
|
| @@ -1478,24 +1302,7 @@
|
| Handle<FixedArray> CloneModuleForInstance(Isolate* isolate,
|
| Handle<FixedArray> original) {
|
| Factory* factory = isolate->factory();
|
| - bool is_first =
|
| - original->GetValue<WeakCell>(isolate, kOwningInstance).is_null();
|
| -
|
| - if (is_first) {
|
| - return original;
|
| - }
|
| -
|
| - // We insert the latest clone in front.
|
| Handle<FixedArray> clone = factory->CopyFixedArray(original);
|
| - Handle<WeakCell> weak_link_to_wasm_obj =
|
| - original->GetValueChecked<WeakCell>(isolate, kModuleObject);
|
| -
|
| - clone->set(kModuleObject, *weak_link_to_wasm_obj);
|
| - Handle<WeakCell> link_to_original = factory->NewWeakCell(original);
|
| - clone->set(kNextInstance, *link_to_original);
|
| - Handle<WeakCell> link_to_clone = factory->NewWeakCell(clone);
|
| - original->set(kPrevInstance, *link_to_clone);
|
| - JSObject::cast(weak_link_to_wasm_obj->value())->SetInternalField(0, *clone);
|
|
|
| // Clone each wasm code object.
|
| Handle<FixedArray> orig_wasm_functions =
|
| @@ -1556,7 +1363,6 @@
|
| clone_wasm_functions->GetValueChecked<Code>(isolate, startup_fct_index);
|
| PatchJSWrapper(isolate, startup_fct_clone, new_target);
|
| }
|
| - clone->set(kImportMap, *isolate->factory()->undefined_value());
|
| return clone;
|
| }
|
|
|
| @@ -1566,29 +1372,26 @@
|
| // * installs named properties on the object for exported functions
|
| // * compiles wasm code to machine code
|
| MaybeHandle<JSObject> WasmModule::Instantiate(
|
| - Isolate* isolate, Handle<FixedArray> compiled_module_template,
|
| + Isolate* isolate, Handle<FixedArray> compiled_module,
|
| Handle<JSReceiver> ffi, Handle<JSArrayBuffer> memory) {
|
| HistogramTimerScope wasm_instantiate_module_time_scope(
|
| isolate->counters()->wasm_instantiate_module_time());
|
| ErrorThrower thrower(isolate, "WasmModule::Instantiate()");
|
| Factory* factory = isolate->factory();
|
|
|
| - Handle<FixedArray> compiled_module =
|
| - CloneModuleForInstance(isolate, compiled_module_template);
|
| -
|
| - bool template_is_owned =
|
| - GetOwningInstance(*compiled_module_template) != nullptr;
|
| -
|
| - MaybeHandle<JSObject> template_owner;
|
| - if (template_is_owned) {
|
| - Handle<WeakCell> weak_owner =
|
| - compiled_module_template->GetValueChecked<WeakCell>(isolate,
|
| - kOwningInstance);
|
| - template_owner = handle(JSObject::cast(weak_owner->value()));
|
| - }
|
| + compiled_module = CloneModuleForInstance(isolate, compiled_module);
|
| +
|
| // These fields are compulsory.
|
| Handle<FixedArray> code_table =
|
| compiled_module->GetValueChecked<FixedArray>(isolate, kFunctions);
|
| +
|
| + std::vector<Handle<Code>> functions(
|
| + static_cast<size_t>(code_table->length()));
|
| + for (int i = 0; i < code_table->length(); ++i) {
|
| + functions[static_cast<size_t>(i)] =
|
| + code_table->GetValueChecked<Code>(isolate, i);
|
| + }
|
| + LinkModuleFunctions(isolate, functions);
|
|
|
| RecordStats(isolate, code_table);
|
|
|
| @@ -1600,61 +1403,35 @@
|
| Handle<JSObject> js_object = factory->NewJSObjectFromMap(map, TENURED);
|
| js_object->SetInternalField(kWasmModuleCodeTable, *code_table);
|
|
|
| - // Remember the old imports, for the case when we are at the first instance -
|
| - // they will be replaced with the instance's actual imports in SetupImports.
|
| - MaybeHandle<FixedArray> old_imports =
|
| - compiled_module_template->GetValue<FixedArray>(isolate, kImportMap);
|
| if (!(SetupInstanceHeap(isolate, compiled_module, js_object, memory,
|
| &thrower) &&
|
| - SetupGlobals(isolate, template_owner, compiled_module, js_object,
|
| - &thrower) &&
|
| + SetupGlobals(isolate, compiled_module, js_object, &thrower) &&
|
| SetupImports(isolate, compiled_module, js_object, &thrower, ffi) &&
|
| SetupExportsObject(compiled_module, isolate, js_object, &thrower))) {
|
| return nothing;
|
| }
|
|
|
| - FixupFunctionsAndImports(
|
| - compiled_module_template->GetValueChecked<FixedArray>(isolate,
|
| - kFunctions),
|
| - code_table, old_imports,
|
| - compiled_module->GetValue<FixedArray>(isolate, kImportMap));
|
| -
|
| SetDebugSupport(factory, compiled_module, js_object);
|
| SetRuntimeSupport(isolate, js_object);
|
|
|
| FlushAssemblyCache(isolate, code_table);
|
|
|
| - {
|
| - std::vector<Handle<Code>> functions(
|
| - static_cast<size_t>(code_table->length()));
|
| - for (int i = 0; i < code_table->length(); ++i) {
|
| - functions[static_cast<size_t>(i)] =
|
| - code_table->GetValueChecked<Code>(isolate, i);
|
| - }
|
| -
|
| - MaybeHandle<FixedArray> maybe_indirect_tables =
|
| - compiled_module->GetValue<FixedArray>(isolate,
|
| - kTableOfIndirectFunctionTables);
|
| - Handle<FixedArray> indirect_tables_template;
|
| - if (maybe_indirect_tables.ToHandle(&indirect_tables_template)) {
|
| - Handle<FixedArray> to_replace =
|
| - template_owner.is_null()
|
| - ? indirect_tables_template
|
| - : handle(FixedArray::cast(
|
| - template_owner.ToHandleChecked()->GetInternalField(
|
| - kWasmModuleFunctionTable)));
|
| - Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable(
|
| - isolate, code_table, indirect_tables_template, to_replace);
|
| - for (int i = 0; i < indirect_tables->length(); ++i) {
|
| - Handle<FixedArray> metadata =
|
| - indirect_tables->GetValueChecked<FixedArray>(isolate, i);
|
| - uint32_t size = Smi::cast(metadata->get(kSize))->value();
|
| - Handle<FixedArray> table =
|
| - metadata->GetValueChecked<FixedArray>(isolate, kTable);
|
| - wasm::PopulateFunctionTable(table, size, &functions);
|
| - }
|
| - js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables);
|
| - }
|
| + MaybeHandle<FixedArray> maybe_indirect_tables =
|
| + compiled_module->GetValue<FixedArray>(isolate,
|
| + kTableOfIndirectFunctionTables);
|
| + Handle<FixedArray> indirect_tables_template;
|
| + if (maybe_indirect_tables.ToHandle(&indirect_tables_template)) {
|
| + Handle<FixedArray> indirect_tables = SetupIndirectFunctionTable(
|
| + isolate, code_table, indirect_tables_template);
|
| + for (int i = 0; i < indirect_tables->length(); ++i) {
|
| + Handle<FixedArray> metadata =
|
| + indirect_tables->GetValueChecked<FixedArray>(isolate, i);
|
| + uint32_t size = Smi::cast(metadata->get(kSize))->value();
|
| + Handle<FixedArray> table =
|
| + metadata->GetValueChecked<FixedArray>(isolate, kTable);
|
| + wasm::PopulateFunctionTable(table, size, &functions);
|
| + }
|
| + js_object->SetInternalField(kWasmModuleFunctionTable, *indirect_tables);
|
| }
|
|
|
| // Run the start function if one was specified.
|
| @@ -1684,19 +1461,6 @@
|
| }
|
|
|
| DCHECK(wasm::IsWasmObject(*js_object));
|
| -
|
| - if (!compiled_module->GetValue<WeakCell>(isolate, kModuleObject).is_null()) {
|
| - js_object->SetInternalField(kWasmCompiledModule, *compiled_module);
|
| - Handle<WeakCell> link_to_owner = factory->NewWeakCell(js_object);
|
| - compiled_module->set(kOwningInstance, *link_to_owner);
|
| -
|
| - Handle<Object> global_handle =
|
| - isolate->global_handles()->Create(*js_object);
|
| - GlobalHandles::MakeWeak(global_handle.location(), global_handle.location(),
|
| - &InstanceFinalizer,
|
| - v8::WeakCallbackType::kFinalizer);
|
| - }
|
| -
|
| return js_object;
|
| }
|
|
|
| @@ -1884,8 +1648,6 @@
|
| Handle<Symbol> module_sym(isolate->native_context()->wasm_module_sym());
|
| Object::SetProperty(module_obj, module_sym, module_obj, STRICT).Check();
|
| }
|
| - Handle<WeakCell> link_to_module = isolate->factory()->NewWeakCell(module_obj);
|
| - compiled_module->set(kModuleObject, *link_to_module);
|
| return module_obj;
|
| }
|
|
|
| @@ -1911,25 +1673,6 @@
|
| origin);
|
| }
|
|
|
| -MaybeHandle<JSArrayBuffer> GetInstanceMemory(Isolate* isolate,
|
| - Handle<JSObject> instance) {
|
| - Object* mem = instance->GetInternalField(kWasmMemArrayBuffer);
|
| - DCHECK(IsWasmObject(*instance));
|
| - if (mem->IsUndefined(isolate)) return MaybeHandle<JSArrayBuffer>();
|
| - return Handle<JSArrayBuffer>(JSArrayBuffer::cast(mem));
|
| -}
|
| -
|
| -void SetInstanceMemory(Handle<JSObject> instance, JSArrayBuffer* buffer) {
|
| - DisallowHeapAllocation no_gc;
|
| - DCHECK(IsWasmObject(*instance));
|
| - instance->SetInternalField(kWasmMemArrayBuffer, buffer);
|
| - Object* module = instance->GetInternalField(kWasmCompiledModule);
|
| - if (module->IsFixedArray()) {
|
| - HeapNumber::cast(FixedArray::cast(module)->get(kMemSize))
|
| - ->set_value(buffer->byte_length()->Number());
|
| - }
|
| -}
|
| -
|
| namespace testing {
|
|
|
| int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
|
| @@ -2014,51 +1757,6 @@
|
| return -1;
|
| }
|
|
|
| -void ValidateInstancesChain(Isolate* isolate, Handle<JSObject> module_obj,
|
| - int instance_count) {
|
| - CHECK_GE(instance_count, 0);
|
| - DisallowHeapAllocation no_gc;
|
| - FixedArray* compiled_module =
|
| - FixedArray::cast(module_obj->GetInternalField(0));
|
| - CHECK_EQ(JSObject::cast(GetModuleObject(compiled_module)->value()),
|
| - *module_obj);
|
| - Object* prev = nullptr;
|
| - int found_instances = GetOwningInstance(compiled_module) == nullptr ? 0 : 1;
|
| - FixedArray* current_instance = compiled_module;
|
| - while (GetNextInstance(current_instance) != nullptr) {
|
| - CHECK((prev == nullptr && GetPrevInstance(current_instance) == nullptr) ||
|
| - GetPrevInstance(current_instance)->value() == prev);
|
| - CHECK_EQ(GetModuleObject(current_instance)->value(), *module_obj);
|
| - CHECK(IsWasmObject(GetOwningInstance(current_instance)->value()));
|
| - prev = current_instance;
|
| - current_instance =
|
| - FixedArray::cast(GetNextInstance(current_instance)->value());
|
| - ++found_instances;
|
| - CHECK_LE(found_instances, instance_count);
|
| - }
|
| - CHECK_EQ(found_instances, instance_count);
|
| -}
|
| -
|
| -void ValidateModuleState(Isolate* isolate, Handle<JSObject> module_obj) {
|
| - DisallowHeapAllocation no_gc;
|
| - FixedArray* compiled_module =
|
| - FixedArray::cast(module_obj->GetInternalField(0));
|
| - CHECK_NOT_NULL(GetModuleObject(compiled_module));
|
| - CHECK_EQ(GetModuleObject(compiled_module)->value(), *module_obj);
|
| - CHECK_NULL(GetPrevInstance(compiled_module));
|
| - CHECK_NULL(GetNextInstance(compiled_module));
|
| - CHECK_NULL(GetOwningInstance(compiled_module));
|
| -}
|
| -
|
| -void ValidateOrphanedInstance(Isolate* isolate, Handle<JSObject> instance) {
|
| - DisallowHeapAllocation no_gc;
|
| - CHECK(IsWasmObject(*instance));
|
| - FixedArray* compiled_module =
|
| - FixedArray::cast(instance->GetInternalField(kWasmCompiledModule));
|
| - CHECK_NOT_NULL(GetModuleObject(compiled_module));
|
| - CHECK(GetModuleObject(compiled_module)->cleared());
|
| -}
|
| -
|
| } // namespace testing
|
| } // namespace wasm
|
| } // namespace internal
|
|
|