Commit 81f42220 authored by mtrofin's avatar mtrofin Committed by Commit bot

[wasm] cloning compiled module before instantiation

To correctly support instantiating a compiled module multiple times, we clone the
compiled module each time we create an instance, since some of the data is specific
to the instance - e.g. export code, wasm functions, indirect table.

BUG=v8:5072

Review-Url: https://codereview.chromium.org/2134593002
Cr-Commit-Position: refs/heads/master@{#37692}
parent 117fda14
...@@ -3113,25 +3113,10 @@ static void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag, ...@@ -3113,25 +3113,10 @@ static void RecordFunctionCompilation(CodeEventListener::LogEventsAndTags tag,
*script_str, 0, 0)); *script_str, 0, 0));
} }
Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate, Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module,
wasm::ModuleEnv* module, Handle<Code> wasm_code, uint32_t index) {
Handle<String> name,
Handle<Code> wasm_code,
uint32_t index) {
const wasm::WasmFunction* func = &module->module->functions[index]; const wasm::WasmFunction* func = &module->module->functions[index];
//----------------------------------------------------------------------------
// Create the JSFunction object.
//----------------------------------------------------------------------------
Handle<SharedFunctionInfo> shared =
isolate->factory()->NewSharedFunctionInfo(name, wasm_code, false);
int params = static_cast<int>(func->sig->parameter_count());
shared->set_length(params);
shared->set_internal_formal_parameter_count(params);
Handle<JSFunction> function = isolate->factory()->NewFunction(
isolate->wasm_function_map(), name, MaybeHandle<Code>());
function->set_shared(*shared);
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Create the Graph // Create the Graph
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
...@@ -3153,59 +3138,53 @@ Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate, ...@@ -3153,59 +3138,53 @@ Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate,
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Run the compilation pipeline. // Run the compilation pipeline.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
{ if (FLAG_trace_turbo_graph) { // Simple textual RPO.
if (FLAG_trace_turbo_graph) { // Simple textual RPO. OFStream os(stdout);
OFStream os(stdout); os << "-- Graph after change lowering -- " << std::endl;
os << "-- Graph after change lowering -- " << std::endl; os << AsRPO(graph);
os << AsRPO(graph); }
}
// Schedule and compile to machine code. // Schedule and compile to machine code.
int params = static_cast<int>( int params =
module->GetFunctionSignature(index)->parameter_count()); static_cast<int>(module->GetFunctionSignature(index)->parameter_count());
CallDescriptor* incoming = Linkage::GetJSCallDescriptor( CallDescriptor* incoming = Linkage::GetJSCallDescriptor(
&zone, false, params + 1, CallDescriptor::kNoFlags); &zone, false, params + 1, CallDescriptor::kNoFlags);
Code::Flags flags = Code::ComputeFlags(Code::JS_TO_WASM_FUNCTION); Code::Flags flags = Code::ComputeFlags(Code::JS_TO_WASM_FUNCTION);
bool debugging = bool debugging =
#if DEBUG #if DEBUG
true; true;
#else #else
FLAG_print_opt_code || FLAG_trace_turbo || FLAG_trace_turbo_graph; FLAG_print_opt_code || FLAG_trace_turbo || FLAG_trace_turbo_graph;
#endif #endif
Vector<const char> func_name = ArrayVector("js-to-wasm"); Vector<const char> func_name = ArrayVector("js-to-wasm");
static unsigned id = 0; static unsigned id = 0;
Vector<char> buffer; Vector<char> buffer;
if (debugging) { if (debugging) {
buffer = Vector<char>::New(128); buffer = Vector<char>::New(128);
int chars = SNPrintF(buffer, "js-to-wasm#%d", id); int chars = SNPrintF(buffer, "js-to-wasm#%d", id);
func_name = Vector<const char>::cast(buffer.SubVector(0, chars)); func_name = Vector<const char>::cast(buffer.SubVector(0, chars));
} }
CompilationInfo info(func_name, isolate, &zone, flags); CompilationInfo info(func_name, isolate, &zone, flags);
Handle<Code> code = Handle<Code> code = Pipeline::GenerateCodeForTesting(&info, incoming, &graph);
Pipeline::GenerateCodeForTesting(&info, incoming, &graph);
#ifdef ENABLE_DISASSEMBLER #ifdef ENABLE_DISASSEMBLER
if (FLAG_print_opt_code && !code.is_null()) { if (FLAG_print_opt_code && !code.is_null()) {
OFStream os(stdout); OFStream os(stdout);
code->Disassemble(buffer.start(), os); code->Disassemble(buffer.start(), os);
} }
#endif #endif
if (debugging) { if (debugging) {
buffer.Dispose(); buffer.Dispose();
} }
if (isolate->logger()->is_logging_code_events() || if (isolate->logger()->is_logging_code_events() || isolate->is_profiling()) {
isolate->is_profiling()) { RecordFunctionCompilation(
RecordFunctionCompilation( CodeEventListener::FUNCTION_TAG, isolate, code, "js-to-wasm", index,
CodeEventListener::FUNCTION_TAG, isolate, code, "js-to-wasm", index, wasm::WasmName("export"),
wasm::WasmName("export"), module->module->GetName(func->name_offset, func->name_length));
module->module->GetName(func->name_offset, func->name_length));
}
// Set the JSFunction's machine code.
function->set_code(*code);
} }
return function; return code;
} }
Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<Code> CompileWasmToJSWrapper(Isolate* isolate,
......
...@@ -83,13 +83,9 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, ...@@ -83,13 +83,9 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate,
Handle<String> import_module, Handle<String> import_module,
MaybeHandle<String> import_function); MaybeHandle<String> import_function);
// Wraps a given wasm code object, producing a JSFunction that can be called // Wraps a given wasm code object, producing a code object.
// from JavaScript. Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, wasm::ModuleEnv* module,
Handle<JSFunction> CompileJSToWasmWrapper(Isolate* isolate, Handle<Code> wasm_code, uint32_t index);
wasm::ModuleEnv* module,
Handle<String> name,
Handle<Code> wasm_code,
uint32_t index);
// Abstracts details of building TurboFan graph nodes for WASM to separate // Abstracts details of building TurboFan graph nodes for WASM to separate
// the WASM decoder from the internal details of TurboFan. // the WASM decoder from the internal details of TurboFan.
......
...@@ -552,8 +552,6 @@ class Factory final { ...@@ -552,8 +552,6 @@ class Factory final {
Handle<Code> CopyCode(Handle<Code> code); Handle<Code> CopyCode(Handle<Code> code);
Handle<Code> CopyCode(Handle<Code> code, Vector<byte> reloc_info);
Handle<BytecodeArray> CopyBytecodeArray(Handle<BytecodeArray>); Handle<BytecodeArray> CopyBytecodeArray(Handle<BytecodeArray>);
// Interface for creating error objects. // Interface for creating error objects.
......
This diff is collapsed.
...@@ -165,6 +165,9 @@ struct WasmModule { ...@@ -165,6 +165,9 @@ struct WasmModule {
uint32_t max_mem_pages; // maximum size of the memory in 64k pages. uint32_t max_mem_pages; // maximum size of the memory in 64k pages.
bool mem_export; // true if the memory is exported. bool mem_export; // true if the memory is exported.
bool mem_external; // true if the memory is external. bool mem_external; // true if the memory is external.
// TODO(wasm): reconcile start function index being an int with
// the fact that we index on uint32_t, so we may technically not be
// able to represent some start_function_index -es.
int start_function_index; // start function, if any. int start_function_index; // start function, if any.
ModuleOrigin origin; // origin of the module ModuleOrigin origin; // origin of the module
...@@ -359,6 +362,12 @@ Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm); ...@@ -359,6 +362,12 @@ Handle<WasmDebugInfo> GetDebugInfo(Handle<JSObject> wasm);
// Return the number of functions in the given wasm object. // Return the number of functions in the given wasm object.
int GetNumberOfFunctions(JSObject* wasm); int GetNumberOfFunctions(JSObject* wasm);
// Create and export JSFunction
Handle<JSFunction> WrapExportCodeAsJSFunction(Isolate* isolate,
Handle<Code> export_code,
Handle<String> name, int arity,
Handle<JSObject> module_instance);
// Check whether the given object is a wasm object. // Check whether the given object is a wasm object.
// This checks the number and type of internal fields, so it's not 100 percent // This checks the number and type of internal fields, so it's not 100 percent
// secure. If it turns out that we need more complete checks, we could add a // secure. If it turns out that we need more complete checks, we could add a
......
...@@ -207,9 +207,12 @@ class TestingModule : public ModuleEnv { ...@@ -207,9 +207,12 @@ class TestingModule : public ModuleEnv {
Handle<JSObject> module_object = Handle<JSObject>(0, isolate_); Handle<JSObject> module_object = Handle<JSObject>(0, isolate_);
Handle<Code> code = instance->function_code[index]; Handle<Code> code = instance->function_code[index];
WasmJs::InstallWasmFunctionMap(isolate_, isolate_->native_context()); WasmJs::InstallWasmFunctionMap(isolate_, isolate_->native_context());
Handle<JSFunction> ret = Handle<Code> ret_code =
compiler::CompileJSToWasmWrapper(isolate_, this, name, code, index); compiler::CompileJSToWasmWrapper(isolate_, this, code, index);
ret->SetInternalField(0, *module_object); Handle<JSFunction> ret = WrapExportCodeAsJSFunction(
isolate_, ret_code, name,
static_cast<int>(this->module->functions[index].sig->parameter_count()),
module_object);
return ret; return ret;
} }
...@@ -238,6 +241,7 @@ class TestingModule : public ModuleEnv { ...@@ -238,6 +241,7 @@ class TestingModule : public ModuleEnv {
*instance->function_code[function_index]); *instance->function_code[function_index]);
} }
} }
WasmFunction* GetFunctionAt(int index) { return &module_.functions[index]; } WasmFunction* GetFunctionAt(int index) { return &module_.functions[index]; }
WasmInterpreter* interpreter() { return interpreter_; } WasmInterpreter* interpreter() { return interpreter_; }
......
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