Commit fac5898d authored by Thibaud Michaud's avatar Thibaud Michaud Committed by Commit Bot

Revert "reland [wasm] Compile JS to WASM wrappers asynchronously"

This reverts commit 117ddc8f.

Reason for revert: The isolate is needed for accessing builtins, and can die during async compilation.

Original change's description:
> reland [wasm] Compile JS to WASM wrappers asynchronously
> 
> The context was not set during streaming compilation.
> The initial upload is the original CL and patch set 1 is the fix.
> 
> Original CL:
> 
> > [wasm] Compile JS to WASM wrappers asynchronously
> >
> > R=mstarzinger@chromium.org, ahaas@chromium.org
> >
> > Bug: v8:9231
> > Change-Id: I9e18073bbe25bf8c9c5f9ace102316e6209d0459
> > Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1669699
> > Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
> > Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
> > Reviewed-by: Andreas Haas <ahaas@chromium.org>
> > Cr-Commit-Position: refs/heads/master@{#62672}
> 
> R=​mstarzinger@chromium.org, ahaas@chromium.org
> 
> Cq-Include-Trybots: luci.v8.try:v8_linux_blink_rel
> Bug: v8:9231
> Change-Id: I61fc11a6de54cc6e93f3600487a89fa5d2350f0e
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1701850
> Reviewed-by: Andreas Haas <ahaas@chromium.org>
> Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
> Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
> Auto-Submit: Thibaud Michaud <thibaudm@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#62721}

TBR=mstarzinger@chromium.org,ahaas@chromium.org,thibaudm@chromium.org

Change-Id: Ie258317f04a944e8e08993dbffb524f722cceddc
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: v8:9231
Cq-Include-Trybots: luci.v8.try:v8_linux_blink_rel
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1704094Reviewed-by: 's avatarThibaud Michaud <thibaudm@chromium.org>
Commit-Queue: Thibaud Michaud <thibaudm@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62741}
parent 55f7b1bb
...@@ -173,12 +173,12 @@ class PipelineData { ...@@ -173,12 +173,12 @@ class PipelineData {
// For CodeStubAssembler and machine graph testing entry point. // For CodeStubAssembler and machine graph testing entry point.
PipelineData(ZoneStats* zone_stats, OptimizedCompilationInfo* info, PipelineData(ZoneStats* zone_stats, OptimizedCompilationInfo* info,
Isolate* isolate, AccountingAllocator* allocator, Graph* graph, Isolate* isolate, Graph* graph, Schedule* schedule,
Schedule* schedule, SourcePositionTable* source_positions, SourcePositionTable* source_positions,
NodeOriginTable* node_origins, JumpOptimizationInfo* jump_opt, NodeOriginTable* node_origins, JumpOptimizationInfo* jump_opt,
const AssemblerOptions& assembler_options) const AssemblerOptions& assembler_options)
: isolate_(isolate), : isolate_(isolate),
allocator_(allocator), allocator_(isolate->allocator()),
info_(info), info_(info),
debug_name_(info_->GetDebugName()), debug_name_(info_->GetDebugName()),
zone_stats_(zone_stats), zone_stats_(zone_stats),
...@@ -1056,19 +1056,16 @@ class WasmHeapStubCompilationJob final : public OptimizedCompilationJob { ...@@ -1056,19 +1056,16 @@ class WasmHeapStubCompilationJob final : public OptimizedCompilationJob {
// we pass it to the CompilationJob constructor, but it is not // we pass it to the CompilationJob constructor, but it is not
// dereferenced there. // dereferenced there.
: OptimizedCompilationJob(isolate->stack_guard()->real_climit(), &info_, : OptimizedCompilationJob(isolate->stack_guard()->real_climit(), &info_,
"TurboFan", State::kReadyToExecute), "TurboFan"),
debug_name_(std::move(debug_name)), debug_name_(std::move(debug_name)),
info_(CStrVector(debug_name_.get()), graph->zone(), kind), info_(CStrVector(debug_name_.get()), graph->zone(), kind),
call_descriptor_(call_descriptor), call_descriptor_(call_descriptor),
zone_stats_(isolate->wasm_engine()->allocator()), zone_stats_(isolate->allocator()),
zone_(std::move(zone)), zone_(std::move(zone)),
graph_(graph), graph_(graph),
data_(&zone_stats_, &info_, isolate, data_(&zone_stats_, &info_, isolate, graph_, nullptr, source_positions,
isolate->wasm_engine()->allocator(), graph_, nullptr, new (zone_.get()) NodeOriginTable(graph_), nullptr, options),
source_positions, new (zone_.get()) NodeOriginTable(graph_), pipeline_(&data_) {}
nullptr, options),
pipeline_(&data_),
wasm_engine_(isolate->wasm_engine()) {}
~WasmHeapStubCompilationJob() = default; ~WasmHeapStubCompilationJob() = default;
...@@ -1086,7 +1083,6 @@ class WasmHeapStubCompilationJob final : public OptimizedCompilationJob { ...@@ -1086,7 +1083,6 @@ class WasmHeapStubCompilationJob final : public OptimizedCompilationJob {
Graph* graph_; Graph* graph_;
PipelineData data_; PipelineData data_;
PipelineImpl pipeline_; PipelineImpl pipeline_;
wasm::WasmEngine* wasm_engine_;
DISALLOW_COPY_AND_ASSIGN(WasmHeapStubCompilationJob); DISALLOW_COPY_AND_ASSIGN(WasmHeapStubCompilationJob);
}; };
...@@ -1107,14 +1103,10 @@ Pipeline::NewWasmHeapStubCompilationJob(Isolate* isolate, ...@@ -1107,14 +1103,10 @@ Pipeline::NewWasmHeapStubCompilationJob(Isolate* isolate,
CompilationJob::Status WasmHeapStubCompilationJob::PrepareJobImpl( CompilationJob::Status WasmHeapStubCompilationJob::PrepareJobImpl(
Isolate* isolate) { Isolate* isolate) {
return CompilationJob::SUCCEEDED;
}
CompilationJob::Status WasmHeapStubCompilationJob::ExecuteJobImpl() {
std::unique_ptr<PipelineStatistics> pipeline_statistics; std::unique_ptr<PipelineStatistics> pipeline_statistics;
if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) { if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
pipeline_statistics.reset(new PipelineStatistics( pipeline_statistics.reset(new PipelineStatistics(
&info_, wasm_engine_->GetOrCreateTurboStatistics(), &zone_stats_)); &info_, isolate->GetTurboStatistics(), &zone_stats_));
pipeline_statistics->BeginPhaseKind("V8.WasmStubCodegen"); pipeline_statistics->BeginPhaseKind("V8.WasmStubCodegen");
} }
if (info_.trace_turbo_json_enabled() || info_.trace_turbo_graph_enabled()) { if (info_.trace_turbo_json_enabled() || info_.trace_turbo_graph_enabled()) {
...@@ -1136,6 +1128,10 @@ CompilationJob::Status WasmHeapStubCompilationJob::ExecuteJobImpl() { ...@@ -1136,6 +1128,10 @@ CompilationJob::Status WasmHeapStubCompilationJob::ExecuteJobImpl() {
<< "\", \"source\":\"\",\n\"phases\":["; << "\", \"source\":\"\",\n\"phases\":[";
} }
pipeline_.RunPrintAndVerify("V8.WasmMachineCode", true); pipeline_.RunPrintAndVerify("V8.WasmMachineCode", true);
return CompilationJob::SUCCEEDED;
}
CompilationJob::Status WasmHeapStubCompilationJob::ExecuteJobImpl() {
pipeline_.ComputeScheduledGraph(); pipeline_.ComputeScheduledGraph();
if (pipeline_.SelectInstructionsAndAssemble(call_descriptor_)) { if (pipeline_.SelectInstructionsAndAssemble(call_descriptor_)) {
return CompilationJob::SUCCEEDED; return CompilationJob::SUCCEEDED;
...@@ -2337,8 +2333,8 @@ MaybeHandle<Code> Pipeline::GenerateCodeForCodeStub( ...@@ -2337,8 +2333,8 @@ MaybeHandle<Code> Pipeline::GenerateCodeForCodeStub(
JumpOptimizationInfo jump_opt; JumpOptimizationInfo jump_opt;
bool should_optimize_jumps = bool should_optimize_jumps =
isolate->serializer_enabled() && FLAG_turbo_rewrite_far_jumps; isolate->serializer_enabled() && FLAG_turbo_rewrite_far_jumps;
PipelineData data(&zone_stats, &info, isolate, isolate->allocator(), graph, PipelineData data(&zone_stats, &info, isolate, graph, nullptr,
nullptr, source_positions, &node_origins, source_positions, &node_origins,
should_optimize_jumps ? &jump_opt : nullptr, options); should_optimize_jumps ? &jump_opt : nullptr, options);
data.set_verify_graph(FLAG_verify_csa); data.set_verify_graph(FLAG_verify_csa);
std::unique_ptr<PipelineStatistics> pipeline_statistics; std::unique_ptr<PipelineStatistics> pipeline_statistics;
...@@ -2383,10 +2379,10 @@ MaybeHandle<Code> Pipeline::GenerateCodeForCodeStub( ...@@ -2383,10 +2379,10 @@ MaybeHandle<Code> Pipeline::GenerateCodeForCodeStub(
// First run code generation on a copy of the pipeline, in order to be able to // First run code generation on a copy of the pipeline, in order to be able to
// repeat it for jump optimization. The first run has to happen on a temporary // repeat it for jump optimization. The first run has to happen on a temporary
// pipeline to avoid deletion of zones on the main pipeline. // pipeline to avoid deletion of zones on the main pipeline.
PipelineData second_data(&zone_stats, &info, isolate, isolate->allocator(), PipelineData second_data(&zone_stats, &info, isolate, data.graph(),
data.graph(), data.schedule(), data.schedule(), data.source_positions(),
data.source_positions(), data.node_origins(), data.node_origins(), data.jump_optimization_info(),
data.jump_optimization_info(), options); options);
second_data.set_verify_graph(FLAG_verify_csa); second_data.set_verify_graph(FLAG_verify_csa);
PipelineImpl second_pipeline(&second_data); PipelineImpl second_pipeline(&second_data);
second_pipeline.SelectInstructionsAndAssemble(call_descriptor); second_pipeline.SelectInstructionsAndAssemble(call_descriptor);
...@@ -2532,8 +2528,8 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting( ...@@ -2532,8 +2528,8 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
// Construct a pipeline for scheduling and code generation. // Construct a pipeline for scheduling and code generation.
ZoneStats zone_stats(isolate->allocator()); ZoneStats zone_stats(isolate->allocator());
NodeOriginTable* node_positions = new (info->zone()) NodeOriginTable(graph); NodeOriginTable* node_positions = new (info->zone()) NodeOriginTable(graph);
PipelineData data(&zone_stats, info, isolate, isolate->allocator(), graph, PipelineData data(&zone_stats, info, isolate, graph, schedule, nullptr,
schedule, nullptr, node_positions, nullptr, options); node_positions, nullptr, options);
std::unique_ptr<PipelineStatistics> pipeline_statistics; std::unique_ptr<PipelineStatistics> pipeline_statistics;
if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) { if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) {
pipeline_statistics.reset(new PipelineStatistics( pipeline_statistics.reset(new PipelineStatistics(
......
...@@ -5985,7 +5985,7 @@ std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob( ...@@ -5985,7 +5985,7 @@ std::unique_ptr<OptimizedCompilationJob> NewJSToWasmCompilationJob(
// Create the Graph. // Create the Graph.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::unique_ptr<Zone> zone = std::unique_ptr<Zone> zone =
base::make_unique<Zone>(isolate->wasm_engine()->allocator(), ZONE_NAME); base::make_unique<Zone>(isolate->allocator(), ZONE_NAME);
Graph* graph = new (zone.get()) Graph(zone.get()); Graph* graph = new (zone.get()) Graph(zone.get());
CommonOperatorBuilder common(zone.get()); CommonOperatorBuilder common(zone.get());
MachineOperatorBuilder machine( MachineOperatorBuilder machine(
...@@ -6448,7 +6448,8 @@ MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) { ...@@ -6448,7 +6448,8 @@ MaybeHandle<Code> CompileCWasmEntry(Isolate* isolate, wasm::FunctionSig* sig) {
isolate, incoming, std::move(zone), graph, Code::C_WASM_ENTRY, isolate, incoming, std::move(zone), graph, Code::C_WASM_ENTRY,
std::move(debug_name), AssemblerOptions::Default(isolate))); std::move(debug_name), AssemblerOptions::Default(isolate)));
if (job->ExecuteJob() == CompilationJob::FAILED || if (job->PrepareJob(isolate) == CompilationJob::FAILED ||
job->ExecuteJob() == CompilationJob::FAILED ||
job->FinalizeJob(isolate) == CompilationJob::FAILED) { job->FinalizeJob(isolate) == CompilationJob::FAILED) {
return {}; return {};
} }
......
...@@ -265,12 +265,15 @@ void WasmCompilationUnit::CompileWasmFunction(Isolate* isolate, ...@@ -265,12 +265,15 @@ void WasmCompilationUnit::CompileWasmFunction(Isolate* isolate,
JSToWasmWrapperCompilationUnit::JSToWasmWrapperCompilationUnit(Isolate* isolate, JSToWasmWrapperCompilationUnit::JSToWasmWrapperCompilationUnit(Isolate* isolate,
FunctionSig* sig, FunctionSig* sig,
bool is_import) bool is_import)
: is_import_(is_import), : job_(compiler::NewJSToWasmCompilationJob(isolate, sig, is_import)) {}
sig_(sig),
job_(compiler::NewJSToWasmCompilationJob(isolate, sig, is_import)) {}
JSToWasmWrapperCompilationUnit::~JSToWasmWrapperCompilationUnit() = default; JSToWasmWrapperCompilationUnit::~JSToWasmWrapperCompilationUnit() = default;
void JSToWasmWrapperCompilationUnit::Prepare(Isolate* isolate) {
CompilationJob::Status status = job_->PrepareJob(isolate);
CHECK_EQ(status, CompilationJob::SUCCEEDED);
}
void JSToWasmWrapperCompilationUnit::Execute() { void JSToWasmWrapperCompilationUnit::Execute() {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "CompileJSToWasmWrapper"); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "CompileJSToWasmWrapper");
DCHECK_EQ(job_->state(), CompilationJob::State::kReadyToExecute); DCHECK_EQ(job_->state(), CompilationJob::State::kReadyToExecute);
...@@ -294,6 +297,7 @@ Handle<Code> JSToWasmWrapperCompilationUnit::CompileJSToWasmWrapper( ...@@ -294,6 +297,7 @@ Handle<Code> JSToWasmWrapperCompilationUnit::CompileJSToWasmWrapper(
Isolate* isolate, FunctionSig* sig, bool is_import) { Isolate* isolate, FunctionSig* sig, bool is_import) {
// Run the compilation unit synchronously. // Run the compilation unit synchronously.
JSToWasmWrapperCompilationUnit unit(isolate, sig, is_import); JSToWasmWrapperCompilationUnit unit(isolate, sig, is_import);
unit.Prepare(isolate);
unit.Execute(); unit.Execute();
return unit.Finalize(isolate); return unit.Finalize(isolate);
} }
......
...@@ -112,19 +112,15 @@ class V8_EXPORT_PRIVATE JSToWasmWrapperCompilationUnit final { ...@@ -112,19 +112,15 @@ class V8_EXPORT_PRIVATE JSToWasmWrapperCompilationUnit final {
bool is_import); bool is_import);
~JSToWasmWrapperCompilationUnit(); ~JSToWasmWrapperCompilationUnit();
void Prepare(Isolate* isolate);
void Execute(); void Execute();
Handle<Code> Finalize(Isolate* isolate); Handle<Code> Finalize(Isolate* isolate);
bool is_import() const { return is_import_; }
FunctionSig* sig() const { return sig_; }
// Run a compilation unit synchronously. // Run a compilation unit synchronously.
static Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, FunctionSig* sig, static Handle<Code> CompileJSToWasmWrapper(Isolate* isolate, FunctionSig* sig,
bool is_import); bool is_import);
private: private:
bool is_import_;
FunctionSig* sig_;
std::unique_ptr<OptimizedCompilationJob> job_; std::unique_ptr<OptimizedCompilationJob> job_;
}; };
......
...@@ -381,7 +381,7 @@ class CompilationStateImpl { ...@@ -381,7 +381,7 @@ class CompilationStateImpl {
// Initialize compilation progress. Set compilation tiers to expect for // Initialize compilation progress. Set compilation tiers to expect for
// baseline and top tier compilation. Must be set before {AddCompilationUnits} // baseline and top tier compilation. Must be set before {AddCompilationUnits}
// is invoked which triggers background compilation. // is invoked which triggers background compilation.
void InitializeCompilationProgress(bool lazy_module, int num_wrappers); void InitializeCompilationProgress(bool lazy_module, int num_import_wrappers);
// Add the callback function to be called on compilation events. Needs to be // Add the callback function to be called on compilation events. Needs to be
// set before {AddCompilationUnits} is run to ensure that it receives all // set before {AddCompilationUnits} is run to ensure that it receives all
...@@ -389,24 +389,13 @@ class CompilationStateImpl { ...@@ -389,24 +389,13 @@ class CompilationStateImpl {
void AddCallback(CompilationState::callback_t); void AddCallback(CompilationState::callback_t);
// Inserts new functions to compile and kicks off compilation. // Inserts new functions to compile and kicks off compilation.
void AddCompilationUnits( void AddCompilationUnits(Vector<WasmCompilationUnit> baseline_units,
Vector<WasmCompilationUnit> baseline_units, Vector<WasmCompilationUnit> top_tier_units);
Vector<WasmCompilationUnit> top_tier_units,
Vector<std::shared_ptr<JSToWasmWrapperCompilationUnit>>
js_to_wasm_wrapper_units);
void AddTopTierCompilationUnit(WasmCompilationUnit); void AddTopTierCompilationUnit(WasmCompilationUnit);
base::Optional<WasmCompilationUnit> GetNextCompilationUnit( base::Optional<WasmCompilationUnit> GetNextCompilationUnit(
int task_id, CompileBaselineOnly baseline_only); int task_id, CompileBaselineOnly baseline_only);
std::shared_ptr<JSToWasmWrapperCompilationUnit>
GetNextJSToWasmWrapperCompilationUnit();
void FinalizeJSToWasmWrappers(Isolate* isolate, const WasmModule* module,
Handle<FixedArray> export_wrappers);
void OnFinishedUnits(Vector<WasmCode*>); void OnFinishedUnits(Vector<WasmCode*>);
void OnFinishedJSToWasmWrapperUnits(int num);
void TriggerCallbacks(bool completes_baseline_compilation,
bool completes_top_tier_compilation);
void OnBackgroundTaskStopped(int task_id, const WasmFeatures& detected); void OnBackgroundTaskStopped(int task_id, const WasmFeatures& detected);
void UpdateDetectedFeatures(const WasmFeatures& detected); void UpdateDetectedFeatures(const WasmFeatures& detected);
...@@ -494,13 +483,6 @@ class CompilationStateImpl { ...@@ -494,13 +483,6 @@ class CompilationStateImpl {
// tasks a fair chance to utilize the worker threads on a regular basis. // tasks a fair chance to utilize the worker threads on a regular basis.
std::atomic<double> next_compilation_deadline_{0}; std::atomic<double> next_compilation_deadline_{0};
// Index of the next wrapper to compile in {js_to_wasm_wrapper_units_}.
std::atomic<int> js_to_wasm_wrapper_id_{0};
// Wrapper compilation units are stored in shared_ptrs so that they are kept
// alive by the tasks even if the NativeModule dies.
std::vector<std::shared_ptr<JSToWasmWrapperCompilationUnit>>
js_to_wasm_wrapper_units_;
// This mutex protects all information of this {CompilationStateImpl} which is // This mutex protects all information of this {CompilationStateImpl} which is
// being accessed concurrently. // being accessed concurrently.
mutable base::Mutex mutex_; mutable base::Mutex mutex_;
...@@ -729,11 +711,6 @@ class CompilationUnitBuilder { ...@@ -729,11 +711,6 @@ class CompilationUnitBuilder {
} }
} }
void AddJSToWasmWrapperUnit(
std::shared_ptr<JSToWasmWrapperCompilationUnit> unit) {
js_to_wasm_wrapper_units_.emplace_back(std::move(unit));
}
void AddTopTierUnit(int func_index) { void AddTopTierUnit(int func_index) {
ExecutionTierPair tiers = GetRequestedExecutionTiers( ExecutionTierPair tiers = GetRequestedExecutionTiers(
native_module_->module(), compilation_state()->compile_mode(), native_module_->module(), compilation_state()->compile_mode(),
...@@ -752,13 +729,9 @@ class CompilationUnitBuilder { ...@@ -752,13 +729,9 @@ class CompilationUnitBuilder {
} }
bool Commit() { bool Commit() {
if (baseline_units_.empty() && tiering_units_.empty() && if (baseline_units_.empty() && tiering_units_.empty()) return false;
js_to_wasm_wrapper_units_.empty()) { compilation_state()->AddCompilationUnits(VectorOf(baseline_units_),
return false; VectorOf(tiering_units_));
}
compilation_state()->AddCompilationUnits(
VectorOf(baseline_units_), VectorOf(tiering_units_),
VectorOf(js_to_wasm_wrapper_units_));
Clear(); Clear();
return true; return true;
} }
...@@ -766,7 +739,6 @@ class CompilationUnitBuilder { ...@@ -766,7 +739,6 @@ class CompilationUnitBuilder {
void Clear() { void Clear() {
baseline_units_.clear(); baseline_units_.clear();
tiering_units_.clear(); tiering_units_.clear();
js_to_wasm_wrapper_units_.clear();
} }
private: private:
...@@ -778,8 +750,6 @@ class CompilationUnitBuilder { ...@@ -778,8 +750,6 @@ class CompilationUnitBuilder {
const ExecutionTier default_tier_; const ExecutionTier default_tier_;
std::vector<WasmCompilationUnit> baseline_units_; std::vector<WasmCompilationUnit> baseline_units_;
std::vector<WasmCompilationUnit> tiering_units_; std::vector<WasmCompilationUnit> tiering_units_;
std::vector<std::shared_ptr<JSToWasmWrapperCompilationUnit>>
js_to_wasm_wrapper_units_;
}; };
void SetCompileError(ErrorThrower* thrower, ModuleWireBytes wire_bytes, void SetCompileError(ErrorThrower* thrower, ModuleWireBytes wire_bytes,
...@@ -939,33 +909,6 @@ void RecordStats(const Code code, Counters* counters) { ...@@ -939,33 +909,6 @@ void RecordStats(const Code code, Counters* counters) {
constexpr int kMainThreadTaskId = -1; constexpr int kMainThreadTaskId = -1;
bool ExecuteJSToWasmWrapperCompilationUnits(
const std::shared_ptr<BackgroundCompileToken>& token) {
std::shared_ptr<JSToWasmWrapperCompilationUnit> wrapper_unit = nullptr;
int num_processed_wrappers = 0;
do {
// TODO(thibaudm): Reschedule the compilation task if it takes too long, so
// that the background thread is not blocked.
{
BackgroundCompileScope compile_scope(token);
if (compile_scope.cancelled()) return false;
wrapper_unit = compile_scope.compilation_state()
->GetNextJSToWasmWrapperCompilationUnit();
}
if (wrapper_unit) {
wrapper_unit->Execute();
++num_processed_wrappers;
}
} while (wrapper_unit);
{
BackgroundCompileScope compile_scope(token);
if (compile_scope.cancelled()) return false;
compile_scope.compilation_state()->OnFinishedJSToWasmWrapperUnits(
num_processed_wrappers);
}
return true;
}
// Run by the main thread and background tasks to take part in compilation. // Run by the main thread and background tasks to take part in compilation.
// Returns whether any units were executed. // Returns whether any units were executed.
bool ExecuteCompilationUnits( bool ExecuteCompilationUnits(
...@@ -974,13 +917,6 @@ bool ExecuteCompilationUnits( ...@@ -974,13 +917,6 @@ bool ExecuteCompilationUnits(
TRACE_COMPILE("Compiling (task %d)...\n", task_id); TRACE_COMPILE("Compiling (task %d)...\n", task_id);
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "ExecuteCompilationUnits"); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "ExecuteCompilationUnits");
// Execute JS to WASM wrapper units first, so that they are ready to be
// finalized by the main thread when the kFinishedBaselineCompilation event is
// triggered.
if (!ExecuteJSToWasmWrapperCompilationUnits(token)) {
return false;
}
const bool is_foreground = task_id == kMainThreadTaskId; const bool is_foreground = task_id == kMainThreadTaskId;
// The main thread uses task id 0, which might collide with one of the // The main thread uses task id 0, which might collide with one of the
// background tasks. This is fine, as it will only cause some contention on // background tasks. This is fine, as it will only cause some contention on
...@@ -1113,26 +1049,6 @@ bool ExecuteCompilationUnits( ...@@ -1113,26 +1049,6 @@ bool ExecuteCompilationUnits(
return true; return true;
} }
using JSToWasmWrapperKey = std::pair<bool, FunctionSig>;
// Returns the number of units added.
int AddExportWrapperUnits(Isolate* isolate, NativeModule* native_module,
CompilationUnitBuilder* builder) {
std::unordered_set<JSToWasmWrapperKey, base::hash<JSToWasmWrapperKey>> keys;
for (auto exp : native_module->module()->export_table) {
if (exp.kind != kExternalFunction) continue;
auto& function = native_module->module()->functions[exp.index];
JSToWasmWrapperKey key(function.imported, *function.sig);
if (keys.insert(key).second) {
auto unit = std::make_shared<JSToWasmWrapperCompilationUnit>(
isolate, function.sig, function.imported);
builder->AddJSToWasmWrapperUnit(std::move(unit));
}
}
return static_cast<int>(keys.size());
}
// Returns the number of units added. // Returns the number of units added.
int AddImportWrapperUnits(NativeModule* native_module, int AddImportWrapperUnits(NativeModule* native_module,
CompilationUnitBuilder* builder) { CompilationUnitBuilder* builder) {
...@@ -1158,7 +1074,7 @@ int AddImportWrapperUnits(NativeModule* native_module, ...@@ -1158,7 +1074,7 @@ int AddImportWrapperUnits(NativeModule* native_module,
return static_cast<int>(keys.size()); return static_cast<int>(keys.size());
} }
void InitializeCompilationUnits(Isolate* isolate, NativeModule* native_module) { void InitializeCompilationUnits(NativeModule* native_module) {
CompilationStateImpl* compilation_state = CompilationStateImpl* compilation_state =
Impl(native_module->compilation_state()); Impl(native_module->compilation_state());
const bool lazy_module = IsLazyModule(native_module->module()); const bool lazy_module = IsLazyModule(native_module->module());
...@@ -1182,10 +1098,8 @@ void InitializeCompilationUnits(Isolate* isolate, NativeModule* native_module) { ...@@ -1182,10 +1098,8 @@ void InitializeCompilationUnits(Isolate* isolate, NativeModule* native_module) {
} }
} }
int num_import_wrappers = AddImportWrapperUnits(native_module, &builder); int num_import_wrappers = AddImportWrapperUnits(native_module, &builder);
int num_export_wrappers = compilation_state->InitializeCompilationProgress(lazy_module,
AddExportWrapperUnits(isolate, native_module, &builder); num_import_wrappers);
compilation_state->InitializeCompilationProgress(
lazy_module, num_import_wrappers + num_export_wrappers);
builder.Commit(); builder.Commit();
} }
...@@ -1287,7 +1201,7 @@ void CompileNativeModule(Isolate* isolate, ErrorThrower* thrower, ...@@ -1287,7 +1201,7 @@ void CompileNativeModule(Isolate* isolate, ErrorThrower* thrower,
} }
// Initialize the compilation units and kick off background compile tasks. // Initialize the compilation units and kick off background compile tasks.
InitializeCompilationUnits(isolate, native_module); InitializeCompilationUnits(native_module);
// If tiering is disabled, the main thread can execute any unit (all of them // If tiering is disabled, the main thread can execute any unit (all of them
// are part of initial compilation). Otherwise, just execute baseline units. // are part of initial compilation). Otherwise, just execute baseline units.
...@@ -1377,8 +1291,7 @@ std::shared_ptr<NativeModule> CompileToNativeModule( ...@@ -1377,8 +1291,7 @@ std::shared_ptr<NativeModule> CompileToNativeModule(
int num_wrappers = MaxNumExportWrappers(native_module->module()); int num_wrappers = MaxNumExportWrappers(native_module->module());
*export_wrappers_out = *export_wrappers_out =
isolate->factory()->NewFixedArray(num_wrappers, AllocationType::kOld); isolate->factory()->NewFixedArray(num_wrappers, AllocationType::kOld);
Impl(native_module->compilation_state()) CompileJsToWasmWrappers(isolate, native_module->module(),
->FinalizeJSToWasmWrappers(isolate, native_module->module(),
*export_wrappers_out); *export_wrappers_out);
// Log the code within the generated module for profiling. // Log the code within the generated module for profiling.
...@@ -1553,12 +1466,8 @@ void AsyncCompileJob::FinishCompile() { ...@@ -1553,12 +1466,8 @@ void AsyncCompileJob::FinishCompile() {
// TODO(bbudge) Allow deserialization without wrapper compilation, so we can // TODO(bbudge) Allow deserialization without wrapper compilation, so we can
// just compile wrappers here. // just compile wrappers here.
if (!is_after_deserialization) { if (!is_after_deserialization) {
CompilationStateImpl* compilation_state = // TODO(wasm): compiling wrappers should be made async.
Impl(native_module_->compilation_state()); CompileWrappers();
Handle<FixedArray> export_wrappers =
handle(module_object_->export_wrappers(), isolate_);
compilation_state->FinalizeJSToWasmWrappers(
isolate_, module_object_->module(), export_wrappers);
} }
FinishModule(); FinishModule();
...@@ -1879,7 +1788,7 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep { ...@@ -1879,7 +1788,7 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep {
// then DoAsync would do the same as NextStep already. // then DoAsync would do the same as NextStep already.
// Add compilation units and kick off compilation. // Add compilation units and kick off compilation.
InitializeCompilationUnits(job->isolate(), job->native_module_.get()); InitializeCompilationUnits(job->native_module_.get());
} }
} }
}; };
...@@ -1940,8 +1849,17 @@ class AsyncCompileJob::CompileFinished : public CompileStep { ...@@ -1940,8 +1849,17 @@ class AsyncCompileJob::CompileFinished : public CompileStep {
} }
}; };
void AsyncCompileJob::CompileWrappers() {
// TODO(wasm): Compile all wrappers here, including the start function wrapper
// and the wrappers for the function table elements.
TRACE_COMPILE("(5) Compile wrappers...\n");
// Compile JS->wasm wrappers for exported functions.
CompileJsToWasmWrappers(isolate_, module_object_->native_module()->module(),
handle(module_object_->export_wrappers(), isolate_));
}
void AsyncCompileJob::FinishModule() { void AsyncCompileJob::FinishModule() {
TRACE_COMPILE("(4) Finish module...\n"); TRACE_COMPILE("(6) Finish module...\n");
AsyncCompileSucceeded(module_object_); AsyncCompileSucceeded(module_object_);
isolate_->wasm_engine()->RemoveCompileJob(this); isolate_->wasm_engine()->RemoveCompileJob(this);
} }
...@@ -2051,12 +1969,8 @@ bool AsyncStreamingProcessor::ProcessCodeSectionHeader( ...@@ -2051,12 +1969,8 @@ bool AsyncStreamingProcessor::ProcessCodeSectionHeader(
int num_import_wrappers = int num_import_wrappers =
AddImportWrapperUnits(native_module, compilation_unit_builder_.get()); AddImportWrapperUnits(native_module, compilation_unit_builder_.get());
HandleScope scope(job_->isolate_); compilation_state->InitializeCompilationProgress(lazy_module,
SaveAndSwitchContext saved_context(job_->isolate_, *job_->native_context_); num_import_wrappers);
int num_export_wrappers = AddExportWrapperUnits(
job_->isolate_, native_module, compilation_unit_builder_.get());
compilation_state->InitializeCompilationProgress(
lazy_module, num_import_wrappers + num_export_wrappers);
return true; return true;
} }
...@@ -2227,8 +2141,8 @@ void CompilationStateImpl::AbortCompilation() { ...@@ -2227,8 +2141,8 @@ void CompilationStateImpl::AbortCompilation() {
callbacks_.clear(); callbacks_.clear();
} }
void CompilationStateImpl::InitializeCompilationProgress(bool lazy_module, void CompilationStateImpl::InitializeCompilationProgress(
int num_wrappers) { bool lazy_module, int num_import_wrappers) {
DCHECK(!failed()); DCHECK(!failed());
auto enabled_features = native_module_->enabled_features(); auto enabled_features = native_module_->enabled_features();
auto* module = native_module_->module(); auto* module = native_module_->module();
...@@ -2272,7 +2186,7 @@ void CompilationStateImpl::InitializeCompilationProgress(bool lazy_module, ...@@ -2272,7 +2186,7 @@ void CompilationStateImpl::InitializeCompilationProgress(bool lazy_module,
DCHECK_IMPLIES(lazy_module, outstanding_top_tier_functions_ == 0); DCHECK_IMPLIES(lazy_module, outstanding_top_tier_functions_ == 0);
DCHECK_LE(0, outstanding_baseline_units_); DCHECK_LE(0, outstanding_baseline_units_);
DCHECK_LE(outstanding_baseline_units_, outstanding_top_tier_functions_); DCHECK_LE(outstanding_baseline_units_, outstanding_top_tier_functions_);
outstanding_baseline_units_ += num_wrappers; outstanding_baseline_units_ += num_import_wrappers;
// Trigger callbacks if module needs no baseline or top tier compilation. This // Trigger callbacks if module needs no baseline or top tier compilation. This
// can be the case for an empty or fully lazy module. // can be the case for an empty or fully lazy module.
...@@ -2297,50 +2211,15 @@ void CompilationStateImpl::AddCallback(CompilationState::callback_t callback) { ...@@ -2297,50 +2211,15 @@ void CompilationStateImpl::AddCallback(CompilationState::callback_t callback) {
void CompilationStateImpl::AddCompilationUnits( void CompilationStateImpl::AddCompilationUnits(
Vector<WasmCompilationUnit> baseline_units, Vector<WasmCompilationUnit> baseline_units,
Vector<WasmCompilationUnit> top_tier_units, Vector<WasmCompilationUnit> top_tier_units) {
Vector<std::shared_ptr<JSToWasmWrapperCompilationUnit>>
js_to_wasm_wrapper_units) {
if (!baseline_units.empty() || !top_tier_units.empty()) {
compilation_unit_queues_.AddUnits(baseline_units, top_tier_units, compilation_unit_queues_.AddUnits(baseline_units, top_tier_units,
native_module_->module()); native_module_->module());
}
js_to_wasm_wrapper_units_.insert(js_to_wasm_wrapper_units_.end(),
js_to_wasm_wrapper_units.begin(),
js_to_wasm_wrapper_units.end());
RestartBackgroundTasks(); RestartBackgroundTasks();
} }
void CompilationStateImpl::AddTopTierCompilationUnit(WasmCompilationUnit unit) { void CompilationStateImpl::AddTopTierCompilationUnit(WasmCompilationUnit unit) {
AddCompilationUnits({}, {&unit, 1}, {}); AddCompilationUnits({}, {&unit, 1});
}
std::shared_ptr<JSToWasmWrapperCompilationUnit>
CompilationStateImpl::GetNextJSToWasmWrapperCompilationUnit() {
int wrapper_id =
js_to_wasm_wrapper_id_.fetch_add(1, std::memory_order_relaxed);
if (wrapper_id < static_cast<int>(js_to_wasm_wrapper_units_.size())) {
return js_to_wasm_wrapper_units_[wrapper_id];
}
return nullptr;
}
void CompilationStateImpl::FinalizeJSToWasmWrappers(
Isolate* isolate, const WasmModule* module,
Handle<FixedArray> export_wrappers) {
// TODO(6792): Wrappers below are allocated with {Factory::NewCode}. As an
// optimization we keep the code space unlocked to avoid repeated unlocking
// because many such wrapper are allocated in sequence below.
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"),
"FinalizeJSToWasmWrappers");
CodeSpaceMemoryModificationScope modification_scope(isolate->heap());
for (auto& unit : js_to_wasm_wrapper_units_) {
Handle<Code> code = unit->Finalize(isolate);
int wrapper_index =
GetExportWrapperIndex(module, unit->sig(), unit->is_import());
export_wrappers->set(wrapper_index, *code);
RecordStats(*code, isolate->counters());
}
} }
base::Optional<WasmCompilationUnit> base::Optional<WasmCompilationUnit>
...@@ -2430,21 +2309,7 @@ void CompilationStateImpl::OnFinishedUnits(Vector<WasmCode*> code_vector) { ...@@ -2430,21 +2309,7 @@ void CompilationStateImpl::OnFinishedUnits(Vector<WasmCode*> code_vector) {
DCHECK_LE(0, outstanding_baseline_units_); DCHECK_LE(0, outstanding_baseline_units_);
} }
TriggerCallbacks(completes_baseline_compilation, // Trigger callbacks.
completes_top_tier_compilation);
}
}
void CompilationStateImpl::OnFinishedJSToWasmWrapperUnits(int num) {
if (num == 0) return;
base::MutexGuard guard(&callbacks_mutex_);
outstanding_baseline_units_ -= num;
bool completes_baseline_compilation = outstanding_baseline_units_ == 0;
TriggerCallbacks(completes_baseline_compilation, false);
}
void CompilationStateImpl::TriggerCallbacks(
bool completes_baseline_compilation, bool completes_top_tier_compilation) {
if (completes_baseline_compilation) { if (completes_baseline_compilation) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "BaselineFinished"); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "BaselineFinished");
for (auto& callback : callbacks_) { for (auto& callback : callbacks_) {
...@@ -2462,6 +2327,7 @@ void CompilationStateImpl::TriggerCallbacks( ...@@ -2462,6 +2327,7 @@ void CompilationStateImpl::TriggerCallbacks(
// Clear the callbacks because no more events will be delivered. // Clear the callbacks because no more events will be delivered.
callbacks_.clear(); callbacks_.clear();
} }
}
} }
void CompilationStateImpl::OnBackgroundTaskStopped( void CompilationStateImpl::OnBackgroundTaskStopped(
...@@ -2509,11 +2375,6 @@ void CompilationStateImpl::RestartBackgroundTasks() { ...@@ -2509,11 +2375,6 @@ void CompilationStateImpl::RestartBackgroundTasks() {
if (failed()) return; if (failed()) return;
size_t max_num_restart = compilation_unit_queues_.GetTotalSize(); size_t max_num_restart = compilation_unit_queues_.GetTotalSize();
if (js_to_wasm_wrapper_id_ <
static_cast<int>(js_to_wasm_wrapper_units_.size())) {
max_num_restart +=
js_to_wasm_wrapper_units_.size() - js_to_wasm_wrapper_id_;
}
while (!available_task_ids_.empty() && max_num_restart-- > 0) { while (!available_task_ids_.empty() && max_num_restart-- > 0) {
int task_id = available_task_ids_.back(); int task_id = available_task_ids_.back();
...@@ -2553,6 +2414,7 @@ void CompilationStateImpl::SetError() { ...@@ -2553,6 +2414,7 @@ void CompilationStateImpl::SetError() {
} }
namespace { namespace {
using JSToWasmWrapperKey = std::pair<bool, FunctionSig>;
using JSToWasmWrapperQueue = using JSToWasmWrapperQueue =
WrapperQueue<JSToWasmWrapperKey, base::hash<JSToWasmWrapperKey>>; WrapperQueue<JSToWasmWrapperKey, base::hash<JSToWasmWrapperKey>>;
using JSToWasmWrapperUnitMap = using JSToWasmWrapperUnitMap =
...@@ -2595,6 +2457,7 @@ void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module, ...@@ -2595,6 +2457,7 @@ void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module,
if (queue.insert(key)) { if (queue.insert(key)) {
auto unit = base::make_unique<JSToWasmWrapperCompilationUnit>( auto unit = base::make_unique<JSToWasmWrapperCompilationUnit>(
isolate, function.sig, function.imported); isolate, function.sig, function.imported);
unit->Prepare(isolate);
compilation_units.emplace(key, std::move(unit)); compilation_units.emplace(key, std::move(unit));
} }
} }
......
...@@ -153,6 +153,8 @@ class AsyncCompileJob { ...@@ -153,6 +153,8 @@ class AsyncCompileJob {
void AsyncCompileSucceeded(Handle<WasmModuleObject> result); void AsyncCompileSucceeded(Handle<WasmModuleObject> result);
void CompileWrappers();
void FinishModule(); void FinishModule();
void StartForegroundTask(); void StartForegroundTask();
......
...@@ -154,18 +154,10 @@ class StreamTester { ...@@ -154,18 +154,10 @@ class StreamTester {
bool IsPromisePending() { return state_ == CompilationState::kPending; } bool IsPromisePending() { return state_ == CompilationState::kPending; }
void OnBytesReceived(const uint8_t* start, size_t length) { void OnBytesReceived(const uint8_t* start, size_t length) {
// Streaming compiler is expected to set its own context and handle scope.
i::SaveAndSwitchContext saved_context(CcTest::i_isolate(), i::Context{});
v8::SealHandleScope seal_handle_scope(CcTest::isolate());
stream_->OnBytesReceived(Vector<const uint8_t>(start, length)); stream_->OnBytesReceived(Vector<const uint8_t>(start, length));
} }
void FinishStream() { void FinishStream() { stream_->Finish(); }
// Streaming compiler is expected to set its own context and handle scope.
i::SaveAndSwitchContext saved_context(CcTest::i_isolate(), i::Context{});
v8::SealHandleScope seal_handle_scope(CcTest::isolate());
stream_->Finish();
}
void SetCompiledModuleBytes(const uint8_t* start, size_t length) { void SetCompiledModuleBytes(const uint8_t* start, size_t length) {
stream_->SetCompiledModuleBytes(Vector<const uint8_t>(start, length)); stream_->SetCompiledModuleBytes(Vector<const uint8_t>(start, length));
......
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