Commit eb04a25f authored by clemensh's avatar clemensh Committed by Commit bot

[wasm] Instantiate the interpreter on demand

If a breakpoint is set on a wasm function, compile an interpreter entry
stub for it, and replace all calls to the original function by calls to
this interpreter entry.
Also, instantiate a wasm interpreter object on demand and set the
breakpoint there.

R=titzer@chromium.org
BUG=v8:5822

Review-Url: https://codereview.chromium.org/2625093004
Cr-Commit-Position: refs/heads/master@{#42309}
parent 865b5e57
...@@ -2949,7 +2949,9 @@ void WasmGraphBuilder::BuildWasmInterpreterEntry( ...@@ -2949,7 +2949,9 @@ void WasmGraphBuilder::BuildWasmInterpreterEntry(
} }
// The return value is also passed via this buffer: // The return value is also passed via this buffer:
DCHECK_GE(1, sig->return_count()); DCHECK_GE(wasm::kV8MaxWasmFunctionReturns, sig->return_count());
// TODO(wasm): Handle multi-value returns.
DCHECK_EQ(1, wasm::kV8MaxWasmFunctionReturns);
int return_size_bytes = int return_size_bytes =
sig->return_count() == 0 ? 0 : 1 << ElementSizeLog2Of(sig->GetReturn(0)); sig->return_count() == 0 ? 0 : 1 << ElementSizeLog2Of(sig->GetReturn(0));
......
This diff is collapsed.
...@@ -1319,7 +1319,7 @@ class WasmInstanceBuilder { ...@@ -1319,7 +1319,7 @@ class WasmInstanceBuilder {
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Set up the exports object for the new instance. // Set up the exports object for the new instance.
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
ProcessExports(code_table, instance); ProcessExports(code_table, instance, compiled_module_);
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Add instance to Memory object // Add instance to Memory object
...@@ -1781,24 +1781,23 @@ class WasmInstanceBuilder { ...@@ -1781,24 +1781,23 @@ class WasmInstanceBuilder {
return mem_buffer; return mem_buffer;
} }
// Process the exports, creating wrappers for functions, tables, memories, bool NeedsWrappers() {
// and globals. if (module_->num_exported_functions > 0) return true;
void ProcessExports(Handle<FixedArray> code_table,
Handle<WasmInstanceObject> instance) {
bool needs_wrappers = module_->num_exported_functions > 0;
for (auto table_instance : table_instances_) { for (auto table_instance : table_instances_) {
if (!table_instance.js_wrappers.is_null()) { if (!table_instance.js_wrappers.is_null()) return true;
needs_wrappers = true;
break;
}
} }
for (auto table : module_->function_tables) { for (auto table : module_->function_tables) {
if (table.exported) { if (table.exported) return true;
needs_wrappers = true;
break;
}
} }
if (needs_wrappers) { return false;
}
// Process the exports, creating wrappers for functions, tables, memories,
// and globals.
void ProcessExports(Handle<FixedArray> code_table,
Handle<WasmInstanceObject> instance,
Handle<WasmCompiledModule> compiled_module) {
if (NeedsWrappers()) {
// Fill the table to cache the exported JSFunction wrappers. // Fill the table to cache the exported JSFunction wrappers.
js_wrappers_.insert(js_wrappers_.begin(), module_->functions.size(), js_wrappers_.insert(js_wrappers_.begin(), module_->functions.size(),
Handle<JSFunction>::null()); Handle<JSFunction>::null());
...@@ -1826,6 +1825,18 @@ class WasmInstanceBuilder { ...@@ -1826,6 +1825,18 @@ class WasmInstanceBuilder {
++export_index; ++export_index;
} }
} }
// Store weak references to all exported functions.
Handle<FixedArray> weak_exported_functions;
if (compiled_module->has_weak_exported_functions()) {
weak_exported_functions = compiled_module->weak_exported_functions();
} else {
weak_exported_functions =
isolate_->factory()->NewFixedArray(export_index);
compiled_module->set_weak_exported_functions(weak_exported_functions);
}
DCHECK_EQ(export_index, weak_exported_functions->length());
// Process each export in the export table (go in reverse so asm.js // Process each export in the export table (go in reverse so asm.js
// can skip duplicates). // can skip duplicates).
for (auto exp : base::Reversed(module_->export_table)) { for (auto exp : base::Reversed(module_->export_table)) {
...@@ -1858,6 +1869,10 @@ class WasmInstanceBuilder { ...@@ -1858,6 +1869,10 @@ class WasmInstanceBuilder {
js_wrappers_[exp.index] = js_function; js_wrappers_[exp.index] = js_function;
} }
desc.set_value(js_function); desc.set_value(js_function);
Handle<WeakCell> weak_export =
isolate_->factory()->NewWeakCell(js_function);
DCHECK_GT(weak_exported_functions->length(), export_index);
weak_exported_functions->set(export_index, *weak_export);
break; break;
} }
case kExternalTable: { case kExternalTable: {
......
...@@ -239,6 +239,7 @@ class WasmCompiledModule : public FixedArray { ...@@ -239,6 +239,7 @@ class WasmCompiledModule : public FixedArray {
MACRO(WASM_OBJECT, WasmSharedModuleData, shared) \ MACRO(WASM_OBJECT, WasmSharedModuleData, shared) \
MACRO(OBJECT, Context, native_context) \ MACRO(OBJECT, Context, native_context) \
MACRO(OBJECT, FixedArray, code_table) \ MACRO(OBJECT, FixedArray, code_table) \
MACRO(OBJECT, FixedArray, weak_exported_functions) \
MACRO(OBJECT, FixedArray, function_tables) \ MACRO(OBJECT, FixedArray, function_tables) \
MACRO(OBJECT, FixedArray, signature_tables) \ MACRO(OBJECT, FixedArray, signature_tables) \
MACRO(OBJECT, FixedArray, empty_function_tables) \ MACRO(OBJECT, FixedArray, empty_function_tables) \
...@@ -280,6 +281,7 @@ class WasmCompiledModule : public FixedArray { ...@@ -280,6 +281,7 @@ class WasmCompiledModule : public FixedArray {
ret->reset_weak_owning_instance(); ret->reset_weak_owning_instance();
ret->reset_weak_next_instance(); ret->reset_weak_next_instance();
ret->reset_weak_prev_instance(); ret->reset_weak_prev_instance();
ret->reset_weak_exported_functions();
return ret; return ret;
} }
...@@ -373,17 +375,22 @@ class WasmCompiledModule : public FixedArray { ...@@ -373,17 +375,22 @@ class WasmCompiledModule : public FixedArray {
DISALLOW_IMPLICIT_CONSTRUCTORS(WasmCompiledModule); DISALLOW_IMPLICIT_CONSTRUCTORS(WasmCompiledModule);
}; };
// TODO(clemensh): Extend this object for breakpoint support, or remove it.
// TODO(clemensh): Exclude this object from serialization.
class WasmDebugInfo : public FixedArray { class WasmDebugInfo : public FixedArray {
enum Fields { kInstance, kFieldCount };
public: public:
enum Fields {
kInstance,
kInterpreterHandle,
kInterpretedFunctions,
kFieldCount
};
static Handle<WasmDebugInfo> New(Handle<WasmInstanceObject>); static Handle<WasmDebugInfo> New(Handle<WasmInstanceObject>);
static bool IsDebugInfo(Object*); static bool IsDebugInfo(Object*);
static WasmDebugInfo* cast(Object*); static WasmDebugInfo* cast(Object*);
static void SetBreakpoint(Handle<WasmDebugInfo>, int func_index, int offset);
static void RunInterpreter(Handle<WasmDebugInfo>, int func_index, static void RunInterpreter(Handle<WasmDebugInfo>, int func_index,
uint8_t* arg_buffer); uint8_t* arg_buffer);
......
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