| Index: src/wasm/wasm-module.cc
|
| diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc
|
| index df63dce97c85dcb3f68cfcd7199419b70ea5a845..a1fa430f2710c96e1e1ccb1495a6601fc4b91ce7 100644
|
| --- a/src/wasm/wasm-module.cc
|
| +++ b/src/wasm/wasm-module.cc
|
| @@ -22,8 +22,6 @@ namespace v8 {
|
| namespace internal {
|
| namespace wasm {
|
|
|
| -static const int kPlaceholderMarker = 1000000000;
|
| -
|
| static const char* wasmSections[] = {
|
| #define F(enumerator, order, string) string,
|
| FOR_EACH_WASM_SECTION_TYPE(F)
|
| @@ -111,98 +109,6 @@ std::ostream& operator<<(std::ostream& os, const WasmFunctionName& pair) {
|
| return os;
|
| }
|
|
|
| -// A helper class for compiling multiple wasm functions that offers
|
| -// placeholder code objects for calling functions that are not yet compiled.
|
| -class WasmLinker {
|
| - public:
|
| - WasmLinker(Isolate* isolate, std::vector<Handle<Code>>* functions)
|
| - : isolate_(isolate),
|
| - placeholder_code_(functions->size()),
|
| - function_code_(functions) {
|
| - for (uint32_t i = 0; i < placeholder_code_.size(); ++i) {
|
| - CreatePlaceholder(i);
|
| - }
|
| - }
|
| -
|
| - Handle<Code> GetPlaceholderCode(uint32_t index) const {
|
| - return placeholder_code_[index];
|
| - }
|
| -
|
| - void Finish(uint32_t index, Handle<Code> code) {
|
| - DCHECK(index < function_code().size());
|
| - function_code()[index] = code;
|
| - }
|
| -
|
| - void Link(Handle<FixedArray> function_table,
|
| - const std::vector<uint16_t>& functions) {
|
| - for (size_t i = 0; i < function_code().size(); i++) {
|
| - LinkFunction(function_code()[i]);
|
| - }
|
| - if (!function_table.is_null()) {
|
| - int table_size = static_cast<int>(functions.size());
|
| - DCHECK_EQ(function_table->length(), table_size * 2);
|
| - for (int i = 0; i < table_size; i++) {
|
| - function_table->set(i + table_size, *function_code()[functions[i]]);
|
| - }
|
| - }
|
| - }
|
| -
|
| - private:
|
| - std::vector<Handle<Code>>& function_code() { return *function_code_; }
|
| -
|
| - void CreatePlaceholder(uint32_t index) {
|
| - DCHECK(index < function_code().size());
|
| - DCHECK(function_code()[index].is_null());
|
| - // Create a placeholder code object and encode the corresponding index in
|
| - // the {constant_pool_offset} field of the code object.
|
| - // TODO(titzer): placeholder code objects are somewhat dangerous.
|
| - byte buffer[] = {0, 0, 0, 0, 0, 0, 0, 0}; // fake instructions.
|
| - CodeDesc desc = {buffer, 8, 8, 0, 0, nullptr};
|
| - Handle<Code> code = isolate_->factory()->NewCode(
|
| - desc, Code::KindField::encode(Code::WASM_FUNCTION),
|
| - Handle<Object>::null());
|
| - code->set_constant_pool_offset(static_cast<int>(index) +
|
| - kPlaceholderMarker);
|
| - placeholder_code_[index] = code;
|
| - function_code()[index] = code;
|
| - }
|
| -
|
| - Isolate* isolate_;
|
| - std::vector<Handle<Code>> placeholder_code_;
|
| - std::vector<Handle<Code>>* function_code_;
|
| -
|
| - void LinkFunction(Handle<Code> code) {
|
| - bool modified = false;
|
| - int mode_mask = RelocInfo::kCodeTargetMask;
|
| - AllowDeferredHandleDereference embedding_raw_address;
|
| - for (RelocIterator it(*code, mode_mask); !it.done(); it.next()) {
|
| - RelocInfo::Mode mode = it.rinfo()->rmode();
|
| - if (RelocInfo::IsCodeTarget(mode)) {
|
| - Code* target =
|
| - Code::GetCodeFromTargetAddress(it.rinfo()->target_address());
|
| - if (target->kind() == Code::WASM_FUNCTION &&
|
| - target->constant_pool_offset() >= kPlaceholderMarker) {
|
| - // Patch direct calls to placeholder code objects.
|
| - uint32_t index = target->constant_pool_offset() - kPlaceholderMarker;
|
| - CHECK(index < function_code().size());
|
| - Handle<Code> new_target = function_code()[index];
|
| - if (target != *new_target) {
|
| - CHECK_EQ(*placeholder_code_[index], target);
|
| - it.rinfo()->set_target_address(new_target->instruction_start(),
|
| - SKIP_WRITE_BARRIER,
|
| - SKIP_ICACHE_FLUSH);
|
| - modified = true;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - if (modified) {
|
| - Assembler::FlushICache(isolate_, code->instruction_start(),
|
| - code->instruction_size());
|
| - }
|
| - }
|
| -};
|
| -
|
| namespace {
|
| // Internal constants for the layout of the module object.
|
| const int kWasmModuleInternalFieldCount = 5;
|
| @@ -735,11 +641,9 @@ MaybeHandle<JSObject> WasmModule::Instantiate(
|
| isolate->counters()->wasm_compile_module_time());
|
|
|
| instance.function_table = BuildFunctionTable(isolate, this);
|
| - WasmLinker linker(isolate, &instance.function_code);
|
| ModuleEnv module_env;
|
| module_env.module = this;
|
| module_env.instance = &instance;
|
| - module_env.linker = &linker;
|
| module_env.origin = origin;
|
|
|
| //-------------------------------------------------------------------------
|
| @@ -778,7 +682,10 @@ MaybeHandle<JSObject> WasmModule::Instantiate(
|
| }
|
|
|
| // Patch all direct call sites.
|
| - linker.Link(instance.function_table, this->function_table);
|
| + compiler::Link(isolate, instance.function_code);
|
| +
|
| + instance.PopulateExportTable(instance.function_code, function_table);
|
| +
|
| instance.js_object->SetInternalField(kWasmModuleFunctionTable,
|
| Smi::FromInt(0));
|
|
|
| @@ -865,11 +772,16 @@ MaybeHandle<JSObject> WasmModule::Instantiate(
|
| return instance.js_object;
|
| }
|
|
|
| -Handle<Code> ModuleEnv::GetCodeOrPlaceholder(uint32_t index) const {
|
| - DCHECK(IsValidFunction(index));
|
| - if (linker != nullptr) return linker->GetPlaceholderCode(index);
|
| - DCHECK_NOT_NULL(instance);
|
| - return instance->function_code[index];
|
| +void WasmModuleInstance::PopulateExportTable(
|
| + const std::vector<Handle<Code>>& compiled_functions,
|
| + const std::vector<uint16_t>& functions) {
|
| + if (!function_table.is_null()) {
|
| + int table_size = static_cast<int>(functions.size());
|
| + DCHECK_EQ(function_table->length(), table_size * 2);
|
| + for (int i = 0; i < table_size; i++) {
|
| + function_table->set(i + table_size, *(compiled_functions[functions[i]]));
|
| + }
|
| + }
|
| }
|
|
|
| Handle<Code> ModuleEnv::GetImportCode(uint32_t index) {
|
| @@ -931,11 +843,9 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const WasmModule* module) {
|
| instance.function_table = BuildFunctionTable(isolate, module);
|
|
|
| // Create module environment.
|
| - WasmLinker linker(isolate, &instance.function_code);
|
| ModuleEnv module_env;
|
| module_env.module = module;
|
| module_env.instance = &instance;
|
| - module_env.linker = &linker;
|
| module_env.origin = module->origin;
|
|
|
| if (module->export_table.size() == 0) {
|
| @@ -948,11 +858,13 @@ int32_t CompileAndRunWasmModule(Isolate* isolate, const WasmModule* module) {
|
| // Compile the function and install it in the linker.
|
| Handle<Code> code = compiler::WasmCompilationUnit::CompileWasmFunction(
|
| &thrower, isolate, &module_env, &func);
|
| - if (!code.is_null()) linker.Finish(func.func_index, code);
|
| + if (!code.is_null()) instance.function_code[func.func_index] = code;
|
| if (thrower.error()) return -1;
|
| }
|
|
|
| - linker.Link(instance.function_table, instance.module->function_table);
|
| + compiler::Link(isolate, instance.function_code);
|
| + instance.PopulateExportTable(instance.function_code,
|
| + instance.module->function_table);
|
|
|
| // Wrap the main code so it can be called as a JS function.
|
| uint32_t main_index = module->export_table.back().func_index;
|
|
|