Commit fa4314da authored by Michael Achenbach's avatar Michael Achenbach Committed by Commit Bot

Revert "[wasm] Allow the initialization of a single compilation unit"

This reverts commit ca931562.

Reason for revert: tsan:
https://build.chromium.org/p/client.v8/builders/V8%20Linux64%20TSAN/builds/16007

Original change's description:
> [wasm] Allow the initialization of a single compilation unit
> 
> This CL adds a new function {InitializeCompilationUnit} to initialize
> a single compilation unit and not just all compilation units at once.
> This is necessary for streaming compilation eventually. This also
> required some refactoring on how the working queue for compilation units
> works. Previously the synchronization was done with an atomic counter,
> now it is done with a lock. Note that the code to finish compilation
> of a module still only works if the working queue gets only empty when
> all work is done. I plan to change this in a different CL.
> 
> Since the code would not be tested without streaming compilation, I added
> an experimental flag and a test to test the new code.
> 
> R=​clemensh@chromium.org, mtrofin@chromium.org
> 
> Change-Id: I839c04fd78d1ea8e1db202f2cbed41c4c2cf4f28
> Reviewed-on: https://chromium-review.googlesource.com/550096
> Commit-Queue: Andreas Haas <ahaas@chromium.org>
> Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
> Reviewed-by: Mircea Trofin <mtrofin@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#46348}

TBR=mtrofin@chromium.org,ahaas@chromium.org,clemensh@chromium.org

