diff --git a/src/codegen/compiler.cc b/src/codegen/compiler.cc index f9efb3eb82..19628adbe6 100644 --- a/src/codegen/compiler.cc +++ b/src/codegen/compiler.cc @@ -36,7 +36,6 @@ #include "src/heap/heap-inl.h" #include "src/heap/local-factory-inl.h" #include "src/heap/local-heap-inl.h" -#include "src/heap/local-heap.h" #include "src/init/bootstrapper.h" #include "src/interpreter/interpreter.h" #include "src/logging/log-inl.h" @@ -341,13 +340,12 @@ CompilationJob::Status OptimizedCompilationJob::PrepareJob(Isolate* isolate) { } CompilationJob::Status OptimizedCompilationJob::ExecuteJob( - RuntimeCallStats* stats, LocalIsolate* local_isolate) { + RuntimeCallStats* stats) { DisallowHeapAccess no_heap_access; // Delegate to the underlying implementation. DCHECK_EQ(state(), State::kReadyToExecute); ScopedTimer t(&time_taken_to_execute_); - return UpdateState(ExecuteJobImpl(stats, local_isolate), - State::kReadyToFinalize); + return UpdateState(ExecuteJobImpl(stats), State::kReadyToFinalize); } CompilationJob::Status OptimizedCompilationJob::FinalizeJob(Isolate* isolate) { @@ -953,21 +951,10 @@ bool GetOptimizedCodeNow(OptimizedCompilationJob* job, Isolate* isolate, TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.OptimizeNonConcurrent"); - if (!PrepareJobWithHandleScope(job, isolate, compilation_info)) { - CompilerTracer::TraceAbortedJob(isolate, compilation_info); - return false; - } - - { - LocalIsolate local_isolate(isolate); - if (job->ExecuteJob(isolate->counters()->runtime_call_stats(), - &local_isolate)) { - CompilerTracer::TraceAbortedJob(isolate, compilation_info); - return false; - } - } - - if (job->FinalizeJob(isolate) != CompilationJob::SUCCEEDED) { + if (!PrepareJobWithHandleScope(job, isolate, compilation_info) || + job->ExecuteJob(isolate->counters()->runtime_call_stats()) != + CompilationJob::SUCCEEDED || + job->FinalizeJob(isolate) != CompilationJob::SUCCEEDED) { CompilerTracer::TraceAbortedJob(isolate, compilation_info); return false; } @@ -1573,7 +1560,6 @@ void BackgroundCompileTask::Run() { DCHECK(info_->flags().is_toplevel()); LocalIsolate isolate(isolate_for_local_isolate_); - UnparkedScope unparked_scope(isolate.heap()); LocalHandleScope handle_scope(&isolate); info_->ast_value_factory()->Internalize(&isolate); diff --git a/src/codegen/compiler.h b/src/codegen/compiler.h index 9687907c68..1e3ed00f93 100644 --- a/src/codegen/compiler.h +++ b/src/codegen/compiler.h @@ -332,8 +332,7 @@ class OptimizedCompilationJob : public CompilationJob { // Executes the compile job. Can be called on a background thread if // can_execute_on_background_thread() returns true. - V8_WARN_UNUSED_RESULT Status - ExecuteJob(RuntimeCallStats* stats, LocalIsolate* local_isolate = nullptr); + V8_WARN_UNUSED_RESULT Status ExecuteJob(RuntimeCallStats* stats); // Finalizes the compile job. Must be called on the main thread. V8_WARN_UNUSED_RESULT Status FinalizeJob(Isolate* isolate); @@ -358,8 +357,7 @@ class OptimizedCompilationJob : public CompilationJob { protected: // Overridden by the actual implementation. virtual Status PrepareJobImpl(Isolate* isolate) = 0; - virtual Status ExecuteJobImpl(RuntimeCallStats* stats, - LocalIsolate* local_heap) = 0; + virtual Status ExecuteJobImpl(RuntimeCallStats* stats) = 0; virtual Status FinalizeJobImpl(Isolate* isolate) = 0; private: diff --git a/src/codegen/optimized-compilation-info.h b/src/codegen/optimized-compilation-info.h index 2cdf034d7f..1225307c61 100644 --- a/src/codegen/optimized-compilation-info.h +++ b/src/codegen/optimized-compilation-info.h @@ -302,8 +302,11 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final { // 1) PersistentHandles created via PersistentHandlesScope inside of // CompilationHandleScope // 2) Owned by OptimizedCompilationInfo - // 3) Owned by the broker's LocalHeap when entering the LocalHeapScope. - // 4) Back to OptimizedCompilationInfo when exiting the LocalHeapScope. + // 3) Owned by JSHeapBroker + // 4) Owned by the broker's LocalHeap + // 5) Back to the broker for a brief moment (after tearing down the + // LocalHeap as part of exiting LocalHeapScope) + // 6) Back to OptimizedCompilationInfo when exiting the LocalHeapScope. // // In normal execution it gets destroyed when PipelineData gets destroyed. // There is a special case in GenerateCodeForTesting where the JSHeapBroker diff --git a/src/compiler-dispatcher/optimizing-compile-dispatcher.cc b/src/compiler-dispatcher/optimizing-compile-dispatcher.cc index dc64a02182..528a9babe3 100644 --- a/src/compiler-dispatcher/optimizing-compile-dispatcher.cc +++ b/src/compiler-dispatcher/optimizing-compile-dispatcher.cc @@ -8,8 +8,6 @@ #include "src/codegen/compiler.h" #include "src/codegen/optimized-compilation-info.h" #include "src/execution/isolate.h" -#include "src/execution/local-isolate.h" -#include "src/heap/local-heap.h" #include "src/init/v8.h" #include "src/logging/counters.h" #include "src/logging/log.h" @@ -58,7 +56,6 @@ class OptimizingCompileDispatcher::CompileTask : public CancelableTask { private: // v8::Task overrides. void RunInternal() override { - LocalIsolate local_isolate(isolate_); DisallowHeapAllocation no_allocation; DisallowHandleAllocation no_handles; DisallowHandleDereference no_deref; @@ -79,8 +76,8 @@ class OptimizingCompileDispatcher::CompileTask : public CancelableTask { dispatcher_->recompilation_delay_)); } - dispatcher_->CompileNext(dispatcher_->NextInput(&local_isolate, true), - runtime_call_stats_scope.Get(), &local_isolate); + dispatcher_->CompileNext(dispatcher_->NextInput(true), + runtime_call_stats_scope.Get()); } { base::MutexGuard lock_guard(&dispatcher_->ref_count_mutex_); @@ -109,7 +106,7 @@ OptimizingCompileDispatcher::~OptimizingCompileDispatcher() { } OptimizedCompilationJob* OptimizingCompileDispatcher::NextInput( - LocalIsolate* local_isolate, bool check_if_flushing) { + bool check_if_flushing) { base::MutexGuard access_input_queue_(&input_queue_mutex_); if (input_queue_length_ == 0) return nullptr; OptimizedCompilationJob* job = input_queue_[InputQueueIndex(0)]; @@ -118,7 +115,6 @@ OptimizedCompilationJob* OptimizingCompileDispatcher::NextInput( input_queue_length_--; if (check_if_flushing) { if (mode_ == FLUSH) { - UnparkedScope scope(local_isolate->heap()); AllowHandleDereference allow_handle_dereference; DisposeCompilationJob(job, true); return nullptr; @@ -128,12 +124,11 @@ OptimizedCompilationJob* OptimizingCompileDispatcher::NextInput( } void OptimizingCompileDispatcher::CompileNext(OptimizedCompilationJob* job, - RuntimeCallStats* stats, - LocalIsolate* local_isolate) { + RuntimeCallStats* stats) { if (!job) return; // The function may have already been optimized by OSR. Simply continue. - CompilationJob::Status status = job->ExecuteJob(stats, local_isolate); + CompilationJob::Status status = job->ExecuteJob(stats); USE(status); // Prevent an unused-variable error. { diff --git a/src/compiler-dispatcher/optimizing-compile-dispatcher.h b/src/compiler-dispatcher/optimizing-compile-dispatcher.h index 36f285d163..51803822d1 100644 --- a/src/compiler-dispatcher/optimizing-compile-dispatcher.h +++ b/src/compiler-dispatcher/optimizing-compile-dispatcher.h @@ -18,7 +18,6 @@ namespace v8 { namespace internal { -class LocalHeap; class OptimizedCompilationJob; class RuntimeCallStats; class SharedFunctionInfo; @@ -59,10 +58,8 @@ class V8_EXPORT_PRIVATE OptimizingCompileDispatcher { enum ModeFlag { COMPILE, FLUSH }; void FlushOutputQueue(bool restore_function_code); - void CompileNext(OptimizedCompilationJob* job, RuntimeCallStats* stats, - LocalIsolate* local_isolate); - OptimizedCompilationJob* NextInput(LocalIsolate* local_isolate, - bool check_if_flushing = false); + void CompileNext(OptimizedCompilationJob* job, RuntimeCallStats* stats); + OptimizedCompilationJob* NextInput(bool check_if_flushing = false); inline int InputQueueIndex(int i) { int result = (i + input_queue_shift_) % input_queue_capacity_; diff --git a/src/compiler/js-heap-broker.cc b/src/compiler/js-heap-broker.cc index 3b76c289b5..28639e1181 100644 --- a/src/compiler/js-heap-broker.cc +++ b/src/compiler/js-heap-broker.cc @@ -2427,6 +2427,7 @@ JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone, tracing_enabled_(tracing_enabled), is_concurrent_inlining_(is_concurrent_inlining), code_kind_(code_kind), + local_heap_(base::nullopt), feedback_(zone()), bytecode_analyses_(zone()), property_access_infos_(zone()), @@ -2471,23 +2472,20 @@ std::string JSHeapBroker::Trace() const { return oss.str(); } -void JSHeapBroker::InitializeLocalHeap(OptimizedCompilationInfo* info, - LocalHeap* local_heap) { +void JSHeapBroker::InitializeLocalHeap(OptimizedCompilationInfo* info) { + set_persistent_handles(info->DetachPersistentHandles()); set_canonical_handles(info->DetachCanonicalHandles()); - DCHECK_NULL(local_heap_); - local_heap_ = local_heap; - DCHECK_NOT_NULL(local_heap_); - local_heap_->AttachPersistentHandles(info->DetachPersistentHandles()); + DCHECK(!local_heap_); + local_heap_.emplace(isolate_->heap(), std::move(ph_)); } void JSHeapBroker::TearDownLocalHeap(OptimizedCompilationInfo* info) { DCHECK_NULL(ph_); DCHECK(local_heap_); - std::unique_ptr ph = - local_heap_->DetachPersistentHandles(); - local_heap_ = nullptr; + ph_ = local_heap_->DetachPersistentHandles(); + local_heap_.reset(); info->set_canonical_handles(DetachCanonicalHandles()); - info->set_persistent_handles(std::move(ph)); + info->set_persistent_handles(DetachPersistentHandles()); } void JSHeapBroker::StopSerializing() { diff --git a/src/compiler/js-heap-broker.h b/src/compiler/js-heap-broker.h index e25997427d..1df21109bf 100644 --- a/src/compiler/js-heap-broker.h +++ b/src/compiler/js-heap-broker.h @@ -117,8 +117,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { BrokerMode mode() const { return mode_; } // Initialize the local heap with the persistent and canonical handles // provided by {info}. - void InitializeLocalHeap(OptimizedCompilationInfo* info, - LocalHeap* local_heap); + void InitializeLocalHeap(OptimizedCompilationInfo* info); // Tear down the local heap and pass the persistent and canonical handles // provided back to {info}. {info} is responsible for disposing of them. void TearDownLocalHeap(OptimizedCompilationInfo* info); @@ -228,7 +227,9 @@ class V8_EXPORT_PRIVATE JSHeapBroker { bool IsSerializedForCompilation(const SharedFunctionInfoRef& shared, const FeedbackVectorRef& feedback) const; - LocalHeap* local_heap() { return local_heap_; } + LocalHeap* local_heap() { + return local_heap_.has_value() ? &(*local_heap_) : nullptr; + } // Return the corresponding canonical persistent handle for {object}. Create // one if it does not exist. @@ -360,7 +361,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { bool const is_concurrent_inlining_; CodeKind const code_kind_; std::unique_ptr ph_; - LocalHeap* local_heap_ = nullptr; + base::Optional local_heap_; std::unique_ptr canonical_handles_; unsigned trace_indentation_ = 0; PerIsolateCompilerCache* compiler_cache_ = nullptr; @@ -452,16 +453,14 @@ class OffHeapBytecodeArray final : public interpreter::AbstractBytecodeArray { // Scope that unparks the LocalHeap, if: // a) We have a JSHeapBroker, -// b) Said JSHeapBroker has a LocalHeap, -// c) Said LocalHeap has been parked and -// d) The given condition evaluates to true. +// b) Said JSHeapBroker has a LocalHeap, and +// c) Said LocalHeap has been parked. // Used, for example, when printing the graph with --trace-turbo with a // previously parked LocalHeap. class UnparkedScopeIfNeeded { public: - explicit UnparkedScopeIfNeeded(JSHeapBroker* broker, - bool extra_condition = true) { - if (broker != nullptr && extra_condition) { + explicit UnparkedScopeIfNeeded(JSHeapBroker* broker) { + if (broker != nullptr) { LocalHeap* local_heap = broker->local_heap(); if (local_heap != nullptr && local_heap->IsParked()) { unparked_scope.emplace(local_heap); diff --git a/src/compiler/pipeline.cc b/src/compiler/pipeline.cc index c394b8184c..8ff486983c 100644 --- a/src/compiler/pipeline.cc +++ b/src/compiler/pipeline.cc @@ -83,7 +83,6 @@ #include "src/diagnostics/code-tracer.h" #include "src/diagnostics/disassembler.h" #include "src/execution/isolate-inl.h" -#include "src/heap/local-heap.h" #include "src/init/bootstrapper.h" #include "src/logging/counters.h" #include "src/objects/shared-function-info.h" @@ -766,14 +765,12 @@ class PipelineRunScope { RuntimeCallTimerScope runtime_call_timer_scope; }; -// LocalHeapScope encapsulates the phase where persistent handles are attached -// to the LocalHeap. +// LocalHeapScope encapsulates the liveness of the brokers's LocalHeap. class LocalHeapScope { public: - explicit LocalHeapScope(JSHeapBroker* broker, OptimizedCompilationInfo* info, - LocalHeap* local_heap) + explicit LocalHeapScope(JSHeapBroker* broker, OptimizedCompilationInfo* info) : broker_(broker), info_(info) { - broker_->InitializeLocalHeap(info_, local_heap); + broker_->InitializeLocalHeap(info_); info_->tick_counter().AttachLocalHeap(broker_->local_heap()); } @@ -1033,8 +1030,7 @@ class PipelineCompilationJob final : public OptimizedCompilationJob { protected: Status PrepareJobImpl(Isolate* isolate) final; - Status ExecuteJobImpl(RuntimeCallStats* stats, - LocalIsolate* local_isolate) final; + Status ExecuteJobImpl(RuntimeCallStats* stats) final; Status FinalizeJobImpl(Isolate* isolate) final; // Registers weak object to optimized code dependencies. @@ -1181,27 +1177,29 @@ PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl( } PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl( - RuntimeCallStats* stats, LocalIsolate* local_isolate) { + RuntimeCallStats* stats) { // Ensure that the RuntimeCallStats table is only available during execution // and not during finalization as that might be on a different thread. PipelineJobScope scope(&data_, stats); - LocalHeapScope local_heap_scope(data_.broker(), data_.info(), - local_isolate->heap()); - - if (data_.broker()->is_concurrent_inlining()) { - if (!pipeline_.CreateGraph()) { - return AbortOptimization(BailoutReason::kGraphBuildingFailed); + { + LocalHeapScope local_heap_scope(data_.broker(), data_.info()); + if (data_.broker()->is_concurrent_inlining()) { + if (!pipeline_.CreateGraph()) { + return AbortOptimization(BailoutReason::kGraphBuildingFailed); + } } - } - // We selectively Unpark inside OptimizeGraph*. - bool success; - if (compilation_info_.code_kind() == CodeKind::TURBOPROP) { - success = pipeline_.OptimizeGraphForMidTier(linkage_); - } else { - success = pipeline_.OptimizeGraph(linkage_); + // We selectively Unpark inside OptimizeGraph*. + ParkedScope parked_scope(data_.broker()->local_heap()); + + bool success; + if (compilation_info_.code_kind() == CodeKind::TURBOPROP) { + success = pipeline_.OptimizeGraphForMidTier(linkage_); + } else { + success = pipeline_.OptimizeGraph(linkage_); + } + if (!success) return FAILED; } - if (!success) return FAILED; pipeline_.AssembleCode(linkage_); @@ -1285,8 +1283,7 @@ class WasmHeapStubCompilationJob final : public OptimizedCompilationJob { protected: Status PrepareJobImpl(Isolate* isolate) final; - Status ExecuteJobImpl(RuntimeCallStats* stats, - LocalIsolate* local_isolate) final; + Status ExecuteJobImpl(RuntimeCallStats* stats) final; Status FinalizeJobImpl(Isolate* isolate) final; private: @@ -1321,7 +1318,7 @@ CompilationJob::Status WasmHeapStubCompilationJob::PrepareJobImpl( } CompilationJob::Status WasmHeapStubCompilationJob::ExecuteJobImpl( - RuntimeCallStats* stats, LocalIsolate* local_isolate) { + RuntimeCallStats* stats) { std::unique_ptr pipeline_statistics; if (FLAG_turbo_stats || FLAG_turbo_stats_nvp) { pipeline_statistics.reset(new PipelineStatistics( @@ -2474,7 +2471,6 @@ void PipelineImpl::Serialize() { bool PipelineImpl::CreateGraph() { PipelineData* data = this->data_; - UnparkedScopeIfNeeded unparked_scope(data->broker()); data->BeginPhaseKind("V8.TFGraphCreation"); @@ -3026,15 +3022,13 @@ MaybeHandle Pipeline::GenerateCodeForTesting( } { - LocalIsolate local_isolate(isolate); - LocalHeapScope local_heap_scope(data.broker(), info, local_isolate.heap()); + LocalHeapScope local_heap_scope(data.broker(), info); if (data.broker()->is_concurrent_inlining()) { if (!pipeline.CreateGraph()) return MaybeHandle(); } // We selectively Unpark inside OptimizeGraph. + ParkedScope parked_scope(data.broker()->local_heap()); if (!pipeline.OptimizeGraph(&linkage)) return MaybeHandle(); - - pipeline.AssembleCode(&linkage); } const bool will_retire_broker = out_broker == nullptr; @@ -3046,6 +3040,7 @@ MaybeHandle Pipeline::GenerateCodeForTesting( info->DetachPersistentHandles(), info->DetachCanonicalHandles()); } + pipeline.AssembleCode(&linkage); Handle code; if (pipeline.FinalizeCode(will_retire_broker).ToHandle(&code) && pipeline.CommitDependencies(code)) { @@ -3483,8 +3478,6 @@ void PipelineImpl::AssembleCode(Linkage* linkage, data->BeginPhaseKind("V8.TFCodeGeneration"); data->InitializeCodeGenerator(linkage, std::move(buffer)); - UnparkedScopeIfNeeded unparked_scope(data->broker(), FLAG_code_comments); - Run(); if (data->info()->trace_turbo_json()) { TurboJsonFile json_of(data->info(), std::ios_base::app); diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc index df3ba06585..75295d662e 100644 --- a/src/compiler/wasm-compiler.cc +++ b/src/compiler/wasm-compiler.cc @@ -7657,7 +7657,7 @@ Handle CompileCWasmEntry(Isolate* isolate, const wasm::FunctionSig* sig, CodeKind::C_WASM_ENTRY, std::move(name_buffer), AssemblerOptions::Default(isolate))); - CHECK_NE(job->ExecuteJob(isolate->counters()->runtime_call_stats(), nullptr), + CHECK_NE(job->ExecuteJob(isolate->counters()->runtime_call_stats()), CompilationJob::FAILED); CHECK_NE(job->FinalizeJob(isolate), CompilationJob::FAILED); diff --git a/src/heap/concurrent-allocator.cc b/src/heap/concurrent-allocator.cc index bf7cf20168..5db9159f14 100644 --- a/src/heap/concurrent-allocator.cc +++ b/src/heap/concurrent-allocator.cc @@ -9,7 +9,6 @@ #include "src/handles/persistent-handles.h" #include "src/heap/concurrent-allocator-inl.h" #include "src/heap/local-heap-inl.h" -#include "src/heap/local-heap.h" #include "src/heap/marking.h" #include "src/heap/memory-chunk.h" @@ -19,7 +18,6 @@ namespace internal { void StressConcurrentAllocatorTask::RunInternal() { Heap* heap = isolate_->heap(); LocalHeap local_heap(heap); - UnparkedScope unparked_scope(&local_heap); const int kNumIterations = 2000; const int kSmallObjectSize = 10 * kTaggedSize; diff --git a/src/heap/local-heap.cc b/src/heap/local-heap.cc index 3327da3cd1..3f215b80a2 100644 --- a/src/heap/local-heap.cc +++ b/src/heap/local-heap.cc @@ -27,7 +27,7 @@ LocalHeap* LocalHeap::Current() { return current_local_heap; } LocalHeap::LocalHeap(Heap* heap, std::unique_ptr persistent_handles) : heap_(heap), - state_(ThreadState::Parked), + state_(ThreadState::Running), safepoint_requested_(false), allocation_failed_(false), prev_(nullptr), @@ -36,36 +36,34 @@ LocalHeap::LocalHeap(Heap* heap, persistent_handles_(std::move(persistent_handles)), marking_barrier_(new MarkingBarrier(this)), old_space_allocator_(this, heap->old_space()) { - heap_->safepoint()->AddLocalHeap(this, [this] { - if (FLAG_local_heaps) { - WriteBarrier::SetForThread(marking_barrier_.get()); - if (heap_->incremental_marking()->IsMarking()) { - marking_barrier_->Activate( - heap_->incremental_marking()->IsCompacting()); - } - } - }); - + heap_->safepoint()->AddLocalHeap(this); if (persistent_handles_) { persistent_handles_->Attach(this); } DCHECK_NULL(current_local_heap); current_local_heap = this; + // TODO(ulan): Ensure that LocalHeap cannot be created without --local-heaps. + if (FLAG_local_heaps) { + WriteBarrier::SetForThread(marking_barrier_.get()); + if (heap_->incremental_marking()->IsMarking()) { + marking_barrier_->Activate(heap_->incremental_marking()->IsCompacting()); + } + } } LocalHeap::~LocalHeap() { + // TODO(ulan): Ensure that LocalHeap cannot be created without --local-heaps. + if (FLAG_local_heaps) { + marking_barrier_->Publish(); + WriteBarrier::ClearForThread(marking_barrier_.get()); + } // Give up LAB before parking thread old_space_allocator_.FreeLinearAllocationArea(); // Park thread since removing the local heap could block. EnsureParkedBeforeDestruction(); - heap_->safepoint()->RemoveLocalHeap(this, [this] { - if (FLAG_local_heaps) { - marking_barrier_->Publish(); - WriteBarrier::ClearForThread(marking_barrier_.get()); - } - }); + heap_->safepoint()->RemoveLocalHeap(this); DCHECK_EQ(current_local_heap, this); current_local_heap = nullptr; @@ -79,13 +77,6 @@ void LocalHeap::EnsurePersistentHandles() { } } -void LocalHeap::AttachPersistentHandles( - std::unique_ptr persistent_handles) { - DCHECK_NULL(persistent_handles_); - persistent_handles_ = std::move(persistent_handles); - persistent_handles_->Attach(this); -} - std::unique_ptr LocalHeap::DetachPersistentHandles() { if (persistent_handles_) persistent_handles_->Detach(); return std::move(persistent_handles_); diff --git a/src/heap/local-heap.h b/src/heap/local-heap.h index 4798dd7eac..f6244aaefe 100644 --- a/src/heap/local-heap.h +++ b/src/heap/local-heap.h @@ -22,15 +22,6 @@ class Heap; class Safepoint; class LocalHandles; -// LocalHeap is used by the GC to track all threads with heap access in order to -// stop them before performing a collection. LocalHeaps can be either Parked or -// Running and are in Parked mode when initialized. -// Running: Thread is allowed to access the heap but needs to give the GC the -// chance to run regularly by manually invoking Safepoint(). The -// thread can be parked using ParkedScope. -// Parked: Heap access is not allowed, so the GC will not stop this thread -// for a collection. Useful when threads do not need heap access for -// some time or for blocking operations like locking a mutex. class V8_EXPORT_PRIVATE LocalHeap { public: explicit LocalHeap( @@ -79,8 +70,6 @@ class V8_EXPORT_PRIVATE LocalHeap { return kNullMaybeHandle; } - void AttachPersistentHandles( - std::unique_ptr persistent_handles); std::unique_ptr DetachPersistentHandles(); #ifdef DEBUG bool ContainsPersistentHandle(Address* location); diff --git a/src/heap/safepoint.cc b/src/heap/safepoint.cc index caa3991e5d..309e7fcf42 100644 --- a/src/heap/safepoint.cc +++ b/src/heap/safepoint.cc @@ -114,6 +114,23 @@ SafepointScope::SafepointScope(Heap* heap) : safepoint_(heap->safepoint()) { SafepointScope::~SafepointScope() { safepoint_->LeaveSafepointScope(); } +void GlobalSafepoint::AddLocalHeap(LocalHeap* local_heap) { + base::MutexGuard guard(&local_heaps_mutex_); + if (local_heaps_head_) local_heaps_head_->prev_ = local_heap; + local_heap->prev_ = nullptr; + local_heap->next_ = local_heaps_head_; + local_heaps_head_ = local_heap; +} + +void GlobalSafepoint::RemoveLocalHeap(LocalHeap* local_heap) { + base::MutexGuard guard(&local_heaps_mutex_); + if (local_heap->next_) local_heap->next_->prev_ = local_heap->prev_; + if (local_heap->prev_) + local_heap->prev_->next_ = local_heap->next_; + else + local_heaps_head_ = local_heap->next_; +} + bool GlobalSafepoint::ContainsLocalHeap(LocalHeap* local_heap) { base::MutexGuard guard(&local_heaps_mutex_); LocalHeap* current = local_heaps_head_; diff --git a/src/heap/safepoint.h b/src/heap/safepoint.h index dd2bb421be..efe499ea13 100644 --- a/src/heap/safepoint.h +++ b/src/heap/safepoint.h @@ -62,36 +62,8 @@ class GlobalSafepoint { void EnterSafepointScope(); void LeaveSafepointScope(); - template - void AddLocalHeap(LocalHeap* local_heap, Callback callback) { - // Safepoint holds this lock in order to stop threads from starting or - // stopping. - base::MutexGuard guard(&local_heaps_mutex_); - - // Additional code protected from safepoint - callback(); - - // Add list to doubly-linked list - if (local_heaps_head_) local_heaps_head_->prev_ = local_heap; - local_heap->prev_ = nullptr; - local_heap->next_ = local_heaps_head_; - local_heaps_head_ = local_heap; - } - - template - void RemoveLocalHeap(LocalHeap* local_heap, Callback callback) { - base::MutexGuard guard(&local_heaps_mutex_); - - // Additional code protected from safepoint - callback(); - - // Remove list from doubly-linked list - if (local_heap->next_) local_heap->next_->prev_ = local_heap->prev_; - if (local_heap->prev_) - local_heap->prev_->next_ = local_heap->next_; - else - local_heaps_head_ = local_heap->next_; - } + void AddLocalHeap(LocalHeap* local_heap); + void RemoveLocalHeap(LocalHeap* local_heap); Barrier barrier_; Heap* heap_; diff --git a/test/cctest/heap/test-concurrent-allocation.cc b/test/cctest/heap/test-concurrent-allocation.cc index e076c31d67..ea61eace03 100644 --- a/test/cctest/heap/test-concurrent-allocation.cc +++ b/test/cctest/heap/test-concurrent-allocation.cc @@ -52,7 +52,6 @@ class ConcurrentAllocationThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_); - UnparkedScope unparked_scope(&local_heap); for (int i = 0; i < kNumIterations; i++) { Address address = local_heap.AllocateRawOrFail( @@ -120,7 +119,6 @@ class LargeObjectConcurrentAllocationThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_); - UnparkedScope unparked_scope(&local_heap); const size_t kLargeObjectSize = kMaxRegularHeapObjectSize * 2; for (int i = 0; i < kNumIterations; i++) { @@ -188,7 +186,6 @@ class ConcurrentBlackAllocationThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_); - UnparkedScope unparked_scope(&local_heap); for (int i = 0; i < kNumIterations; i++) { if (i == kWhiteIterations) { @@ -268,7 +265,6 @@ class ConcurrentWriteBarrierThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_); - UnparkedScope unparked_scope(&local_heap); fixed_array_.set(0, value_); } @@ -330,7 +326,6 @@ class ConcurrentRecordRelocSlotThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_); - UnparkedScope unparked_scope(&local_heap); int mode_mask = RelocInfo::EmbeddedObjectModeMask(); for (RelocIterator it(code_, mode_mask); !it.done(); it.next()) { DCHECK(RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode())); diff --git a/test/cctest/heap/test-heap.cc b/test/cctest/heap/test-heap.cc index 40fad51ac5..3638ba5f88 100644 --- a/test/cctest/heap/test-heap.cc +++ b/test/cctest/heap/test-heap.cc @@ -7184,7 +7184,6 @@ TEST(GarbageCollectionWithLocalHeap) { Heap* heap = CcTest::i_isolate()->heap(); LocalHeap local_heap(heap); - UnparkedScope unparked_scope(&local_heap); CcTest::CollectGarbage(OLD_SPACE); { ParkedScope parked_scope(&local_heap); } CcTest::CollectGarbage(OLD_SPACE); diff --git a/test/cctest/test-concurrent-descriptor-array.cc b/test/cctest/test-concurrent-descriptor-array.cc index 4d8080d20d..23ad50d5b6 100644 --- a/test/cctest/test-concurrent-descriptor-array.cc +++ b/test/cctest/test-concurrent-descriptor-array.cc @@ -34,7 +34,6 @@ class ConcurrentSearchThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_, std::move(ph_)); - UnparkedScope unparked_scope(&local_heap); LocalHandleScope scope(&local_heap); for (int i = 0; i < kNumHandles; i++) { diff --git a/test/cctest/test-concurrent-prototype.cc b/test/cctest/test-concurrent-prototype.cc index 22901dfc57..bf8a710e0d 100644 --- a/test/cctest/test-concurrent-prototype.cc +++ b/test/cctest/test-concurrent-prototype.cc @@ -33,7 +33,6 @@ class ConcurrentSearchThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_, std::move(ph_)); - UnparkedScope unparked_scope(&local_heap); LocalHandleScope scope(&local_heap); for (int i = 0; i < kNumHandles; i++) { diff --git a/test/cctest/test-concurrent-script-context-table.cc b/test/cctest/test-concurrent-script-context-table.cc index d89bd0e8ca..be1c6c37e5 100644 --- a/test/cctest/test-concurrent-script-context-table.cc +++ b/test/cctest/test-concurrent-script-context-table.cc @@ -35,7 +35,6 @@ class ScriptContextTableAccessUsedThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_, std::move(ph_)); - UnparkedScope unparked_scope(&local_heap); LocalHandleScope scope(&local_heap); sema_started_->Signal(); @@ -68,7 +67,6 @@ class AccessScriptContextTableThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_, std::move(ph_)); - UnparkedScope unparked_scope(&local_heap); LocalHandleScope scope(&local_heap); sema_started_->Signal(); diff --git a/test/cctest/test-concurrent-transition-array.cc b/test/cctest/test-concurrent-transition-array.cc index f4b8bdf138..42a640de74 100644 --- a/test/cctest/test-concurrent-transition-array.cc +++ b/test/cctest/test-concurrent-transition-array.cc @@ -35,7 +35,6 @@ class ConcurrentSearchThread : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_, std::move(ph_)); - UnparkedScope scope(&local_heap); background_thread_started_->Signal(); @@ -71,7 +70,6 @@ class ConcurrentSearchOnOutdatedAccessorThread final void Run() override { LocalHeap local_heap(heap_, std::move(ph_)); - UnparkedScope scope(&local_heap); TransitionsAccessor accessor(CcTest::i_isolate(), map_, true); background_thread_started_->Signal(); diff --git a/test/cctest/test-local-handles.cc b/test/cctest/test-local-handles.cc index 1b81c28d48..8d1d08fa93 100644 --- a/test/cctest/test-local-handles.cc +++ b/test/cctest/test-local-handles.cc @@ -36,7 +36,6 @@ class LocalHandlesThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_); - UnparkedScope unparked_scope(&local_heap); LocalHandleScope scope(&local_heap); static constexpr int kNumHandles = @@ -104,7 +103,6 @@ TEST(CreateLocalHandlesWithoutLocalHandleScope) { { LocalHeap local_heap(isolate->heap()); - UnparkedScope scope(&local_heap); handle(Smi::FromInt(17), &local_heap); } } @@ -125,7 +123,6 @@ TEST(DereferenceLocalHandle) { } { LocalHeap local_heap(isolate->heap(), std::move(phs)); - UnparkedScope unparked_scope(&local_heap); LocalHandleScope scope(&local_heap); Handle local_number = handle(*ph, &local_heap); CHECK_EQ(42, local_number->value()); diff --git a/test/cctest/test-persistent-handles.cc b/test/cctest/test-persistent-handles.cc index e1db2295ac..dd94ee6ca9 100644 --- a/test/cctest/test-persistent-handles.cc +++ b/test/cctest/test-persistent-handles.cc @@ -42,7 +42,6 @@ class PersistentHandlesThread final : public v8::base::Thread { void Run() override { LocalHeap local_heap(heap_, std::move(ph_)); - UnparkedScope unparked_scope(&local_heap); LocalHandleScope scope(&local_heap); for (int i = 0; i < kNumHandles; i++) { @@ -130,7 +129,6 @@ TEST(DereferencePersistentHandle) { } { LocalHeap local_heap(isolate->heap(), std::move(phs)); - UnparkedScope scope(&local_heap); CHECK_EQ(42, ph->value()); DisallowHandleDereference disallow_scope; CHECK_EQ(42, ph->value()); @@ -142,6 +140,7 @@ TEST(NewPersistentHandleFailsWhenParked) { Isolate* isolate = CcTest::i_isolate(); LocalHeap local_heap(isolate->heap()); + ParkedScope scope(&local_heap); // Fail here in debug mode: Persistent handles can't be created if local heap // is parked local_heap.NewPersistentHandle(Smi::FromInt(1)); @@ -152,6 +151,7 @@ TEST(NewPersistentHandleFailsWhenParkedExplicit) { Isolate* isolate = CcTest::i_isolate(); LocalHeap local_heap(isolate->heap(), isolate->NewPersistentHandles()); + ParkedScope scope(&local_heap); // Fail here in debug mode: Persistent handles can't be created if local heap // is parked local_heap.NewPersistentHandle(Smi::FromInt(1)); diff --git a/test/unittests/compiler-dispatcher/optimizing-compile-dispatcher-unittest.cc b/test/unittests/compiler-dispatcher/optimizing-compile-dispatcher-unittest.cc index 4b871e7253..046898f312 100644 --- a/test/unittests/compiler-dispatcher/optimizing-compile-dispatcher-unittest.cc +++ b/test/unittests/compiler-dispatcher/optimizing-compile-dispatcher-unittest.cc @@ -10,9 +10,7 @@ #include "src/codegen/compiler.h" #include "src/codegen/optimized-compilation-info.h" #include "src/execution/isolate.h" -#include "src/execution/local-isolate.h" #include "src/handles/handles.h" -#include "src/heap/local-heap.h" #include "src/objects/objects-inl.h" #include "src/parsing/parse-info.h" #include "test/unittests/test-helpers.h" @@ -44,8 +42,7 @@ class BlockingCompilationJob : public OptimizedCompilationJob { // OptimiziedCompilationJob implementation. Status PrepareJobImpl(Isolate* isolate) override { UNREACHABLE(); } - Status ExecuteJobImpl(RuntimeCallStats* stats, - LocalIsolate* local_isolate) override { + Status ExecuteJobImpl(RuntimeCallStats* stats) override { blocking_.SetValue(true); semaphore_.Wait(); blocking_.SetValue(false); diff --git a/test/unittests/heap/local-factory-unittest.cc b/test/unittests/heap/local-factory-unittest.cc index 7f35b9b1f8..a1d750f033 100644 --- a/test/unittests/heap/local-factory-unittest.cc +++ b/test/unittests/heap/local-factory-unittest.cc @@ -62,8 +62,7 @@ class LocalFactoryTest : public TestWithIsolateAndZone { isolate(), true, construct_language_mode(FLAG_use_strict), REPLMode::kNo), &state_), - local_isolate_(isolate()), - unparked_scope_(local_isolate_.heap()) { + local_isolate_(isolate()) { FLAG_concurrent_allocation = true; } @@ -115,7 +114,6 @@ class LocalFactoryTest : public TestWithIsolateAndZone { UnoptimizedCompileState state_; ParseInfo parse_info_; LocalIsolate local_isolate_; - UnparkedScope unparked_scope_; Handle source_string_; Handle