diff options
author | Myles Borins <mylesborins@google.com> | 2019-09-24 11:56:38 -0400 |
---|---|---|
committer | Myles Borins <myles.borins@gmail.com> | 2019-10-07 03:19:23 -0400 |
commit | f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2 (patch) | |
tree | f5edbccb3ffda2573d70a6e291e7157f290e0ae0 /deps/v8/src/wasm/module-compiler.cc | |
parent | ffd22e81983056d09c064c59343a0e488236272d (diff) | |
download | android-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.tar.gz android-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.tar.bz2 android-node-v8-f7f6c928c1c9c136b7926f892b8a2fda11d8b4b2.zip |
deps: update V8 to 7.8.279.9
PR-URL: https://github.com/nodejs/node/pull/29694
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Diffstat (limited to 'deps/v8/src/wasm/module-compiler.cc')
-rw-r--r-- | deps/v8/src/wasm/module-compiler.cc | 341 |
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()); } } |