Change-Id: Ied6532f05463c0b78c8b8f5307d44640bcca8316
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/558224Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46350}
parent f341bb0f
...@@ -129,13 +129,15 @@ bool ModuleCompiler::FetchAndExecuteCompilationUnit( ...@@ -129,13 +129,15 @@ bool ModuleCompiler::FetchAndExecuteCompilationUnit(
DisallowHandleDereference no_deref; DisallowHandleDereference no_deref;
DisallowCodeDependencyChange no_dependency_change; DisallowCodeDependencyChange no_dependency_change;
std::unique_ptr<compiler::WasmCompilationUnit> unit; // - 1 because AtomicIncrement returns the value after the atomic increment.
{ // Bail out fast if there's no work to do.
base::LockGuard<base::Mutex> guard(&compilation_units_mutex_); size_t index = next_unit_.Increment(1) - 1;
if (compilation_units_.empty()) return false; if (index >= compilation_units_.size()) {
unit = std::move(compilation_units_.back()); return false;
compilation_units_.pop_back();
} }
std::unique_ptr<compiler::WasmCompilationUnit> unit =
std::move(compilation_units_.at(index));
unit->ExecuteCompilation(); unit->ExecuteCompilation();
{ {
base::LockGuard<base::Mutex> guard(&result_mutex_); base::LockGuard<base::Mutex> guard(&result_mutex_);
...@@ -149,23 +151,20 @@ bool ModuleCompiler::FetchAndExecuteCompilationUnit( ...@@ -149,23 +151,20 @@ bool ModuleCompiler::FetchAndExecuteCompilationUnit(
return true; return true;
} }
size_t ModuleCompiler::InitializeCompilationUnits( size_t ModuleCompiler::InitializeParallelCompilation(
const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env) { const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env) {
uint32_t start = module_env.module_env.module->num_imported_functions + uint32_t start = module_env.module_env.module->num_imported_functions +
FLAG_skip_compiling_wasm_funcs; FLAG_skip_compiling_wasm_funcs;
uint32_t num_funcs = static_cast<uint32_t>(functions.size()); uint32_t num_funcs = static_cast<uint32_t>(functions.size());
uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start; uint32_t funcs_to_compile = start > num_funcs ? 0 : num_funcs - start;
CompilationUnitBuilder builder(this); compilation_units_.reserve(funcs_to_compile);
for (uint32_t i = start; i < num_funcs; ++i) { for (uint32_t i = start; i < num_funcs; ++i) {
const WasmFunction* func = &functions[i]; const WasmFunction* func = &functions[i];
uint32_t buffer_offset = func->code.offset(); constexpr bool is_sync = true;
Vector<const uint8_t> bytes( compilation_units_.push_back(std::unique_ptr<compiler::WasmCompilationUnit>(
module_env.wire_bytes.start() + func->code.offset(), new compiler::WasmCompilationUnit(isolate_, &module_env, func,
func->code.end_offset() - func->code.offset()); centry_stub_, !is_sync)));
WasmName name = module_env.wire_bytes.GetName(func); }
builder.AddUnit(&module_env.module_env, func, buffer_offset, bytes, name);
}
builder.Commit();
return funcs_to_compile; return funcs_to_compile;
} }
...@@ -192,7 +191,7 @@ size_t ModuleCompiler::FinishCompilationUnits( ...@@ -192,7 +191,7 @@ size_t ModuleCompiler::FinishCompilationUnits(
results[func_index] = result; results[func_index] = result;
++finished; ++finished;
} }
if (!compilation_units_.empty()) RestartCompilationTasks(); RestartCompilationTasks();
return finished; return finished;
} }
...@@ -242,14 +241,16 @@ void ModuleCompiler::CompileInParallel(ModuleBytesEnv* module_env, ...@@ -242,14 +241,16 @@ 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}.
InitializeCompilationUnits(module->functions, *module_env); InitializeParallelCompilation(module->functions, *module_env);
executed_units_.EnableThrottling(); executed_units_.EnableThrottling();
// 2) The main thread spawns {CompilationTask} instances which run on // 2) The main thread spawns {CompilationTask} instances which run on
// the background threads. // the background threads.
RestartCompilationTasks(); RestartCompilationTasks();
while (!compilation_units_.empty()) { size_t finished_functions = 0;
while (finished_functions < compilation_units_.size()) {
// 3.a) The background threads and the main thread pick one compilation // 3.a) The background threads and the main thread pick one compilation
// unit at a time and execute the parallel phase of the compilation // unit at a time and execute the parallel phase of the compilation
// unit. After finishing the execution of the parallel phase, the // unit. After finishing the execution of the parallel phase, the
...@@ -262,14 +263,12 @@ void ModuleCompiler::CompileInParallel(ModuleBytesEnv* module_env, ...@@ -262,14 +263,12 @@ void ModuleCompiler::CompileInParallel(ModuleBytesEnv* module_env,
// dequeues it and finishes the compilation unit. Compilation units // dequeues it and finishes the compilation unit. Compilation units
// are finished concurrently to the background threads to save // are finished concurrently to the background threads to save
// memory. // memory.
FinishCompilationUnits(results, thrower); finished_functions += FinishCompilationUnits(results, thrower);
} }
// 4) After the parallel phase of all compilation units has started, the // 4) After the parallel phase of all compilation units has started, the
// main thread waits for all {CompilationTask} instances to finish - which // main thread waits for all {CompilationTask} instances to finish - which
// happens once they all realize there's no next work item to process. // happens once they all realize there's no next work item to process.
background_task_manager_.CancelAndWait(); background_task_manager_.CancelAndWait();
// Finish all compilation units which have been executed while we waited.
FinishCompilationUnits(results, thrower);
} }
void ModuleCompiler::CompileSequentially(ModuleBytesEnv* module_env, void ModuleCompiler::CompileSequentially(ModuleBytesEnv* module_env,
...@@ -2143,8 +2142,7 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep { ...@@ -2143,8 +2142,7 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep {
->NumberOfAvailableBackgroundThreads()))); ->NumberOfAvailableBackgroundThreads())));
job_->module_bytes_env_.reset(new ModuleBytesEnv( job_->module_bytes_env_.reset(new ModuleBytesEnv(
module, job_->temp_instance_.get(), job_->wire_bytes_)); module, job_->temp_instance_.get(), job_->wire_bytes_));
job_->outstanding_units_ = job_->compiler_->InitializeParallelCompilation(
job_->outstanding_units_ = job_->compiler_->InitializeCompilationUnits(
module->functions, *job_->module_bytes_env_); module->functions, *job_->module_bytes_env_);
job_->DoAsync<ExecuteAndFinishCompilationUnits>(num_background_tasks); job_->DoAsync<ExecuteAndFinishCompilationUnits>(num_background_tasks);
......
...@@ -39,44 +39,6 @@ class ModuleCompiler { ...@@ -39,44 +39,6 @@ class ModuleCompiler {
void RunInternal() override; void RunInternal() override;
}; };
// The CompilationUnitBuilder builds compilation units and stores them in an
// internal buffer. The buffer is moved into the working queue of the
// ModuleCompiler when {Commit} is called.
class CompilationUnitBuilder {
public:
explicit CompilationUnitBuilder(ModuleCompiler* compiler)
: compiler_(compiler) {}
~CompilationUnitBuilder() { DCHECK(units_.empty()); }
void AddUnit(ModuleEnv* module_env, const WasmFunction* function,
uint32_t buffer_offset, Vector<const uint8_t> bytes,
WasmName name) {
constexpr bool is_sync = true;
units_.emplace_back(new compiler::WasmCompilationUnit(
compiler_->isolate_, module_env,
wasm::FunctionBody{function->sig, buffer_offset, bytes.begin(),
bytes.end()},
name, function->func_index, compiler_->centry_stub_, is_sync));
}
void Commit() {
{
base::LockGuard<base::Mutex> guard(
&compiler_->compilation_units_mutex_);
compiler_->compilation_units_.insert(
compiler_->compilation_units_.end(),
std::make_move_iterator(units_.begin()),
std::make_move_iterator(units_.end()));
}
units_.clear();
}
private:
ModuleCompiler* compiler_;
std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> units_;
};
class CodeGenerationSchedule { class CodeGenerationSchedule {
public: public:
explicit CodeGenerationSchedule( explicit CodeGenerationSchedule(
...@@ -127,8 +89,8 @@ class ModuleCompiler { ...@@ -127,8 +89,8 @@ class ModuleCompiler {
return executed_units_.ShouldIncreaseWorkload(); return executed_units_.ShouldIncreaseWorkload();
} }
size_t InitializeCompilationUnits(const std::vector<WasmFunction>& functions, size_t InitializeParallelCompilation(
ModuleBytesEnv& module_env); const std::vector<WasmFunction>& functions, ModuleBytesEnv& module_env);
void ReopenHandlesInDeferredScope(); void ReopenHandlesInDeferredScope();
...@@ -172,9 +134,9 @@ class ModuleCompiler { ...@@ -172,9 +134,9 @@ class ModuleCompiler {
bool is_sync_; bool is_sync_;
std::vector<std::unique_ptr<compiler::WasmCompilationUnit>> std::vector<std::unique_ptr<compiler::WasmCompilationUnit>>
compilation_units_; compilation_units_;
base::Mutex compilation_units_mutex_;
CodeGenerationSchedule executed_units_; CodeGenerationSchedule executed_units_;
base::Mutex result_mutex_; base::Mutex result_mutex_;
base::AtomicNumber<size_t> next_unit_;
const size_t num_background_tasks_; const size_t num_background_tasks_;
// This flag should only be set while holding result_mutex_. // This flag should only be set while holding result_mutex_.
bool finisher_is_running_ = false; bool finisher_is_running_ = false;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// Flags: --wasm-async-compilation --expose-wasm --allow-natives-syntax // Flags: --expose-wasm --allow-natives-syntax
load("test/mjsunit/wasm/wasm-constants.js"); load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js"); load("test/mjsunit/wasm/wasm-module-builder.js");
......
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