Index: src/compiler/wasm-compiler.cc |
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc |
index bb984253017de9addbbc353615b0fb36e91b669a..d95ec917e98e7d357725ce59a04af21ca06a3f9d 100644 |
--- a/src/compiler/wasm-compiler.cc |
+++ b/src/compiler/wasm-compiler.cc |
@@ -66,7 +66,8 @@ void MergeControlToEnd(JSGraph* jsgraph, Node* node) { |
} |
Node* BuildModifyThreadInWasmFlag(bool new_value, JSGraph* jsgraph, |
- Node** effect_ptr, Node* control) { |
+ Node* centry_stub_node, Node** effect_ptr, |
+ Node* control) { |
// TODO(eholk): generate code to modify the thread-local storage directly, |
// rather than calling the runtime. |
if (!trap_handler::UseTrapHandler()) { |
@@ -83,7 +84,7 @@ Node* BuildModifyThreadInWasmFlag(bool new_value, JSGraph* jsgraph, |
// CEntryStubConstant nodes have to be created and cached in the main |
// thread. At the moment this is only done for CEntryStubConstant(1). |
DCHECK_EQ(1, fun->result_size); |
- Node* inputs[] = {jsgraph->CEntryStubConstant(fun->result_size), |
+ Node* inputs[] = {centry_stub_node, |
jsgraph->ExternalConstant( |
ExternalReference(f, jsgraph->isolate())), // ref |
jsgraph->Int32Constant(fun->nargs), // arity |
@@ -100,15 +101,16 @@ Node* BuildModifyThreadInWasmFlag(bool new_value, JSGraph* jsgraph, |
// Only call this function for code which is not reused across instantiations, |
// as we do not patch the embedded context. |
Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, JSGraph* jsgraph, |
- Node* context, Node** parameters, |
- int parameter_count, Node** effect_ptr, |
- Node** control) { |
+ Node* centry_stub_node, Node* context, |
+ Node** parameters, int parameter_count, |
+ Node** effect_ptr, Node** control) { |
// Setting and clearing the thread-in-wasm flag should not be done as a normal |
// runtime call. |
DCHECK_NE(f, Runtime::kSetThreadInWasm); |
DCHECK_NE(f, Runtime::kClearThreadInWasm); |
// We're leaving Wasm code, so clear the flag. |
- *control = BuildModifyThreadInWasmFlag(false, jsgraph, effect_ptr, *control); |
+ *control = BuildModifyThreadInWasmFlag(false, jsgraph, centry_stub_node, |
+ effect_ptr, *control); |
const Runtime::Function* fun = Runtime::FunctionForId(f); |
CallDescriptor* desc = Linkage::GetRuntimeCallDescriptor( |
@@ -123,7 +125,7 @@ Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, JSGraph* jsgraph, |
DCHECK_GE(kMaxParams, parameter_count); |
Node* inputs[kMaxParams + 6]; |
int count = 0; |
- inputs[count++] = jsgraph->CEntryStubConstant(fun->result_size); |
+ inputs[count++] = centry_stub_node; |
for (int i = 0; i < parameter_count; i++) { |
inputs[count++] = parameters[i]; |
} |
@@ -139,27 +141,30 @@ Node* BuildCallToRuntimeWithContext(Runtime::FunctionId f, JSGraph* jsgraph, |
*effect_ptr = node; |
// Restore the thread-in-wasm flag, since we have returned to Wasm. |
- *control = BuildModifyThreadInWasmFlag(true, jsgraph, effect_ptr, *control); |
+ *control = BuildModifyThreadInWasmFlag(true, jsgraph, centry_stub_node, |
+ effect_ptr, *control); |
return node; |
} |
Node* BuildCallToRuntime(Runtime::FunctionId f, JSGraph* jsgraph, |
- Node** parameters, int parameter_count, |
- Node** effect_ptr, Node** control) { |
- return BuildCallToRuntimeWithContext(f, jsgraph, jsgraph->NoContextConstant(), |
- parameters, parameter_count, effect_ptr, |
- control); |
+ Node* centry_stub_node, Node** parameters, |
+ int parameter_count, Node** effect_ptr, |
+ Node** control) { |
+ return BuildCallToRuntimeWithContext(f, jsgraph, centry_stub_node, |
+ jsgraph->NoContextConstant(), parameters, |
+ parameter_count, effect_ptr, control); |
} |
} // namespace |
WasmGraphBuilder::WasmGraphBuilder( |
wasm::ModuleEnv* module_env, Zone* zone, JSGraph* jsgraph, |
- wasm::FunctionSig* sig, |
+ Handle<Code> centry_stub, wasm::FunctionSig* sig, |
compiler::SourcePositionTable* source_position_table) |
: zone_(zone), |
jsgraph_(jsgraph), |
+ centry_stub_node_(jsgraph_->HeapConstant(centry_stub)), |
module_(module_env), |
signature_tables_(zone), |
function_tables_(zone), |
@@ -1721,9 +1726,9 @@ Node* WasmGraphBuilder::GrowMemory(Node* input) { |
Node* parameters[] = {BuildChangeUint32ToSmi(input)}; |
Node* old_effect = *effect_; |
- Node* call = BuildCallToRuntime(Runtime::kWasmGrowMemory, jsgraph(), |
- parameters, arraysize(parameters), effect_, |
- &check_input_range.if_true); |
+ Node* call = BuildCallToRuntime( |
+ Runtime::kWasmGrowMemory, jsgraph(), centry_stub_node_, parameters, |
+ arraysize(parameters), effect_, &check_input_range.if_true); |
Node* result = BuildChangeSmiToInt32(call); |
@@ -1753,17 +1758,18 @@ Node* WasmGraphBuilder::Throw(Node* input) { |
graph()->NewNode(machine->Word32And(), input, Int32Constant(0xFFFFu))); |
Node* parameters[] = {lower, upper}; // thrown value |
- return BuildCallToRuntime(Runtime::kWasmThrow, jsgraph(), parameters, |
- arraysize(parameters), effect_, control_); |
+ return BuildCallToRuntime(Runtime::kWasmThrow, jsgraph(), centry_stub_node_, |
+ parameters, arraysize(parameters), effect_, |
+ control_); |
} |
Node* WasmGraphBuilder::Catch(Node* input, wasm::WasmCodePosition position) { |
CommonOperatorBuilder* common = jsgraph()->common(); |
Node* parameters[] = {input}; // caught value |
- Node* value = |
- BuildCallToRuntime(Runtime::kWasmGetCaughtExceptionValue, jsgraph(), |
- parameters, arraysize(parameters), effect_, control_); |
+ Node* value = BuildCallToRuntime(Runtime::kWasmGetCaughtExceptionValue, |
+ jsgraph(), centry_stub_node_, parameters, |
+ arraysize(parameters), effect_, control_); |
Node* is_smi; |
Node* is_heap; |
@@ -2613,14 +2619,16 @@ void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code, |
graph()->start()); |
// Set the ThreadInWasm flag before we do the actual call. |
- BuildModifyThreadInWasmFlag(true, jsgraph(), effect_, *control_); |
+ BuildModifyThreadInWasmFlag(true, jsgraph(), centry_stub_node_, effect_, |
+ *control_); |
if (!wasm::IsJSCompatibleSignature(sig_)) { |
// Throw a TypeError. Use the context of the calling javascript function |
// (passed as a parameter), such that the generated code is context |
// independent. |
BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, jsgraph(), |
- context, nullptr, 0, effect_, control_); |
+ centry_stub_node_, context, nullptr, 0, |
+ effect_, control_); |
// Add a dummy call to the wasm function so that the generated wrapper |
// contains a reference to the wrapped wasm function. Without this reference |
@@ -2660,7 +2668,8 @@ void WasmGraphBuilder::BuildJSToWasmWrapper(Handle<Code> wasm_code, |
*effect_ = call; |
// Clear the ThreadInWasmFlag |
- BuildModifyThreadInWasmFlag(false, jsgraph(), effect_, *control_); |
+ BuildModifyThreadInWasmFlag(false, jsgraph(), centry_stub_node_, effect_, |
+ *control_); |
Node* retval = call; |
Node* jsval = ToJS( |
@@ -2698,7 +2707,8 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, |
Node* context = |
jsgraph()->HeapConstant(jsgraph()->isolate()->native_context()); |
BuildCallToRuntimeWithContext(Runtime::kWasmThrowTypeError, jsgraph(), |
- context, nullptr, 0, effect_, control_); |
+ centry_stub_node_, context, nullptr, 0, |
+ effect_, control_); |
// We don't need to return a value here, as the runtime call will not return |
// anyway (the c entry stub will trigger stack unwinding). |
ReturnVoid(); |
@@ -2709,7 +2719,8 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, |
Node* call = nullptr; |
- BuildModifyThreadInWasmFlag(false, jsgraph(), effect_, *control_); |
+ BuildModifyThreadInWasmFlag(false, jsgraph(), centry_stub_node_, effect_, |
+ *control_); |
if (target->IsJSFunction()) { |
Handle<JSFunction> function = Handle<JSFunction>::cast(target); |
@@ -2774,7 +2785,8 @@ void WasmGraphBuilder::BuildWasmToJSWrapper(Handle<JSReceiver> target, |
*effect_ = call; |
SetSourcePosition(call, 0); |
- BuildModifyThreadInWasmFlag(true, jsgraph(), effect_, *control_); |
+ BuildModifyThreadInWasmFlag(true, jsgraph(), centry_stub_node_, effect_, |
+ *control_); |
// Convert the return value back. |
Node* val = sig->return_count() == 0 |
@@ -2859,8 +2871,8 @@ void WasmGraphBuilder::BuildWasmInterpreterEntry( |
jsgraph()->SmiConstant(function_index), // function index |
arg_buffer, // argument buffer |
}; |
- BuildCallToRuntime(Runtime::kWasmRunInterpreter, jsgraph(), parameters, |
- arraysize(parameters), effect_, control_); |
+ BuildCallToRuntime(Runtime::kWasmRunInterpreter, jsgraph(), centry_stub_node_, |
+ parameters, arraysize(parameters), effect_, control_); |
// Read back the return value. |
if (sig->return_count() == 0) { |
@@ -2907,10 +2919,9 @@ Node* WasmGraphBuilder::CurrentMemoryPages() { |
// CurrentMemoryPages will not be called from asm.js, hence we cannot be in |
// lazy-compilation mode, hence the instance will be set. |
DCHECK_EQ(wasm::kWasmOrigin, module_->module->get_origin()); |
- DCHECK_NOT_NULL(module_); |
- DCHECK_NOT_NULL(module_->instance); |
- Node* call = BuildCallToRuntime(Runtime::kWasmMemorySize, jsgraph(), nullptr, |
- 0, effect_, control_); |
+ Node* call = |
+ BuildCallToRuntime(Runtime::kWasmMemorySize, jsgraph(), centry_stub_node_, |
+ nullptr, 0, effect_, control_); |
Node* result = BuildChangeSmiToInt32(call); |
return result; |
} |
@@ -3686,7 +3697,8 @@ Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, |
Node* effect = nullptr; |
wasm::ModuleEnv module_env(module, nullptr); |
- WasmGraphBuilder builder(&module_env, &zone, &jsgraph, func->sig); |
+ WasmGraphBuilder builder(&module_env, &zone, &jsgraph, |
+ CEntryStub(isolate, 1).GetCode(), func->sig); |
builder.set_control_ptr(&control); |
builder.set_effect_ptr(&effect); |
builder.BuildJSToWasmWrapper(wasm_code, func->sig); |
@@ -3765,7 +3777,8 @@ Handle<Code> CompileWasmToJSWrapper(Isolate* isolate, Handle<JSReceiver> target, |
origin == wasm::kAsmJsOrigin ? new (&zone) SourcePositionTable(&graph) |
: nullptr; |
- WasmGraphBuilder builder(nullptr, &zone, &jsgraph, sig, |
+ WasmGraphBuilder builder(nullptr, &zone, &jsgraph, |
+ CEntryStub(isolate, 1).GetCode(), sig, |
source_position_table); |
builder.set_control_ptr(&control); |
builder.set_effect_ptr(&effect); |
@@ -3847,7 +3860,8 @@ Handle<Code> CompileWasmInterpreterEntry(Isolate* isolate, uint32_t func_index, |
Node* control = nullptr; |
Node* effect = nullptr; |
- WasmGraphBuilder builder(nullptr, &zone, &jsgraph, sig); |
+ WasmGraphBuilder builder(nullptr, &zone, &jsgraph, |
+ CEntryStub(isolate, 1).GetCode(), sig); |
builder.set_control_ptr(&control); |
builder.set_effect_ptr(&effect); |
builder.BuildWasmInterpreterEntry(func_index, sig, instance); |
@@ -3912,7 +3926,7 @@ SourcePositionTable* WasmCompilationUnit::BuildGraphForWasmFunction( |
SourcePositionTable* source_position_table = |
new (jsgraph_->zone()) SourcePositionTable(graph); |
WasmGraphBuilder builder(module_env_, jsgraph_->zone(), jsgraph_, |
- func_body_.sig, source_position_table); |
+ centry_stub_, func_body_.sig, source_position_table); |
graph_construction_result_ = |
wasm::BuildTFGraph(isolate_->allocator(), &builder, func_body_); |
@@ -3949,6 +3963,9 @@ Vector<const char> GetDebugName(Zone* zone, wasm::WasmName name, int index) { |
if (!name.is_empty()) { |
return name; |
} |
+#ifndef DEBUG |
+ return {}; |
+#endif |
constexpr int kBufferLength = 15; |
EmbeddedVector<char, kBufferLength> name_vector; |
@@ -3984,42 +4001,24 @@ WasmCompilationUnit::WasmCompilationUnit(Isolate* isolate, |
func_body_(body), |
func_name_(name), |
is_sync_(is_sync), |
- graph_zone_(new Zone(isolate->allocator(), ZONE_NAME)), |
- jsgraph_(new (graph_zone()) JSGraph( |
- isolate, new (graph_zone()) Graph(graph_zone()), |
- new (graph_zone()) CommonOperatorBuilder(graph_zone()), nullptr, |
- nullptr, |
- new (graph_zone()) MachineOperatorBuilder( |
- graph_zone(), MachineType::PointerRepresentation(), |
- InstructionSelector::SupportedMachineOperatorFlags(), |
- InstructionSelector::AlignmentRequirements()))), |
- compilation_zone_(isolate->allocator(), ZONE_NAME), |
- info_(GetDebugName(&compilation_zone_, name, index), isolate, |
- &compilation_zone_, Code::ComputeFlags(Code::WASM_FUNCTION)), |
- func_index_(index), |
- protected_instructions_(&compilation_zone_) {} |
- |
-void WasmCompilationUnit::InitializeHandles() { |
- // Create and cache this node in the main thread, which contains a handle to |
- // the code object of the c-entry stub. |
- jsgraph_->CEntryStubConstant(1); |
- DCHECK(!handles_initialized_); |
-#if DEBUG |
- handles_initialized_ = true; |
-#endif // DEBUG |
-} |
+ centry_stub_(CEntryStub(isolate, 1).GetCode()), |
+ func_index_(index) {} |
void WasmCompilationUnit::ExecuteCompilation() { |
- DCHECK(handles_initialized_); |
if (is_sync_) { |
// TODO(karlschimpf): Make this work when asynchronous. |
// https://bugs.chromium.org/p/v8/issues/detail?id=6361 |
HistogramTimerScope wasm_compile_function_time_scope( |
isolate_->counters()->wasm_compile_function_time()); |
ExecuteCompilationInternal(); |
- return; |
} |
ExecuteCompilationInternal(); |
+ // Record the memory cost this unit places on the system until |
+ // it is finalized. That may be "0" in error cases. |
+ if (job_) { |
+ size_t cost = job_->AllocatedMemory(); |
+ set_memory_cost(cost); |
+ } |
} |
void WasmCompilationUnit::ExecuteCompilationInternal() { |
@@ -4035,7 +4034,14 @@ void WasmCompilationUnit::ExecuteCompilationInternal() { |
double decode_ms = 0; |
size_t node_count = 0; |
- std::unique_ptr<Zone> graph_zone(graph_zone_.release()); |
+ Zone graph_zone(isolate_->allocator(), ZONE_NAME); |
+ jsgraph_ = new (&graph_zone) JSGraph( |
+ isolate_, new (&graph_zone) Graph(&graph_zone), |
+ new (&graph_zone) CommonOperatorBuilder(&graph_zone), nullptr, nullptr, |
+ new (&graph_zone) MachineOperatorBuilder( |
+ &graph_zone, MachineType::PointerRepresentation(), |
+ InstructionSelector::SupportedMachineOperatorFlags(), |
+ InstructionSelector::AlignmentRequirements())); |
SourcePositionTable* source_positions = BuildGraphForWasmFunction(&decode_ms); |
if (graph_construction_result_.failed()) { |
@@ -4049,16 +4055,24 @@ void WasmCompilationUnit::ExecuteCompilationInternal() { |
pipeline_timer.Start(); |
} |
+ compilation_zone_.reset(new Zone(isolate_->allocator(), ZONE_NAME)); |
+ |
// Run the compiler pipeline to generate machine code. |
CallDescriptor* descriptor = wasm::ModuleEnv::GetWasmCallDescriptor( |
- &compilation_zone_, func_body_.sig); |
+ compilation_zone_.get(), func_body_.sig); |
if (jsgraph_->machine()->Is32()) { |
- descriptor = |
- module_env_->GetI32WasmCallDescriptor(&compilation_zone_, descriptor); |
+ descriptor = module_env_->GetI32WasmCallDescriptor(compilation_zone_.get(), |
+ descriptor); |
} |
+ info_.reset(new CompilationInfo( |
+ GetDebugName(compilation_zone_.get(), func_name_, func_index_), isolate_, |
+ compilation_zone_.get(), Code::ComputeFlags(Code::WASM_FUNCTION))); |
+ ZoneVector<trap_handler::ProtectedInstructionData> protected_instructions( |
+ compilation_zone_.get()); |
+ |
job_.reset(Pipeline::NewWasmCompilationJob( |
- &info_, jsgraph_, descriptor, source_positions, &protected_instructions_, |
- !module_env_->module->is_wasm())); |
+ info_.get(), jsgraph_, descriptor, source_positions, |
+ &protected_instructions, !module_env_->module->is_wasm())); |
ok_ = job_->ExecuteJob() == CompilationJob::SUCCEEDED; |
// TODO(bradnelson): Improve histogram handling of size_t. |
if (is_sync_) |
@@ -4075,6 +4089,8 @@ void WasmCompilationUnit::ExecuteCompilationInternal() { |
static_cast<unsigned>(func_body_.end - func_body_.start), decode_ms, |
node_count, pipeline_ms); |
} |
+ // The graph zone is about to get out of scope. Avoid invalid references. |
+ jsgraph_ = nullptr; |
} |
Handle<Code> WasmCompilationUnit::FinishCompilation( |
@@ -4102,7 +4118,7 @@ Handle<Code> WasmCompilationUnit::FinishCompilation( |
if (job_->FinalizeJob() != CompilationJob::SUCCEEDED) { |
return Handle<Code>::null(); |
} |
- Handle<Code> code = info_.code(); |
+ Handle<Code> code = info_->code(); |
DCHECK(!code.is_null()); |
if (isolate_->logger()->is_logging_code_events() || |
@@ -4127,7 +4143,6 @@ Handle<Code> WasmCompilationUnit::CompileWasmFunction( |
wasm::ErrorThrower* thrower, Isolate* isolate, |
wasm::ModuleBytesEnv* module_env, const wasm::WasmFunction* function) { |
WasmCompilationUnit unit(isolate, module_env, function); |
- unit.InitializeHandles(); |
unit.ExecuteCompilation(); |
return unit.FinishCompilation(thrower); |
} |