summaryrefslogtreecommitdiff
path: root/deps/v8/src/wasm/module-compiler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/wasm/module-compiler.cc')
-rw-r--r--deps/v8/src/wasm/module-compiler.cc341
1 files changed, 249 insertions, 92 deletions
diff --git a/deps/v8/src/wasm/module-compiler.cc b/deps/v8/src/wasm/module-compiler.cc
index 658f329775..c264bac96e 100644
--- a/deps/v8/src/wasm/module-compiler.cc
+++ b/deps/v8/src/wasm/module-compiler.cc
@@ -152,6 +152,9 @@ class CompilationUnitQueues {
for (int task_id = 0; task_id < max_tasks; ++task_id) {
queues_[task_id].next_steal_task_id = next_task_id(task_id);
}
+ for (auto& atomic_counter : num_units_) {
+ std::atomic_init(&atomic_counter, size_t{0});
+ }
}
base::Optional<WasmCompilationUnit> GetNextUnit(
@@ -254,15 +257,14 @@ class CompilationUnitQueues {
};
struct BigUnitsQueue {
- BigUnitsQueue() = default;
+ BigUnitsQueue() {
+ for (auto& atomic : has_units) std::atomic_init(&atomic, false);
+ }
base::Mutex mutex;
// Can be read concurrently to check whether any elements are in the queue.
- std::atomic_bool has_units[kNumTiers] = {
- ATOMIC_VAR_INIT(false),
- ATOMIC_VAR_INIT(false)
- };
+ std::atomic<bool> has_units[kNumTiers];
// Protected by {mutex}:
std::priority_queue<BigUnit> units[kNumTiers];
@@ -271,11 +273,8 @@ class CompilationUnitQueues {
std::vector<Queue> queues_;
BigUnitsQueue big_units_queue_;
- std::atomic_size_t num_units_[kNumTiers] = {
- ATOMIC_VAR_INIT(0),
- ATOMIC_VAR_INIT(0)
- };
- std::atomic_int next_queue_to_add{0};
+ std::atomic<size_t> num_units_[kNumTiers];
+ std::atomic<int> next_queue_to_add{0};
int next_task_id(int task_id) const {
int next = task_id + 1;
@@ -382,7 +381,7 @@ class CompilationStateImpl {
// Initialize compilation progress. Set compilation tiers to expect for
// baseline and top tier compilation. Must be set before {AddCompilationUnits}
// is invoked which triggers background compilation.
- void InitializeCompilationProgress(bool lazy_module, int num_import_wrappers);
+ void InitializeCompilationProgress(bool lazy_module, int num_wrappers);
// Add the callback function to be called on compilation events. Needs to be
// set before {AddCompilationUnits} is run to ensure that it receives all
@@ -390,13 +389,24 @@ class CompilationStateImpl {
void AddCallback(CompilationState::callback_t);
// Inserts new functions to compile and kicks off compilation.
- void AddCompilationUnits(Vector<WasmCompilationUnit> baseline_units,
- Vector<WasmCompilationUnit> top_tier_units);
+ void AddCompilationUnits(
+ Vector<WasmCompilationUnit> baseline_units,
+ Vector<WasmCompilationUnit> top_tier_units,
+ Vector<std::shared_ptr<JSToWasmWrapperCompilationUnit>>
+ js_to_wasm_wrapper_units);
void AddTopTierCompilationUnit(WasmCompilationUnit);
base::Optional<WasmCompilationUnit> GetNextCompilationUnit(
int task_id, CompileBaselineOnly baseline_only);
+ std::shared_ptr<JSToWasmWrapperCompilationUnit>
+ GetNextJSToWasmWrapperCompilationUnit();
+ void FinalizeJSToWasmWrappers(Isolate* isolate, const WasmModule* module,
+ Handle<FixedArray>* export_wrappers_out);
+
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 UpdateDetectedFeatures(const WasmFeatures& detected);
@@ -471,7 +481,7 @@ class CompilationStateImpl {
// Compilation error, atomically updated. This flag can be updated and read
// using relaxed semantics.
- std::atomic_bool compile_failed_{false};
+ std::atomic<bool> compile_failed_{false};
const int max_background_tasks_ = 0;
@@ -484,6 +494,13 @@ class CompilationStateImpl {
// tasks a fair chance to utilize the worker threads on a regular basis.
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
// being accessed concurrently.
mutable base::Mutex mutex_;
@@ -525,9 +542,9 @@ class CompilationStateImpl {
//////////////////////////////////////////////////////////////////////////////
// Encoding of fields in the {compilation_progress_} vector.
- class RequiredBaselineTierField : public BitField8<ExecutionTier, 0, 2> {};
- class RequiredTopTierField : public BitField8<ExecutionTier, 2, 2> {};
- class ReachedTierField : public BitField8<ExecutionTier, 4, 2> {};
+ using RequiredBaselineTierField = BitField8<ExecutionTier, 0, 2>;
+ using RequiredTopTierField = BitField8<ExecutionTier, 2, 2>;
+ using ReachedTierField = BitField8<ExecutionTier, 4, 2>;
};
CompilationStateImpl* Impl(CompilationState* compilation_state) {
@@ -712,6 +729,11 @@ class CompilationUnitBuilder {
}
}
+ void AddJSToWasmWrapperUnit(
+ std::shared_ptr<JSToWasmWrapperCompilationUnit> unit) {
+ js_to_wasm_wrapper_units_.emplace_back(std::move(unit));
+ }
+
void AddTopTierUnit(int func_index) {
ExecutionTierPair tiers = GetRequestedExecutionTiers(
native_module_->module(), compilation_state()->compile_mode(),
@@ -730,9 +752,13 @@ class CompilationUnitBuilder {
}
bool Commit() {
- if (baseline_units_.empty() && tiering_units_.empty()) return false;
- compilation_state()->AddCompilationUnits(VectorOf(baseline_units_),
- VectorOf(tiering_units_));
+ if (baseline_units_.empty() && tiering_units_.empty() &&
+ js_to_wasm_wrapper_units_.empty()) {
+ return false;
+ }
+ compilation_state()->AddCompilationUnits(
+ VectorOf(baseline_units_), VectorOf(tiering_units_),
+ VectorOf(js_to_wasm_wrapper_units_));
Clear();
return true;
}
@@ -740,6 +766,7 @@ class CompilationUnitBuilder {
void Clear() {
baseline_units_.clear();
tiering_units_.clear();
+ js_to_wasm_wrapper_units_.clear();
}
private:
@@ -751,6 +778,8 @@ class CompilationUnitBuilder {
const ExecutionTier default_tier_;
std::vector<WasmCompilationUnit> baseline_units_;
std::vector<WasmCompilationUnit> tiering_units_;
+ std::vector<std::shared_ptr<JSToWasmWrapperCompilationUnit>>
+ js_to_wasm_wrapper_units_;
};
void SetCompileError(ErrorThrower* thrower, ModuleWireBytes wire_bytes,
@@ -910,6 +939,33 @@ void RecordStats(const Code code, Counters* counters) {
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.
// Returns whether any units were executed.
bool ExecuteCompilationUnits(
@@ -918,6 +974,13 @@ bool ExecuteCompilationUnits(
TRACE_COMPILE("Compiling (task %d)...\n", task_id);
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;
// 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
@@ -1050,6 +1113,35 @@ bool ExecuteCompilationUnits(
return true;
}
+using JSToWasmWrapperKey = std::pair<bool, FunctionSig>;
+
+// Returns the number of units added.
+int AddExportWrapperUnits(Isolate* isolate, WasmEngine* wasm_engine,
+ NativeModule* native_module,
+ CompilationUnitBuilder* builder,
+ const WasmFeatures& enabled_features) {
+// Disable asynchronous wrapper compilation when builtins are not embedded,
+// otherwise the isolate might be used after tear down to access builtins.
+#ifdef V8_EMBEDDED_BUILTINS
+ 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, wasm_engine, function.sig, function.imported,
+ enabled_features);
+ builder->AddJSToWasmWrapperUnit(std::move(unit));
+ }
+ }
+
+ return static_cast<int>(keys.size());
+#else
+ return 0;
+#endif
+}
+
// Returns the number of units added.
int AddImportWrapperUnits(NativeModule* native_module,
CompilationUnitBuilder* builder) {
@@ -1059,8 +1151,7 @@ int AddImportWrapperUnits(NativeModule* native_module,
int num_imported_functions = native_module->num_imported_functions();
for (int func_index = 0; func_index < num_imported_functions; func_index++) {
FunctionSig* sig = native_module->module()->functions[func_index].sig;
- bool has_bigint_feature = native_module->enabled_features().bigint;
- if (!IsJSCompatibleSignature(sig, has_bigint_feature)) {
+ if (!IsJSCompatibleSignature(sig, native_module->enabled_features())) {
continue;
}
WasmImportWrapperCache::CacheKey key(compiler::kDefaultImportCallKind, sig);
@@ -1075,7 +1166,7 @@ int AddImportWrapperUnits(NativeModule* native_module,
return static_cast<int>(keys.size());
}
-void InitializeCompilationUnits(NativeModule* native_module) {
+void InitializeCompilationUnits(Isolate* isolate, NativeModule* native_module) {
CompilationStateImpl* compilation_state =
Impl(native_module->compilation_state());
const bool lazy_module = IsLazyModule(native_module->module());
@@ -1099,8 +1190,11 @@ void InitializeCompilationUnits(NativeModule* native_module) {
}
}
int num_import_wrappers = AddImportWrapperUnits(native_module, &builder);
- compilation_state->InitializeCompilationProgress(lazy_module,
- num_import_wrappers);
+ int num_export_wrappers =
+ AddExportWrapperUnits(isolate, isolate->wasm_engine(), native_module,
+ &builder, WasmFeaturesFromIsolate(isolate));
+ compilation_state->InitializeCompilationProgress(
+ lazy_module, num_import_wrappers + num_export_wrappers);
builder.Commit();
}
@@ -1202,7 +1296,7 @@ void CompileNativeModule(Isolate* isolate, ErrorThrower* thrower,
}
// Initialize the compilation units and kick off background compile tasks.
- InitializeCompilationUnits(native_module);
+ InitializeCompilationUnits(isolate, native_module);
// If tiering is disabled, the main thread can execute any unit (all of them
// are part of initial compilation). Otherwise, just execute baseline units.
@@ -1274,26 +1368,23 @@ std::shared_ptr<NativeModule> CompileToNativeModule(
OwnedVector<uint8_t> wire_bytes_copy =
OwnedVector<uint8_t>::Of(wire_bytes.module_bytes());
- // Create and compile the native module.
- size_t code_size_estimate =
- wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module.get());
-
// Create a new {NativeModule} first.
auto native_module = isolate->wasm_engine()->NewNativeModule(
- isolate, enabled, code_size_estimate,
- wasm::NativeModule::kCanAllocateMoreMemory, std::move(module));
+ isolate, enabled, std::move(module));
native_module->SetWireBytes(std::move(wire_bytes_copy));
native_module->SetRuntimeStubs(isolate);
CompileNativeModule(isolate, thrower, wasm_module, native_module.get());
if (thrower->error()) return {};
- // Compile JS->wasm wrappers for exported functions.
- int num_wrappers = MaxNumExportWrappers(native_module->module());
- *export_wrappers_out =
- isolate->factory()->NewFixedArray(num_wrappers, AllocationType::kOld);
+#ifdef V8_EMBEDDED_BUILTINS
+ Impl(native_module->compilation_state())
+ ->FinalizeJSToWasmWrappers(isolate, native_module->module(),
+ export_wrappers_out);
+#else
CompileJsToWasmWrappers(isolate, native_module->module(),
- *export_wrappers_out);
+ export_wrappers_out);
+#endif
// Log the code within the generated module for profiling.
native_module->LogWasmCodes(isolate);
@@ -1367,7 +1458,9 @@ class AsyncStreamingProcessor final : public StreamingProcessor {
ModuleDecoder decoder_;
AsyncCompileJob* job_;
+ WasmEngine* wasm_engine_;
std::unique_ptr<CompilationUnitBuilder> compilation_unit_builder_;
+ base::TimeTicks start_time_;
int num_functions_ = 0;
};
@@ -1415,11 +1508,8 @@ void AsyncCompileJob::CreateNativeModule(
// breakpoints on a (potentially empty) subset of the instances.
// Create the module object.
- size_t code_size_estimate =
- wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module.get());
native_module_ = isolate_->wasm_engine()->NewNativeModule(
- isolate_, enabled_features_, code_size_estimate,
- wasm::NativeModule::kCanAllocateMoreMemory, std::move(module));
+ isolate_, enabled_features_, std::move(module));
native_module_->SetWireBytes({std::move(bytes_copy_), wire_bytes_.length()});
native_module_->SetRuntimeStubs(isolate_);
@@ -1433,10 +1523,8 @@ void AsyncCompileJob::PrepareRuntimeObjects() {
Handle<Script> script =
CreateWasmScript(isolate_, wire_bytes_, module->source_map_url);
- size_t code_size_estimate =
- wasm::WasmCodeManager::EstimateNativeModuleCodeSize(module);
- Handle<WasmModuleObject> module_object = WasmModuleObject::New(
- isolate_, native_module_, script, code_size_estimate);
+ Handle<WasmModuleObject> module_object =
+ WasmModuleObject::New(isolate_, native_module_, script);
module_object_ = isolate_->global_handles()->Create(*module_object);
}
@@ -1462,17 +1550,25 @@ void AsyncCompileJob::FinishCompile() {
}
isolate_->debug()->OnAfterCompile(script);
- // We can only update the feature counts once the entire compile is done.
auto compilation_state =
Impl(module_object_->native_module()->compilation_state());
- compilation_state->PublishDetectedFeatures(isolate_);
-
// TODO(bbudge) Allow deserialization without wrapper compilation, so we can
// just compile wrappers here.
if (!is_after_deserialization) {
- // TODO(wasm): compiling wrappers should be made async.
- CompileWrappers();
+#ifdef V8_EMBEDDED_BUILTINS
+ Handle<FixedArray> export_wrappers;
+ compilation_state->FinalizeJSToWasmWrappers(
+ isolate_, module_object_->module(), &export_wrappers);
+ module_object_->set_export_wrappers(*export_wrappers);
+#else
+ Handle<FixedArray> export_wrappers;
+ CompileJsToWasmWrappers(isolate_, module_object_->module(),
+ &export_wrappers);
+ module_object_->set_export_wrappers(*export_wrappers);
+#endif
}
+ // We can only update the feature counts once the entire compile is done.
+ compilation_state->PublishDetectedFeatures(isolate_);
FinishModule();
}
@@ -1792,7 +1888,7 @@ class AsyncCompileJob::PrepareAndStartCompile : public CompileStep {
// then DoAsync would do the same as NextStep already.
// Add compilation units and kick off compilation.
- InitializeCompilationUnits(job->native_module_.get());
+ InitializeCompilationUnits(job->isolate(), job->native_module_.get());
}
}
};
@@ -1853,17 +1949,8 @@ 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() {
- TRACE_COMPILE("(6) Finish module...\n");
+ TRACE_COMPILE("(4) Finish module...\n");
AsyncCompileSucceeded(module_object_);
isolate_->wasm_engine()->RemoveCompileJob(this);
}
@@ -1871,7 +1958,9 @@ void AsyncCompileJob::FinishModule() {
AsyncStreamingProcessor::AsyncStreamingProcessor(AsyncCompileJob* job)
: decoder_(job->enabled_features_),
job_(job),
- compilation_unit_builder_(nullptr) {}
+ wasm_engine_(job_->isolate_->wasm_engine()),
+ compilation_unit_builder_(nullptr),
+ start_time_(base::TimeTicks::Now()) {}
void AsyncStreamingProcessor::FinishAsyncCompileJobWithError(
const WasmError& error) {
@@ -1973,8 +2062,11 @@ bool AsyncStreamingProcessor::ProcessCodeSectionHeader(
int num_import_wrappers =
AddImportWrapperUnits(native_module, compilation_unit_builder_.get());
- compilation_state->InitializeCompilationProgress(lazy_module,
- num_import_wrappers);
+ int num_export_wrappers = AddExportWrapperUnits(
+ job_->isolate_, wasm_engine_, native_module,
+ compilation_unit_builder_.get(), job_->enabled_features_);
+ compilation_state->InitializeCompilationProgress(
+ lazy_module, num_import_wrappers + num_export_wrappers);
return true;
}
@@ -2097,6 +2189,13 @@ bool AsyncStreamingProcessor::Deserialize(Vector<const uint8_t> module_bytes,
MaybeHandle<WasmModuleObject> result =
DeserializeNativeModule(job_->isolate_, module_bytes, wire_bytes);
+ if (base::TimeTicks::IsHighResolution()) {
+ base::TimeDelta duration = base::TimeTicks::Now() - start_time_;
+ auto* histogram = job_->isolate_->counters()
+ ->wasm_streaming_deserialize_wasm_module_time();
+ histogram->AddSample(static_cast<int>(duration.InMicroseconds()));
+ }
+
if (result.is_null()) return false;
job_->module_object_ =
@@ -2145,8 +2244,8 @@ void CompilationStateImpl::AbortCompilation() {
callbacks_.clear();
}
-void CompilationStateImpl::InitializeCompilationProgress(
- bool lazy_module, int num_import_wrappers) {
+void CompilationStateImpl::InitializeCompilationProgress(bool lazy_module,
+ int num_wrappers) {
DCHECK(!failed());
auto enabled_features = native_module_->enabled_features();
auto* module = native_module_->module();
@@ -2190,7 +2289,7 @@ void CompilationStateImpl::InitializeCompilationProgress(
DCHECK_IMPLIES(lazy_module, outstanding_top_tier_functions_ == 0);
DCHECK_LE(0, outstanding_baseline_units_);
DCHECK_LE(outstanding_baseline_units_, outstanding_top_tier_functions_);
- outstanding_baseline_units_ += num_import_wrappers;
+ outstanding_baseline_units_ += num_wrappers;
// Trigger callbacks if module needs no baseline or top tier compilation. This
// can be the case for an empty or fully lazy module.
@@ -2215,15 +2314,52 @@ void CompilationStateImpl::AddCallback(CompilationState::callback_t callback) {
void CompilationStateImpl::AddCompilationUnits(
Vector<WasmCompilationUnit> baseline_units,
- Vector<WasmCompilationUnit> top_tier_units) {
- compilation_unit_queues_.AddUnits(baseline_units, top_tier_units,
- native_module_->module());
+ 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,
+ 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();
}
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_out) {
+ *export_wrappers_out = isolate->factory()->NewFixedArray(
+ MaxNumExportWrappers(module), AllocationType::kOld);
+ // 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_out)->set(wrapper_index, *code);
+ RecordStats(*code, isolate->counters());
+ }
}
base::Optional<WasmCompilationUnit>
@@ -2313,25 +2449,38 @@ void CompilationStateImpl::OnFinishedUnits(Vector<WasmCode*> code_vector) {
DCHECK_LE(0, outstanding_baseline_units_);
}
- // Trigger callbacks.
- if (completes_baseline_compilation) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "BaselineFinished");
- for (auto& callback : callbacks_) {
- callback(CompilationEvent::kFinishedBaselineCompilation);
- }
- if (outstanding_top_tier_functions_ == 0) {
- completes_top_tier_compilation = true;
- }
+ TriggerCallbacks(completes_baseline_compilation,
+ 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) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "BaselineFinished");
+ for (auto& callback : callbacks_) {
+ callback(CompilationEvent::kFinishedBaselineCompilation);
}
- if (outstanding_baseline_units_ == 0 && completes_top_tier_compilation) {
- TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "TopTierFinished");
- for (auto& callback : callbacks_) {
- callback(CompilationEvent::kFinishedTopTierCompilation);
- }
- // Clear the callbacks because no more events will be delivered.
- callbacks_.clear();
+ if (outstanding_top_tier_functions_ == 0) {
+ completes_top_tier_compilation = true;
}
}
+ if (outstanding_baseline_units_ == 0 && completes_top_tier_compilation) {
+ TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.wasm"), "TopTierFinished");
+ for (auto& callback : callbacks_) {
+ callback(CompilationEvent::kFinishedTopTierCompilation);
+ }
+ // Clear the callbacks because no more events will be delivered.
+ callbacks_.clear();
+ }
}
void CompilationStateImpl::OnBackgroundTaskStopped(
@@ -2379,6 +2528,11 @@ void CompilationStateImpl::RestartBackgroundTasks() {
if (failed()) return;
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) {
int task_id = available_task_ids_.back();
@@ -2418,7 +2572,6 @@ void CompilationStateImpl::SetError() {
}
namespace {
-using JSToWasmWrapperKey = std::pair<bool, FunctionSig>;
using JSToWasmWrapperQueue =
WrapperQueue<JSToWasmWrapperKey, base::hash<JSToWasmWrapperKey>>;
using JSToWasmWrapperUnitMap =
@@ -2449,9 +2602,13 @@ class CompileJSToWasmWrapperTask final : public CancelableTask {
} // namespace
void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module,
- Handle<FixedArray> export_wrappers) {
+ Handle<FixedArray>* export_wrappers_out) {
+ *export_wrappers_out = isolate->factory()->NewFixedArray(
+ MaxNumExportWrappers(module), AllocationType::kOld);
+
JSToWasmWrapperQueue queue;
JSToWasmWrapperUnitMap compilation_units;
+ WasmFeatures enabled_features = WasmFeaturesFromIsolate(isolate);
// Prepare compilation units in the main thread.
for (auto exp : module->export_table) {
@@ -2460,8 +2617,8 @@ void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module,
JSToWasmWrapperKey key(function.imported, *function.sig);
if (queue.insert(key)) {
auto unit = base::make_unique<JSToWasmWrapperCompilationUnit>(
- isolate, function.sig, function.imported);
- unit->Prepare(isolate);
+ isolate, isolate->wasm_engine(), function.sig, function.imported,
+ enabled_features);
compilation_units.emplace(key, std::move(unit));
}
}
@@ -2492,7 +2649,7 @@ void CompileJsToWasmWrappers(Isolate* isolate, const WasmModule* module,
JSToWasmWrapperCompilationUnit* unit = pair.second.get();
Handle<Code> code = unit->Finalize(isolate);
int wrapper_index = GetExportWrapperIndex(module, &key.second, key.first);
- export_wrappers->set(wrapper_index, *code);
+ (*export_wrappers_out)->set(wrapper_index, *code);
RecordStats(*code, isolate->counters());
}
}