Commit b29bfffd authored by Mircea Trofin's avatar Mircea Trofin Committed by Commit Bot

[wasm] Initialize parallel jobs with less memory.

Avoid constructing zones and large zone objects when initializing
WasmCompilationUnit. The main reason we did that is so we can cache
the CEntryStub node, which requires a code object, obtainable only
on the main thread. We need that value, however, on background threads,
which is also where we need the aforementioned large objects. We only
need that for the WasmCompilationUnits being currently compiled, which
is a number proportional to the number of background threads provided
by the embedder. Specifically, one zone is needed only for the duration
of the background compilation, while the second zone needs to survive 
past that, so the compilation results may be committed to the GC heap
as Code objects.

The problem with these large objects is that the first allocation
in a Zone is at minimum 8KB. We used to allocate 2 zones. For
modules with 200K functions, that means 3.2GB of memory pre-allocated
before any of it is actually needed.

This change attaches a Handle to the CEntryStub on the WasmCompilationUnits,
and delays zone creation to when needed. The change also adds a way to 
cache CEntryStubs in a JSGraph from a given Code handle - limited to the
scenario needed by wasm (and removable once we get wasm off the GC heap,
which subsumes removing this dependency on CEntryStubs)

An additional constraint for this change is that we want it to be easily 
back-mergeable to address chromium:723899.

For the wasm payload in question, collecting the max memory used by d8
using /usr/bin/time --format='(%Xtext+%Ddata %Mmax)', we get the 
following numbers (in KB):

- unchanged: 3307480
- patch 1: 1807140 (45% reduction)
- patch 3: 1230320 (62% reduction from first)
- patch 5/6: 519368 (84% reduction from first)

