Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Unified Diff: src/compiler/wasm-compiler.cc

Issue 2957693002: Merged changes to avoid OOM for large wasm modules. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/compiler/zone-stats.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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);
}
« no previous file with comments | « src/compiler/wasm-compiler.h ('k') | src/compiler/zone-stats.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698