Index: src/wasm/wasm-module.cc |
diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc |
index df63dce97c85dcb3f68cfcd7199419b70ea5a845..54508f43aa49ee3358ee251cb8da11ae92f5b4f7 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,22 +641,12 @@ 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; |
//------------------------------------------------------------------------- |
- // Compile wrappers to imported functions. |
- //------------------------------------------------------------------------- |
- if (!CompileWrappersToImportedFunctions(isolate, this, ffi, &instance, |
- &thrower, factory, &module_env, |
- code_stats)) { |
- return MaybeHandle<JSObject>(); |
- } |
- //------------------------------------------------------------------------- |
// Compile all functions in the module. |
//------------------------------------------------------------------------- |
{ |
@@ -778,7 +674,22 @@ MaybeHandle<JSObject> WasmModule::Instantiate( |
} |
// Patch all direct call sites. |
- linker.Link(instance.function_table, this->function_table); |
+ compiler::Link(isolate, instance.function_code, instance.function_code, |
+ RelocInfo::kWasmDirectCallMask); |
+ //------------------------------------------------------------------------- |
+ // Compile wrappers to imported functions. |
+ //------------------------------------------------------------------------- |
+ if (!CompileWrappersToImportedFunctions(isolate, this, ffi, &instance, |
+ &thrower, factory, &module_env, |
+ code_stats)) { |
+ return MaybeHandle<JSObject>(); |
+ } |
+ |
+ compiler::Link(isolate, instance.function_code, instance.import_code, |
+ RelocInfo::kWasmImportCallMask); |
+ |
+ instance.PopulateExportTable(instance.function_code, function_table); |
+ |
instance.js_object->SetInternalField(kWasmModuleFunctionTable, |
Smi::FromInt(0)); |
@@ -865,25 +776,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]; |
-} |
- |
-Handle<Code> ModuleEnv::GetImportCode(uint32_t index) { |
- DCHECK(IsValidImport(index)); |
- return instance ? instance->import_code[index] : Handle<Code>::null(); |
-} |
- |
-compiler::CallDescriptor* ModuleEnv::GetCallDescriptor(Zone* zone, |
- uint32_t index) { |
- DCHECK(IsValidFunction(index)); |
- // Always make a direct call to whatever is in the table at that location. |
- // A wrapper will be generated for FFI calls. |
- const WasmFunction* function = &module->functions[index]; |
- return GetWasmCallDescriptor(zone, function->sig); |
+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]])); |
+ } |
+ } |
} |
int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start, |
@@ -931,11 +833,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 +848,14 @@ 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.function_code, |
+ RelocInfo::kWasmDirectCallMask); |
+ 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; |