Bug: chomium:732010, chromium:723899
Change-Id: I45b96792daf8a9c8dc47d45fb52da75945a41401
Reviewed-on: https://chromium-review.googlesource.com/530193
Commit-Queue: Mircea Trofin <mtrofin@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45880}
parent 57f0ca07
This diff is collapsed.
...@@ -53,7 +53,6 @@ class WasmCompilationUnit final { ...@@ -53,7 +53,6 @@ class WasmCompilationUnit final {
wasm::FunctionBody body, wasm::WasmName name, int index, wasm::FunctionBody body, wasm::WasmName name, int index,
bool is_sync = true); bool is_sync = true);
Zone* graph_zone() { return graph_zone_.get(); }
int func_index() const { return func_index_; } int func_index() const { return func_index_; }
void InitializeHandles(); void InitializeHandles();
...@@ -73,21 +72,19 @@ class WasmCompilationUnit final { ...@@ -73,21 +72,19 @@ class WasmCompilationUnit final {
wasm::FunctionBody func_body_; wasm::FunctionBody func_body_;
wasm::WasmName func_name_; wasm::WasmName func_name_;
bool is_sync_; bool is_sync_;
// The graph zone is deallocated at the end of ExecuteCompilation. // The graph zone is deallocated at the end of ExecuteCompilation by virtue of
std::unique_ptr<Zone> graph_zone_; // it being zone allocated.
JSGraph* jsgraph_; JSGraph* jsgraph_ = nullptr;
Zone compilation_zone_; // the compilation_zone_, info_, and job_ fields need to survive past
CompilationInfo info_; // ExecuteCompilation, onto FinishCompilation (which happens on the main
// thread).
std::unique_ptr<Zone> compilation_zone_;
std::unique_ptr<CompilationInfo> info_;
std::unique_ptr<CompilationJob> job_; std::unique_ptr<CompilationJob> job_;
Handle<Code> centry_stub_;
int func_index_; int func_index_;
wasm::Result<wasm::DecodeStruct*> graph_construction_result_; wasm::Result<wasm::DecodeStruct*> graph_construction_result_;
bool ok_ = true; bool ok_ = true;
#if DEBUG
bool handles_initialized_ = false;
#endif // DEBUG
ZoneVector<trap_handler::ProtectedInstructionData>
protected_instructions_; // Instructions that are protected by the signal
// handler.
void ExecuteCompilationInternal(); void ExecuteCompilationInternal();
...@@ -119,7 +116,8 @@ typedef ZoneVector<Node*> NodeVector; ...@@ -119,7 +116,8 @@ typedef ZoneVector<Node*> NodeVector;
class WasmGraphBuilder { class WasmGraphBuilder {
public: public:
WasmGraphBuilder( WasmGraphBuilder(
wasm::ModuleEnv* module_env, Zone* z, JSGraph* g, wasm::FunctionSig* sig, wasm::ModuleEnv* module_env, Zone* z, JSGraph* g,
Handle<Code> centry_stub_, wasm::FunctionSig* sig,
compiler::SourcePositionTable* source_position_table = nullptr); compiler::SourcePositionTable* source_position_table = nullptr);
Node** Buffer(size_t count) { Node** Buffer(size_t count) {
...@@ -269,6 +267,7 @@ class WasmGraphBuilder { ...@@ -269,6 +267,7 @@ class WasmGraphBuilder {
Zone* zone_; Zone* zone_;
JSGraph* jsgraph_; JSGraph* jsgraph_;
Node* centry_stub_node_;
wasm::ModuleEnv* module_ = nullptr; wasm::ModuleEnv* module_ = nullptr;
Node* mem_buffer_ = nullptr; Node* mem_buffer_ = nullptr;
Node* mem_size_ = nullptr; Node* mem_size_ = nullptr;
......
...@@ -134,12 +134,6 @@ size_t ModuleCompiler::InitializeParallelCompilation( ...@@ -134,12 +134,6 @@ size_t ModuleCompiler::InitializeParallelCompilation(
return funcs_to_compile; return funcs_to_compile;
} }
void ModuleCompiler::InitializeHandles() {
for (auto& unit : compilation_units_) {
unit->InitializeHandles();
}
}
uint32_t* ModuleCompiler::StartCompilationTasks() { uint32_t* ModuleCompiler::StartCompilationTasks() {
num_background_tasks_ = num_background_tasks_ =
Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks), Min(static_cast<size_t>(FLAG_wasm_num_compilation_tasks),
...@@ -224,7 +218,6 @@ void ModuleCompiler::CompileInParallel(ModuleBytesEnv* module_env, ...@@ -224,7 +218,6 @@ void ModuleCompiler::CompileInParallel(ModuleBytesEnv* module_env,
// 1) The main thread allocates a compilation unit for each wasm function // 1) The main thread allocates a compilation unit for each wasm function
// and stores them in the vector {compilation_units}. // and stores them in the vector {compilation_units}.
InitializeParallelCompilation(module->functions, *module_env); InitializeParallelCompilation(module->functions, *module_env);
InitializeHandles();
// Objects for the synchronization with the background threads. // Objects for the synchronization with the background threads.
base::AtomicNumber<size_t> next_unit( base::AtomicNumber<size_t> next_unit(
...@@ -1869,7 +1862,6 @@ void AsyncCompileJob::ReopenHandlesInDeferredScope() { ...@@ -1869,7 +1862,6 @@ void AsyncCompileJob::ReopenHandlesInDeferredScope() {
signature_tables_ = handle(*signature_tables_, isolate_); signature_tables_ = handle(*signature_tables_, isolate_);
code_table_ = handle(*code_table_, isolate_); code_table_ = handle(*code_table_, isolate_);
temp_instance_->ReopenHandles(isolate_); temp_instance_->ReopenHandles(isolate_);
compiler_->InitializeHandles();
deferred_handles_.push_back(deferred.Detach()); deferred_handles_.push_back(deferred.Detach());
} }
......
...@@ -81,8 +81,6 @@ class ModuleCompiler { ...@@ -81,8 +81,6 @@ class ModuleCompiler {
size_t InitializeParallelCompilation( size_t InitializeParallelCompilation(
const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env); const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env);
void InitializeHandles();
uint32_t* StartCompilationTasks(); uint32_t* StartCompilationTasks();
void WaitForCompilationTasks(uint32_t* task_ids); void WaitForCompilationTasks(uint32_t* task_ids);
......
...@@ -996,7 +996,6 @@ void LazyCompilationOrchestrator::CompileFunction( ...@@ -996,7 +996,6 @@ void LazyCompilationOrchestrator::CompileFunction(
ErrorThrower thrower(isolate, "WasmLazyCompile"); ErrorThrower thrower(isolate, "WasmLazyCompile");
compiler::WasmCompilationUnit unit(isolate, &module_env, body, compiler::WasmCompilationUnit unit(isolate, &module_env, body,
CStrVector(func_name.c_str()), func_index); CStrVector(func_name.c_str()), func_index);
unit.InitializeHandles();
unit.ExecuteCompilation(); unit.ExecuteCompilation();
Handle<Code> code = unit.FinishCompilation(&thrower); Handle<Code> code = unit.FinishCompilation(&thrower);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <memory> #include <memory>
#include "src/base/utils/random-number-generator.h" #include "src/base/utils/random-number-generator.h"
#include "src/code-stubs.h"
#include "src/compiler/compiler-source-position-table.h" #include "src/compiler/compiler-source-position-table.h"
#include "src/compiler/graph-visualizer.h" #include "src/compiler/graph-visualizer.h"
#include "src/compiler/int64-lowering.h" #include "src/compiler/int64-lowering.h"
...@@ -356,8 +357,9 @@ inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module, ...@@ -356,8 +357,9 @@ inline void TestBuildingGraph(Zone* zone, JSGraph* jsgraph, ModuleEnv* module,
FunctionSig* sig, FunctionSig* sig,
SourcePositionTable* source_position_table, SourcePositionTable* source_position_table,
const byte* start, const byte* end) { const byte* start, const byte* end) {
compiler::WasmGraphBuilder builder(module, zone, jsgraph, sig, compiler::WasmGraphBuilder builder(
source_position_table); module, zone, jsgraph, CEntryStub(jsgraph->isolate(), 1).GetCode(), sig,
source_position_table);
DecodeResult result = DecodeResult result =
BuildTFGraph(zone->allocator(), &builder, sig, start, end); BuildTFGraph(zone->allocator(), &builder, sig, start, end);
if (result.failed()) { if (result.failed()) {
......
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