Commit de914c75 authored by Dominik Inführ's avatar Dominik Inführ Committed by Commit Bot

Reland "[compiler, heap] Create LocalHeap outside of ExecuteJob"

This is a reland of 44708a5b

Original change's description:
> [compiler, heap] Create LocalHeap outside of ExecuteJob
>
> Create LocalHeap directly in the Task or in GetOptimizedCodeNow and
> pass its reference as argument to ExecuteJob. This allows us to create
> LocalHeap differently for the main and background thread, e.g. by
> passing an additional argument to the constructor in the future.
> It will be required in the future anyways when the main thread will
> have its own LocalHeap/LocalIsolate.
>
> Extending the scope of LocalHeap, also made
> HandleBase::IsDereferenceAllowed more precise and uncovered two
> potential issues: heap accesses in
> OptimizingCompileDispatcher::CompileNext and PipelineImpl::AssembleCode
> with --code-comments.
>
> LocalHeap can now be created in the parked state. Also fixed a data
> race with LocalHeap's destructor publishing write barrier entries
> without holding the lock.
>
> Bug: v8:10315
> Change-Id: I9226972601a07b87108cd66efbbb6a0d118af58d
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2460818
> Commit-Queue: Georg Neis <neis@chromium.org>
> Reviewed-by: Leszek Swirski <leszeks@chromium.org>
> Reviewed-by: Santiago Aboy Solanes <solanes@chromium.org>
> Reviewed-by: Georg Neis <neis@chromium.org>
> Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#70521}

Bug: v8:10315
Change-Id: I4c459fd6dfb98d47fc9941c0dc6864bf5a1d2d3e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2474788Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarSantiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70560}
parent 812a16da
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "src/heap/heap-inl.h" #include "src/heap/heap-inl.h"
#include "src/heap/local-factory-inl.h" #include "src/heap/local-factory-inl.h"
#include "src/heap/local-heap-inl.h" #include "src/heap/local-heap-inl.h"
#include "src/heap/local-heap.h"
#include "src/init/bootstrapper.h" #include "src/init/bootstrapper.h"
#include "src/interpreter/interpreter.h" #include "src/interpreter/interpreter.h"
#include "src/logging/log-inl.h" #include "src/logging/log-inl.h"
...@@ -340,12 +341,13 @@ CompilationJob::Status OptimizedCompilationJob::PrepareJob(Isolate* isolate) { ...@@ -340,12 +341,13 @@ CompilationJob::Status OptimizedCompilationJob::PrepareJob(Isolate* isolate) {
} }
CompilationJob::Status OptimizedCompilationJob::ExecuteJob( CompilationJob::Status OptimizedCompilationJob::ExecuteJob(
RuntimeCallStats* stats) { RuntimeCallStats* stats, LocalIsolate* local_isolate) {
DisallowHeapAccess no_heap_access; DisallowHeapAccess no_heap_access;
// Delegate to the underlying implementation. // Delegate to the underlying implementation.
DCHECK_EQ(state(), State::kReadyToExecute); DCHECK_EQ(state(), State::kReadyToExecute);
ScopedTimer t(&time_taken_to_execute_); ScopedTimer t(&time_taken_to_execute_);
return UpdateState(ExecuteJobImpl(stats), State::kReadyToFinalize); return UpdateState(ExecuteJobImpl(stats, local_isolate),
State::kReadyToFinalize);
} }
CompilationJob::Status OptimizedCompilationJob::FinalizeJob(Isolate* isolate) { CompilationJob::Status OptimizedCompilationJob::FinalizeJob(Isolate* isolate) {
...@@ -951,10 +953,21 @@ bool GetOptimizedCodeNow(OptimizedCompilationJob* job, Isolate* isolate, ...@@ -951,10 +953,21 @@ bool GetOptimizedCodeNow(OptimizedCompilationJob* job, Isolate* isolate,
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.OptimizeNonConcurrent"); "V8.OptimizeNonConcurrent");
if (!PrepareJobWithHandleScope(job, isolate, compilation_info) || if (!PrepareJobWithHandleScope(job, isolate, compilation_info)) {
job->ExecuteJob(isolate->counters()->runtime_call_stats()) != CompilerTracer::TraceAbortedJob(isolate, compilation_info);
CompilationJob::SUCCEEDED || return false;
job->FinalizeJob(isolate) != CompilationJob::SUCCEEDED) { }
{
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) {
CompilerTracer::TraceAbortedJob(isolate, compilation_info); CompilerTracer::TraceAbortedJob(isolate, compilation_info);
return false; return false;
} }
...@@ -1560,6 +1573,7 @@ void BackgroundCompileTask::Run() { ...@@ -1560,6 +1573,7 @@ void BackgroundCompileTask::Run() {
DCHECK(info_->flags().is_toplevel()); DCHECK(info_->flags().is_toplevel());
LocalIsolate isolate(isolate_for_local_isolate_); LocalIsolate isolate(isolate_for_local_isolate_);
UnparkedScope unparked_scope(isolate.heap());
LocalHandleScope handle_scope(&isolate); LocalHandleScope handle_scope(&isolate);
info_->ast_value_factory()->Internalize(&isolate); info_->ast_value_factory()->Internalize(&isolate);
......
...@@ -332,7 +332,8 @@ class OptimizedCompilationJob : public CompilationJob { ...@@ -332,7 +332,8 @@ class OptimizedCompilationJob : public CompilationJob {
// Executes the compile job. Can be called on a background thread if // Executes the compile job. Can be called on a background thread if
// can_execute_on_background_thread() returns true. // can_execute_on_background_thread() returns true.
V8_WARN_UNUSED_RESULT Status ExecuteJob(RuntimeCallStats* stats); V8_WARN_UNUSED_RESULT Status
ExecuteJob(RuntimeCallStats* stats, LocalIsolate* local_isolate = nullptr);
// Finalizes the compile job. Must be called on the main thread. // Finalizes the compile job. Must be called on the main thread.
V8_WARN_UNUSED_RESULT Status FinalizeJob(Isolate* isolate); V8_WARN_UNUSED_RESULT Status FinalizeJob(Isolate* isolate);
...@@ -357,7 +358,8 @@ class OptimizedCompilationJob : public CompilationJob { ...@@ -357,7 +358,8 @@ class OptimizedCompilationJob : public CompilationJob {
protected: protected:
// Overridden by the actual implementation. // Overridden by the actual implementation.
virtual Status PrepareJobImpl(Isolate* isolate) = 0; virtual Status PrepareJobImpl(Isolate* isolate) = 0;
virtual Status ExecuteJobImpl(RuntimeCallStats* stats) = 0; virtual Status ExecuteJobImpl(RuntimeCallStats* stats,
LocalIsolate* local_heap) = 0;
virtual Status FinalizeJobImpl(Isolate* isolate) = 0; virtual Status FinalizeJobImpl(Isolate* isolate) = 0;
private: private:
......
...@@ -302,11 +302,8 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final { ...@@ -302,11 +302,8 @@ class V8_EXPORT_PRIVATE OptimizedCompilationInfo final {
// 1) PersistentHandles created via PersistentHandlesScope inside of // 1) PersistentHandles created via PersistentHandlesScope inside of
// CompilationHandleScope // CompilationHandleScope
// 2) Owned by OptimizedCompilationInfo // 2) Owned by OptimizedCompilationInfo
// 3) Owned by JSHeapBroker // 3) Owned by the broker's LocalHeap when entering the LocalHeapScope.
// 4) Owned by the broker's LocalHeap // 4) Back to OptimizedCompilationInfo when exiting the LocalHeapScope.
// 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. // In normal execution it gets destroyed when PipelineData gets destroyed.
// There is a special case in GenerateCodeForTesting where the JSHeapBroker // There is a special case in GenerateCodeForTesting where the JSHeapBroker
......
...@@ -8,6 +8,8 @@ ...@@ -8,6 +8,8 @@
#include "src/codegen/compiler.h" #include "src/codegen/compiler.h"
#include "src/codegen/optimized-compilation-info.h" #include "src/codegen/optimized-compilation-info.h"
#include "src/execution/isolate.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/init/v8.h"
#include "src/logging/counters.h" #include "src/logging/counters.h"
#include "src/logging/log.h" #include "src/logging/log.h"
...@@ -56,6 +58,7 @@ class OptimizingCompileDispatcher::CompileTask : public CancelableTask { ...@@ -56,6 +58,7 @@ class OptimizingCompileDispatcher::CompileTask : public CancelableTask {
private: private:
// v8::Task overrides. // v8::Task overrides.
void RunInternal() override { void RunInternal() override {
LocalIsolate local_isolate(isolate_);
DisallowHeapAllocation no_allocation; DisallowHeapAllocation no_allocation;
DisallowHandleAllocation no_handles; DisallowHandleAllocation no_handles;
DisallowHandleDereference no_deref; DisallowHandleDereference no_deref;
...@@ -76,8 +79,8 @@ class OptimizingCompileDispatcher::CompileTask : public CancelableTask { ...@@ -76,8 +79,8 @@ class OptimizingCompileDispatcher::CompileTask : public CancelableTask {
dispatcher_->recompilation_delay_)); dispatcher_->recompilation_delay_));
} }
dispatcher_->CompileNext(dispatcher_->NextInput(true), dispatcher_->CompileNext(dispatcher_->NextInput(&local_isolate, true),
runtime_call_stats_scope.Get()); runtime_call_stats_scope.Get(), &local_isolate);
} }
{ {
base::MutexGuard lock_guard(&dispatcher_->ref_count_mutex_); base::MutexGuard lock_guard(&dispatcher_->ref_count_mutex_);
...@@ -106,7 +109,7 @@ OptimizingCompileDispatcher::~OptimizingCompileDispatcher() { ...@@ -106,7 +109,7 @@ OptimizingCompileDispatcher::~OptimizingCompileDispatcher() {
} }
OptimizedCompilationJob* OptimizingCompileDispatcher::NextInput( OptimizedCompilationJob* OptimizingCompileDispatcher::NextInput(
bool check_if_flushing) { LocalIsolate* local_isolate, bool check_if_flushing) {
base::MutexGuard access_input_queue_(&input_queue_mutex_); base::MutexGuard access_input_queue_(&input_queue_mutex_);
if (input_queue_length_ == 0) return nullptr; if (input_queue_length_ == 0) return nullptr;
OptimizedCompilationJob* job = input_queue_[InputQueueIndex(0)]; OptimizedCompilationJob* job = input_queue_[InputQueueIndex(0)];
...@@ -115,6 +118,7 @@ OptimizedCompilationJob* OptimizingCompileDispatcher::NextInput( ...@@ -115,6 +118,7 @@ OptimizedCompilationJob* OptimizingCompileDispatcher::NextInput(
input_queue_length_--; input_queue_length_--;
if (check_if_flushing) { if (check_if_flushing) {
if (mode_ == FLUSH) { if (mode_ == FLUSH) {
UnparkedScope scope(local_isolate->heap());
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
DisposeCompilationJob(job, true); DisposeCompilationJob(job, true);
return nullptr; return nullptr;
...@@ -124,11 +128,12 @@ OptimizedCompilationJob* OptimizingCompileDispatcher::NextInput( ...@@ -124,11 +128,12 @@ OptimizedCompilationJob* OptimizingCompileDispatcher::NextInput(
} }
void OptimizingCompileDispatcher::CompileNext(OptimizedCompilationJob* job, void OptimizingCompileDispatcher::CompileNext(OptimizedCompilationJob* job,
RuntimeCallStats* stats) { RuntimeCallStats* stats,
LocalIsolate* local_isolate) {
if (!job) return; if (!job) return;
// The function may have already been optimized by OSR. Simply continue. // The function may have already been optimized by OSR. Simply continue.
CompilationJob::Status status = job->ExecuteJob(stats); CompilationJob::Status status = job->ExecuteJob(stats, local_isolate);
USE(status); // Prevent an unused-variable error. USE(status); // Prevent an unused-variable error.
{ {
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
namespace v8 { namespace v8 {
namespace internal { namespace internal {
class LocalHeap;
class OptimizedCompilationJob; class OptimizedCompilationJob;
class RuntimeCallStats; class RuntimeCallStats;
class SharedFunctionInfo; class SharedFunctionInfo;
...@@ -58,8 +59,10 @@ class V8_EXPORT_PRIVATE OptimizingCompileDispatcher { ...@@ -58,8 +59,10 @@ class V8_EXPORT_PRIVATE OptimizingCompileDispatcher {
enum ModeFlag { COMPILE, FLUSH }; enum ModeFlag { COMPILE, FLUSH };
void FlushOutputQueue(bool restore_function_code); void FlushOutputQueue(bool restore_function_code);
void CompileNext(OptimizedCompilationJob* job, RuntimeCallStats* stats); void CompileNext(OptimizedCompilationJob* job, RuntimeCallStats* stats,
OptimizedCompilationJob* NextInput(bool check_if_flushing = false); LocalIsolate* local_isolate);
OptimizedCompilationJob* NextInput(LocalIsolate* local_isolate,
bool check_if_flushing = false);
inline int InputQueueIndex(int i) { inline int InputQueueIndex(int i) {
int result = (i + input_queue_shift_) % input_queue_capacity_; int result = (i + input_queue_shift_) % input_queue_capacity_;
......
...@@ -2427,7 +2427,6 @@ JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone, ...@@ -2427,7 +2427,6 @@ JSHeapBroker::JSHeapBroker(Isolate* isolate, Zone* broker_zone,
tracing_enabled_(tracing_enabled), tracing_enabled_(tracing_enabled),
is_concurrent_inlining_(is_concurrent_inlining), is_concurrent_inlining_(is_concurrent_inlining),
code_kind_(code_kind), code_kind_(code_kind),
local_heap_(base::nullopt),
feedback_(zone()), feedback_(zone()),
bytecode_analyses_(zone()), bytecode_analyses_(zone()),
property_access_infos_(zone()), property_access_infos_(zone()),
...@@ -2472,20 +2471,23 @@ std::string JSHeapBroker::Trace() const { ...@@ -2472,20 +2471,23 @@ std::string JSHeapBroker::Trace() const {
return oss.str(); return oss.str();
} }
void JSHeapBroker::InitializeLocalHeap(OptimizedCompilationInfo* info) { void JSHeapBroker::InitializeLocalHeap(OptimizedCompilationInfo* info,
set_persistent_handles(info->DetachPersistentHandles()); LocalHeap* local_heap) {
set_canonical_handles(info->DetachCanonicalHandles()); set_canonical_handles(info->DetachCanonicalHandles());
DCHECK(!local_heap_); DCHECK_NULL(local_heap_);
local_heap_.emplace(isolate_->heap(), std::move(ph_)); local_heap_ = local_heap;
DCHECK_NOT_NULL(local_heap_);
local_heap_->AttachPersistentHandles(info->DetachPersistentHandles());
} }
void JSHeapBroker::TearDownLocalHeap(OptimizedCompilationInfo* info) { void JSHeapBroker::TearDownLocalHeap(OptimizedCompilationInfo* info) {
DCHECK_NULL(ph_); DCHECK_NULL(ph_);
DCHECK(local_heap_); DCHECK(local_heap_);
ph_ = local_heap_->DetachPersistentHandles(); std::unique_ptr<PersistentHandles> ph =
local_heap_.reset(); local_heap_->DetachPersistentHandles();
local_heap_ = nullptr;
info->set_canonical_handles(DetachCanonicalHandles()); info->set_canonical_handles(DetachCanonicalHandles());
info->set_persistent_handles(DetachPersistentHandles()); info->set_persistent_handles(std::move(ph));
} }
void JSHeapBroker::StopSerializing() { void JSHeapBroker::StopSerializing() {
......
...@@ -117,7 +117,8 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -117,7 +117,8 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
BrokerMode mode() const { return mode_; } BrokerMode mode() const { return mode_; }
// Initialize the local heap with the persistent and canonical handles // Initialize the local heap with the persistent and canonical handles
// provided by {info}. // provided by {info}.
void InitializeLocalHeap(OptimizedCompilationInfo* info); void InitializeLocalHeap(OptimizedCompilationInfo* info,
LocalHeap* local_heap);
// Tear down the local heap and pass the persistent and canonical handles // Tear down the local heap and pass the persistent and canonical handles
// provided back to {info}. {info} is responsible for disposing of them. // provided back to {info}. {info} is responsible for disposing of them.
void TearDownLocalHeap(OptimizedCompilationInfo* info); void TearDownLocalHeap(OptimizedCompilationInfo* info);
...@@ -227,9 +228,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -227,9 +228,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
bool IsSerializedForCompilation(const SharedFunctionInfoRef& shared, bool IsSerializedForCompilation(const SharedFunctionInfoRef& shared,
const FeedbackVectorRef& feedback) const; const FeedbackVectorRef& feedback) const;
LocalHeap* local_heap() { LocalHeap* local_heap() { return local_heap_; }
return local_heap_.has_value() ? &(*local_heap_) : nullptr;
}
// Return the corresponding canonical persistent handle for {object}. Create // Return the corresponding canonical persistent handle for {object}. Create
// one if it does not exist. // one if it does not exist.
...@@ -361,7 +360,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker { ...@@ -361,7 +360,7 @@ class V8_EXPORT_PRIVATE JSHeapBroker {
bool const is_concurrent_inlining_; bool const is_concurrent_inlining_;
CodeKind const code_kind_; CodeKind const code_kind_;
std::unique_ptr<PersistentHandles> ph_; std::unique_ptr<PersistentHandles> ph_;
base::Optional<LocalHeap> local_heap_; LocalHeap* local_heap_ = nullptr;
std::unique_ptr<CanonicalHandlesMap> canonical_handles_; std::unique_ptr<CanonicalHandlesMap> canonical_handles_;
unsigned trace_indentation_ = 0; unsigned trace_indentation_ = 0;
PerIsolateCompilerCache* compiler_cache_ = nullptr; PerIsolateCompilerCache* compiler_cache_ = nullptr;
...@@ -453,14 +452,16 @@ class OffHeapBytecodeArray final : public interpreter::AbstractBytecodeArray { ...@@ -453,14 +452,16 @@ class OffHeapBytecodeArray final : public interpreter::AbstractBytecodeArray {
// Scope that unparks the LocalHeap, if: // Scope that unparks the LocalHeap, if:
// a) We have a JSHeapBroker, // a) We have a JSHeapBroker,
// b) Said JSHeapBroker has a LocalHeap, and // b) Said JSHeapBroker has a LocalHeap,
// c) Said LocalHeap has been parked. // c) Said LocalHeap has been parked and
// d) The given condition evaluates to true.
// Used, for example, when printing the graph with --trace-turbo with a // Used, for example, when printing the graph with --trace-turbo with a
// previously parked LocalHeap. // previously parked LocalHeap.
class UnparkedScopeIfNeeded { class UnparkedScopeIfNeeded {
public: public:
explicit UnparkedScopeIfNeeded(JSHeapBroker* broker) { explicit UnparkedScopeIfNeeded(JSHeapBroker* broker,
if (broker != nullptr) { bool extra_condition = true) {
if (broker != nullptr && extra_condition) {
LocalHeap* local_heap = broker->local_heap(); LocalHeap* local_heap = broker->local_heap();
if (local_heap != nullptr && local_heap->IsParked()) { if (local_heap != nullptr && local_heap->IsParked()) {
unparked_scope.emplace(local_heap); unparked_scope.emplace(local_heap);
......
...@@ -83,6 +83,7 @@ ...@@ -83,6 +83,7 @@
#include "src/diagnostics/code-tracer.h" #include "src/diagnostics/code-tracer.h"
#include "src/diagnostics/disassembler.h" #include "src/diagnostics/disassembler.h"
#include "src/execution/isolate-inl.h" #include "src/execution/isolate-inl.h"
#include "src/heap/local-heap.h"
#include "src/init/bootstrapper.h" #include "src/init/bootstrapper.h"
#include "src/logging/counters.h" #include "src/logging/counters.h"
#include "src/objects/shared-function-info.h" #include "src/objects/shared-function-info.h"
...@@ -765,12 +766,14 @@ class PipelineRunScope { ...@@ -765,12 +766,14 @@ class PipelineRunScope {
RuntimeCallTimerScope runtime_call_timer_scope; RuntimeCallTimerScope runtime_call_timer_scope;
}; };
// LocalHeapScope encapsulates the liveness of the brokers's LocalHeap. // LocalHeapScope encapsulates the phase where persistent handles are attached
// to the LocalHeap.
class LocalHeapScope { class LocalHeapScope {
public: public:
explicit LocalHeapScope(JSHeapBroker* broker, OptimizedCompilationInfo* info) explicit LocalHeapScope(JSHeapBroker* broker, OptimizedCompilationInfo* info,
LocalHeap* local_heap)
: broker_(broker), info_(info) { : broker_(broker), info_(info) {
broker_->InitializeLocalHeap(info_); broker_->InitializeLocalHeap(info_, local_heap);
info_->tick_counter().AttachLocalHeap(broker_->local_heap()); info_->tick_counter().AttachLocalHeap(broker_->local_heap());
} }
...@@ -1030,7 +1033,8 @@ class PipelineCompilationJob final : public OptimizedCompilationJob { ...@@ -1030,7 +1033,8 @@ class PipelineCompilationJob final : public OptimizedCompilationJob {
protected: protected:
Status PrepareJobImpl(Isolate* isolate) final; Status PrepareJobImpl(Isolate* isolate) final;
Status ExecuteJobImpl(RuntimeCallStats* stats) final; Status ExecuteJobImpl(RuntimeCallStats* stats,
LocalIsolate* local_isolate) final;
Status FinalizeJobImpl(Isolate* isolate) final; Status FinalizeJobImpl(Isolate* isolate) final;
// Registers weak object to optimized code dependencies. // Registers weak object to optimized code dependencies.
...@@ -1177,30 +1181,28 @@ PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl( ...@@ -1177,30 +1181,28 @@ PipelineCompilationJob::Status PipelineCompilationJob::PrepareJobImpl(
} }
PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl( PipelineCompilationJob::Status PipelineCompilationJob::ExecuteJobImpl(
RuntimeCallStats* stats) { RuntimeCallStats* stats, LocalIsolate* local_isolate) {
// Ensure that the RuntimeCallStats table is only available during execution // Ensure that the RuntimeCallStats table is only available during execution
// and not during finalization as that might be on a different thread. // and not during finalization as that might be on a different thread.
PipelineJobScope scope(&data_, stats); PipelineJobScope scope(&data_, stats);
{ LocalHeapScope local_heap_scope(data_.broker(), data_.info(),
LocalHeapScope local_heap_scope(data_.broker(), data_.info()); local_isolate->heap());
if (data_.broker()->is_concurrent_inlining()) {
if (!pipeline_.CreateGraph()) {
return AbortOptimization(BailoutReason::kGraphBuildingFailed);
}
}
// We selectively Unpark inside OptimizeGraph*. if (data_.broker()->is_concurrent_inlining()) {
ParkedScope parked_scope(data_.broker()->local_heap()); if (!pipeline_.CreateGraph()) {
return AbortOptimization(BailoutReason::kGraphBuildingFailed);
bool success;
if (compilation_info_.code_kind() == CodeKind::TURBOPROP) {
success = pipeline_.OptimizeGraphForMidTier(linkage_);
} else {
success = pipeline_.OptimizeGraph(linkage_);
} }
if (!success) return FAILED;
} }
// We selectively Unpark inside OptimizeGraph*.
bool success;
if (compilation_info_.code_kind() == CodeKind::TURBOPROP) {
success = pipeline_.OptimizeGraphForMidTier(linkage_);
} else {
success = pipeline_.OptimizeGraph(linkage_);
}
if (!success) return FAILED;
pipeline_.AssembleCode(linkage_); pipeline_.AssembleCode(linkage_);
return SUCCEEDED; return SUCCEEDED;
...@@ -1283,7 +1285,8 @@ class WasmHeapStubCompilationJob final : public OptimizedCompilationJob { ...@@ -1283,7 +1285,8 @@ class WasmHeapStubCompilationJob final : public OptimizedCompilationJob {
protected: protected:
Status PrepareJobImpl(Isolate* isolate) final; Status PrepareJobImpl(Isolate* isolate) final;
Status ExecuteJobImpl(RuntimeCallStats* stats) final; Status ExecuteJobImpl(RuntimeCallStats* stats,
LocalIsolate* local_isolate) final;
Status FinalizeJobImpl(Isolate* isolate) final; Status FinalizeJobImpl(Isolate* isolate) final;
private: private:
...@@ -1318,7 +1321,7 @@ CompilationJob::Status WasmHeapStubCompilationJob::PrepareJobImpl( ...@@ -1318,7 +1321,7 @@ CompilationJob::Status WasmHeapStubCompilationJob::PrepareJobImpl(
} }
CompilationJob::Status WasmHeapStubCompilationJob::ExecuteJobImpl( CompilationJob::Status WasmHeapStubCompilationJob::ExecuteJobImpl(
RuntimeCallStats* stats) { RuntimeCallStats* stats, LocalIsolate* local_isolate) {
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(
...@@ -2471,6 +2474,7 @@ void PipelineImpl::Serialize() { ...@@ -2471,6 +2474,7 @@ void PipelineImpl::Serialize() {
bool PipelineImpl::CreateGraph() { bool PipelineImpl::CreateGraph() {
PipelineData* data = this->data_; PipelineData* data = this->data_;
UnparkedScopeIfNeeded unparked_scope(data->broker());
data->BeginPhaseKind("V8.TFGraphCreation"); data->BeginPhaseKind("V8.TFGraphCreation");
...@@ -3022,13 +3026,15 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting( ...@@ -3022,13 +3026,15 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
} }
{ {
LocalHeapScope local_heap_scope(data.broker(), info); LocalIsolate local_isolate(isolate);
LocalHeapScope local_heap_scope(data.broker(), info, local_isolate.heap());
if (data.broker()->is_concurrent_inlining()) { if (data.broker()->is_concurrent_inlining()) {
if (!pipeline.CreateGraph()) return MaybeHandle<Code>(); if (!pipeline.CreateGraph()) return MaybeHandle<Code>();
} }
// We selectively Unpark inside OptimizeGraph. // We selectively Unpark inside OptimizeGraph.
ParkedScope parked_scope(data.broker()->local_heap());
if (!pipeline.OptimizeGraph(&linkage)) return MaybeHandle<Code>(); if (!pipeline.OptimizeGraph(&linkage)) return MaybeHandle<Code>();
pipeline.AssembleCode(&linkage);
} }
const bool will_retire_broker = out_broker == nullptr; const bool will_retire_broker = out_broker == nullptr;
...@@ -3040,7 +3046,6 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting( ...@@ -3040,7 +3046,6 @@ MaybeHandle<Code> Pipeline::GenerateCodeForTesting(
info->DetachPersistentHandles(), info->DetachCanonicalHandles()); info->DetachPersistentHandles(), info->DetachCanonicalHandles());
} }
pipeline.AssembleCode(&linkage);
Handle<Code> code; Handle<Code> code;
if (pipeline.FinalizeCode(will_retire_broker).ToHandle(&code) && if (pipeline.FinalizeCode(will_retire_broker).ToHandle(&code) &&
pipeline.CommitDependencies(code)) { pipeline.CommitDependencies(code)) {
...@@ -3478,6 +3483,8 @@ void PipelineImpl::AssembleCode(Linkage* linkage, ...@@ -3478,6 +3483,8 @@ void PipelineImpl::AssembleCode(Linkage* linkage,
data->BeginPhaseKind("V8.TFCodeGeneration"); data->BeginPhaseKind("V8.TFCodeGeneration");
data->InitializeCodeGenerator(linkage, std::move(buffer)); data->InitializeCodeGenerator(linkage, std::move(buffer));
UnparkedScopeIfNeeded unparked_scope(data->broker(), FLAG_code_comments);
Run<AssembleCodePhase>(); Run<AssembleCodePhase>();
if (data->info()->trace_turbo_json()) { if (data->info()->trace_turbo_json()) {
TurboJsonFile json_of(data->info(), std::ios_base::app); TurboJsonFile json_of(data->info(), std::ios_base::app);
......
...@@ -7657,7 +7657,7 @@ Handle<Code> CompileCWasmEntry(Isolate* isolate, const wasm::FunctionSig* sig, ...@@ -7657,7 +7657,7 @@ Handle<Code> CompileCWasmEntry(Isolate* isolate, const wasm::FunctionSig* sig,
CodeKind::C_WASM_ENTRY, std::move(name_buffer), CodeKind::C_WASM_ENTRY, std::move(name_buffer),
AssemblerOptions::Default(isolate))); AssemblerOptions::Default(isolate)));
CHECK_NE(job->ExecuteJob(isolate->counters()->runtime_call_stats()), CHECK_NE(job->ExecuteJob(isolate->counters()->runtime_call_stats(), nullptr),
CompilationJob::FAILED); CompilationJob::FAILED);
CHECK_NE(job->FinalizeJob(isolate), CompilationJob::FAILED); CHECK_NE(job->FinalizeJob(isolate), CompilationJob::FAILED);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/handles/persistent-handles.h" #include "src/handles/persistent-handles.h"
#include "src/heap/concurrent-allocator-inl.h" #include "src/heap/concurrent-allocator-inl.h"
#include "src/heap/local-heap-inl.h" #include "src/heap/local-heap-inl.h"
#include "src/heap/local-heap.h"
#include "src/heap/marking.h" #include "src/heap/marking.h"
#include "src/heap/memory-chunk.h" #include "src/heap/memory-chunk.h"
...@@ -18,6 +19,7 @@ namespace internal { ...@@ -18,6 +19,7 @@ namespace internal {
void StressConcurrentAllocatorTask::RunInternal() { void StressConcurrentAllocatorTask::RunInternal() {
Heap* heap = isolate_->heap(); Heap* heap = isolate_->heap();
LocalHeap local_heap(heap); LocalHeap local_heap(heap);
UnparkedScope unparked_scope(&local_heap);
const int kNumIterations = 2000; const int kNumIterations = 2000;
const int kSmallObjectSize = 10 * kTaggedSize; const int kSmallObjectSize = 10 * kTaggedSize;
......
...@@ -27,7 +27,7 @@ LocalHeap* LocalHeap::Current() { return current_local_heap; } ...@@ -27,7 +27,7 @@ LocalHeap* LocalHeap::Current() { return current_local_heap; }
LocalHeap::LocalHeap(Heap* heap, LocalHeap::LocalHeap(Heap* heap,
std::unique_ptr<PersistentHandles> persistent_handles) std::unique_ptr<PersistentHandles> persistent_handles)
: heap_(heap), : heap_(heap),
state_(ThreadState::Running), state_(ThreadState::Parked),
safepoint_requested_(false), safepoint_requested_(false),
allocation_failed_(false), allocation_failed_(false),
prev_(nullptr), prev_(nullptr),
...@@ -36,34 +36,35 @@ LocalHeap::LocalHeap(Heap* heap, ...@@ -36,34 +36,35 @@ LocalHeap::LocalHeap(Heap* heap,
persistent_handles_(std::move(persistent_handles)), persistent_handles_(std::move(persistent_handles)),
marking_barrier_(new MarkingBarrier(this)), marking_barrier_(new MarkingBarrier(this)),
old_space_allocator_(this, heap->old_space()) { old_space_allocator_(this, heap->old_space()) {
heap_->safepoint()->AddLocalHeap(this); 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());
}
}
});
if (persistent_handles_) { if (persistent_handles_) {
persistent_handles_->Attach(this); persistent_handles_->Attach(this);
} }
DCHECK_NULL(current_local_heap); DCHECK_NULL(current_local_heap);
current_local_heap = this; 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() { 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. // Park thread since removing the local heap could block.
EnsureParkedBeforeDestruction(); EnsureParkedBeforeDestruction();
heap_->safepoint()->RemoveLocalHeap(this); heap_->safepoint()->RemoveLocalHeap(this, [this] {
old_space_allocator_.FreeLinearAllocationArea();
if (FLAG_local_heaps) {
marking_barrier_->Publish();
WriteBarrier::ClearForThread(marking_barrier_.get());
}
});
DCHECK_EQ(current_local_heap, this); DCHECK_EQ(current_local_heap, this);
current_local_heap = nullptr; current_local_heap = nullptr;
...@@ -77,6 +78,13 @@ void LocalHeap::EnsurePersistentHandles() { ...@@ -77,6 +78,13 @@ void LocalHeap::EnsurePersistentHandles() {
} }
} }
void LocalHeap::AttachPersistentHandles(
std::unique_ptr<PersistentHandles> persistent_handles) {
DCHECK_NULL(persistent_handles_);
persistent_handles_ = std::move(persistent_handles);
persistent_handles_->Attach(this);
}
std::unique_ptr<PersistentHandles> LocalHeap::DetachPersistentHandles() { std::unique_ptr<PersistentHandles> LocalHeap::DetachPersistentHandles() {
if (persistent_handles_) persistent_handles_->Detach(); if (persistent_handles_) persistent_handles_->Detach();
return std::move(persistent_handles_); return std::move(persistent_handles_);
...@@ -116,6 +124,7 @@ void LocalHeap::Unpark() { ...@@ -116,6 +124,7 @@ void LocalHeap::Unpark() {
} }
void LocalHeap::EnsureParkedBeforeDestruction() { void LocalHeap::EnsureParkedBeforeDestruction() {
if (IsParked()) return;
base::MutexGuard guard(&state_mutex_); base::MutexGuard guard(&state_mutex_);
state_ = ThreadState::Parked; state_ = ThreadState::Parked;
state_change_.NotifyAll(); state_change_.NotifyAll();
......
...@@ -22,6 +22,15 @@ class Heap; ...@@ -22,6 +22,15 @@ class Heap;
class Safepoint; class Safepoint;
class LocalHandles; 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 { class V8_EXPORT_PRIVATE LocalHeap {
public: public:
explicit LocalHeap( explicit LocalHeap(
...@@ -70,6 +79,8 @@ class V8_EXPORT_PRIVATE LocalHeap { ...@@ -70,6 +79,8 @@ class V8_EXPORT_PRIVATE LocalHeap {
return kNullMaybeHandle; return kNullMaybeHandle;
} }
void AttachPersistentHandles(
std::unique_ptr<PersistentHandles> persistent_handles);
std::unique_ptr<PersistentHandles> DetachPersistentHandles(); std::unique_ptr<PersistentHandles> DetachPersistentHandles();
#ifdef DEBUG #ifdef DEBUG
bool ContainsPersistentHandle(Address* location); bool ContainsPersistentHandle(Address* location);
......
...@@ -114,23 +114,6 @@ SafepointScope::SafepointScope(Heap* heap) : safepoint_(heap->safepoint()) { ...@@ -114,23 +114,6 @@ SafepointScope::SafepointScope(Heap* heap) : safepoint_(heap->safepoint()) {
SafepointScope::~SafepointScope() { safepoint_->LeaveSafepointScope(); } 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) { bool GlobalSafepoint::ContainsLocalHeap(LocalHeap* local_heap) {
base::MutexGuard guard(&local_heaps_mutex_); base::MutexGuard guard(&local_heaps_mutex_);
LocalHeap* current = local_heaps_head_; LocalHeap* current = local_heaps_head_;
......
...@@ -62,8 +62,36 @@ class GlobalSafepoint { ...@@ -62,8 +62,36 @@ class GlobalSafepoint {
void EnterSafepointScope(); void EnterSafepointScope();
void LeaveSafepointScope(); void LeaveSafepointScope();
void AddLocalHeap(LocalHeap* local_heap); template <typename Callback>
void RemoveLocalHeap(LocalHeap* local_heap); 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 <typename Callback>
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_;
}
Barrier barrier_; Barrier barrier_;
Heap* heap_; Heap* heap_;
......
...@@ -52,6 +52,7 @@ class ConcurrentAllocationThread final : public v8::base::Thread { ...@@ -52,6 +52,7 @@ class ConcurrentAllocationThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_); LocalHeap local_heap(heap_);
UnparkedScope unparked_scope(&local_heap);
for (int i = 0; i < kNumIterations; i++) { for (int i = 0; i < kNumIterations; i++) {
Address address = local_heap.AllocateRawOrFail( Address address = local_heap.AllocateRawOrFail(
...@@ -119,6 +120,7 @@ class LargeObjectConcurrentAllocationThread final : public v8::base::Thread { ...@@ -119,6 +120,7 @@ class LargeObjectConcurrentAllocationThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_); LocalHeap local_heap(heap_);
UnparkedScope unparked_scope(&local_heap);
const size_t kLargeObjectSize = kMaxRegularHeapObjectSize * 2; const size_t kLargeObjectSize = kMaxRegularHeapObjectSize * 2;
for (int i = 0; i < kNumIterations; i++) { for (int i = 0; i < kNumIterations; i++) {
...@@ -186,6 +188,7 @@ class ConcurrentBlackAllocationThread final : public v8::base::Thread { ...@@ -186,6 +188,7 @@ class ConcurrentBlackAllocationThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_); LocalHeap local_heap(heap_);
UnparkedScope unparked_scope(&local_heap);
for (int i = 0; i < kNumIterations; i++) { for (int i = 0; i < kNumIterations; i++) {
if (i == kWhiteIterations) { if (i == kWhiteIterations) {
...@@ -265,6 +268,7 @@ class ConcurrentWriteBarrierThread final : public v8::base::Thread { ...@@ -265,6 +268,7 @@ class ConcurrentWriteBarrierThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_); LocalHeap local_heap(heap_);
UnparkedScope unparked_scope(&local_heap);
fixed_array_.set(0, value_); fixed_array_.set(0, value_);
} }
...@@ -326,6 +330,7 @@ class ConcurrentRecordRelocSlotThread final : public v8::base::Thread { ...@@ -326,6 +330,7 @@ class ConcurrentRecordRelocSlotThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_); LocalHeap local_heap(heap_);
UnparkedScope unparked_scope(&local_heap);
int mode_mask = RelocInfo::EmbeddedObjectModeMask(); int mode_mask = RelocInfo::EmbeddedObjectModeMask();
for (RelocIterator it(code_, mode_mask); !it.done(); it.next()) { for (RelocIterator it(code_, mode_mask); !it.done(); it.next()) {
DCHECK(RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode())); DCHECK(RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode()));
......
...@@ -7184,6 +7184,7 @@ TEST(GarbageCollectionWithLocalHeap) { ...@@ -7184,6 +7184,7 @@ TEST(GarbageCollectionWithLocalHeap) {
Heap* heap = CcTest::i_isolate()->heap(); Heap* heap = CcTest::i_isolate()->heap();
LocalHeap local_heap(heap); LocalHeap local_heap(heap);
UnparkedScope unparked_scope(&local_heap);
CcTest::CollectGarbage(OLD_SPACE); CcTest::CollectGarbage(OLD_SPACE);
{ ParkedScope parked_scope(&local_heap); } { ParkedScope parked_scope(&local_heap); }
CcTest::CollectGarbage(OLD_SPACE); CcTest::CollectGarbage(OLD_SPACE);
......
...@@ -34,6 +34,7 @@ class ConcurrentSearchThread final : public v8::base::Thread { ...@@ -34,6 +34,7 @@ class ConcurrentSearchThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_, std::move(ph_)); LocalHeap local_heap(heap_, std::move(ph_));
UnparkedScope unparked_scope(&local_heap);
LocalHandleScope scope(&local_heap); LocalHandleScope scope(&local_heap);
for (int i = 0; i < kNumHandles; i++) { for (int i = 0; i < kNumHandles; i++) {
......
...@@ -33,6 +33,7 @@ class ConcurrentSearchThread final : public v8::base::Thread { ...@@ -33,6 +33,7 @@ class ConcurrentSearchThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_, std::move(ph_)); LocalHeap local_heap(heap_, std::move(ph_));
UnparkedScope unparked_scope(&local_heap);
LocalHandleScope scope(&local_heap); LocalHandleScope scope(&local_heap);
for (int i = 0; i < kNumHandles; i++) { for (int i = 0; i < kNumHandles; i++) {
......
...@@ -35,6 +35,7 @@ class ScriptContextTableAccessUsedThread final : public v8::base::Thread { ...@@ -35,6 +35,7 @@ class ScriptContextTableAccessUsedThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_, std::move(ph_)); LocalHeap local_heap(heap_, std::move(ph_));
UnparkedScope unparked_scope(&local_heap);
LocalHandleScope scope(&local_heap); LocalHandleScope scope(&local_heap);
sema_started_->Signal(); sema_started_->Signal();
...@@ -67,6 +68,7 @@ class AccessScriptContextTableThread final : public v8::base::Thread { ...@@ -67,6 +68,7 @@ class AccessScriptContextTableThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_, std::move(ph_)); LocalHeap local_heap(heap_, std::move(ph_));
UnparkedScope unparked_scope(&local_heap);
LocalHandleScope scope(&local_heap); LocalHandleScope scope(&local_heap);
sema_started_->Signal(); sema_started_->Signal();
......
...@@ -35,6 +35,7 @@ class ConcurrentSearchThread : public v8::base::Thread { ...@@ -35,6 +35,7 @@ class ConcurrentSearchThread : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_, std::move(ph_)); LocalHeap local_heap(heap_, std::move(ph_));
UnparkedScope scope(&local_heap);
background_thread_started_->Signal(); background_thread_started_->Signal();
...@@ -70,6 +71,7 @@ class ConcurrentSearchOnOutdatedAccessorThread final ...@@ -70,6 +71,7 @@ class ConcurrentSearchOnOutdatedAccessorThread final
void Run() override { void Run() override {
LocalHeap local_heap(heap_, std::move(ph_)); LocalHeap local_heap(heap_, std::move(ph_));
UnparkedScope scope(&local_heap);
TransitionsAccessor accessor(CcTest::i_isolate(), map_, true); TransitionsAccessor accessor(CcTest::i_isolate(), map_, true);
background_thread_started_->Signal(); background_thread_started_->Signal();
......
...@@ -36,6 +36,7 @@ class LocalHandlesThread final : public v8::base::Thread { ...@@ -36,6 +36,7 @@ class LocalHandlesThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_); LocalHeap local_heap(heap_);
UnparkedScope unparked_scope(&local_heap);
LocalHandleScope scope(&local_heap); LocalHandleScope scope(&local_heap);
static constexpr int kNumHandles = static constexpr int kNumHandles =
...@@ -103,6 +104,7 @@ TEST(CreateLocalHandlesWithoutLocalHandleScope) { ...@@ -103,6 +104,7 @@ TEST(CreateLocalHandlesWithoutLocalHandleScope) {
{ {
LocalHeap local_heap(isolate->heap()); LocalHeap local_heap(isolate->heap());
UnparkedScope scope(&local_heap);
handle(Smi::FromInt(17), &local_heap); handle(Smi::FromInt(17), &local_heap);
} }
} }
...@@ -123,6 +125,7 @@ TEST(DereferenceLocalHandle) { ...@@ -123,6 +125,7 @@ TEST(DereferenceLocalHandle) {
} }
{ {
LocalHeap local_heap(isolate->heap(), std::move(phs)); LocalHeap local_heap(isolate->heap(), std::move(phs));
UnparkedScope unparked_scope(&local_heap);
LocalHandleScope scope(&local_heap); LocalHandleScope scope(&local_heap);
Handle<HeapNumber> local_number = handle(*ph, &local_heap); Handle<HeapNumber> local_number = handle(*ph, &local_heap);
CHECK_EQ(42, local_number->value()); CHECK_EQ(42, local_number->value());
......
...@@ -42,6 +42,7 @@ class PersistentHandlesThread final : public v8::base::Thread { ...@@ -42,6 +42,7 @@ class PersistentHandlesThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_, std::move(ph_)); LocalHeap local_heap(heap_, std::move(ph_));
UnparkedScope unparked_scope(&local_heap);
LocalHandleScope scope(&local_heap); LocalHandleScope scope(&local_heap);
for (int i = 0; i < kNumHandles; i++) { for (int i = 0; i < kNumHandles; i++) {
...@@ -129,6 +130,7 @@ TEST(DereferencePersistentHandle) { ...@@ -129,6 +130,7 @@ TEST(DereferencePersistentHandle) {
} }
{ {
LocalHeap local_heap(isolate->heap(), std::move(phs)); LocalHeap local_heap(isolate->heap(), std::move(phs));
UnparkedScope scope(&local_heap);
CHECK_EQ(42, ph->value()); CHECK_EQ(42, ph->value());
DisallowHandleDereference disallow_scope; DisallowHandleDereference disallow_scope;
CHECK_EQ(42, ph->value()); CHECK_EQ(42, ph->value());
...@@ -140,7 +142,6 @@ TEST(NewPersistentHandleFailsWhenParked) { ...@@ -140,7 +142,6 @@ TEST(NewPersistentHandleFailsWhenParked) {
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
LocalHeap local_heap(isolate->heap()); LocalHeap local_heap(isolate->heap());
ParkedScope scope(&local_heap);
// Fail here in debug mode: Persistent handles can't be created if local heap // Fail here in debug mode: Persistent handles can't be created if local heap
// is parked // is parked
local_heap.NewPersistentHandle(Smi::FromInt(1)); local_heap.NewPersistentHandle(Smi::FromInt(1));
...@@ -151,7 +152,6 @@ TEST(NewPersistentHandleFailsWhenParkedExplicit) { ...@@ -151,7 +152,6 @@ TEST(NewPersistentHandleFailsWhenParkedExplicit) {
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
LocalHeap local_heap(isolate->heap(), isolate->NewPersistentHandles()); 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 // Fail here in debug mode: Persistent handles can't be created if local heap
// is parked // is parked
local_heap.NewPersistentHandle(Smi::FromInt(1)); local_heap.NewPersistentHandle(Smi::FromInt(1));
......
...@@ -10,7 +10,9 @@ ...@@ -10,7 +10,9 @@
#include "src/codegen/compiler.h" #include "src/codegen/compiler.h"
#include "src/codegen/optimized-compilation-info.h" #include "src/codegen/optimized-compilation-info.h"
#include "src/execution/isolate.h" #include "src/execution/isolate.h"
#include "src/execution/local-isolate.h"
#include "src/handles/handles.h" #include "src/handles/handles.h"
#include "src/heap/local-heap.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "src/parsing/parse-info.h" #include "src/parsing/parse-info.h"
#include "test/unittests/test-helpers.h" #include "test/unittests/test-helpers.h"
...@@ -42,7 +44,8 @@ class BlockingCompilationJob : public OptimizedCompilationJob { ...@@ -42,7 +44,8 @@ class BlockingCompilationJob : public OptimizedCompilationJob {
// OptimiziedCompilationJob implementation. // OptimiziedCompilationJob implementation.
Status PrepareJobImpl(Isolate* isolate) override { UNREACHABLE(); } Status PrepareJobImpl(Isolate* isolate) override { UNREACHABLE(); }
Status ExecuteJobImpl(RuntimeCallStats* stats) override { Status ExecuteJobImpl(RuntimeCallStats* stats,
LocalIsolate* local_isolate) override {
blocking_.SetValue(true); blocking_.SetValue(true);
semaphore_.Wait(); semaphore_.Wait();
blocking_.SetValue(false); blocking_.SetValue(false);
......
...@@ -62,7 +62,8 @@ class LocalFactoryTest : public TestWithIsolateAndZone { ...@@ -62,7 +62,8 @@ class LocalFactoryTest : public TestWithIsolateAndZone {
isolate(), true, construct_language_mode(FLAG_use_strict), isolate(), true, construct_language_mode(FLAG_use_strict),
REPLMode::kNo), REPLMode::kNo),
&state_), &state_),
local_isolate_(isolate()) { local_isolate_(isolate()),
unparked_scope_(local_isolate_.heap()) {
FLAG_concurrent_allocation = true; FLAG_concurrent_allocation = true;
} }
...@@ -114,6 +115,7 @@ class LocalFactoryTest : public TestWithIsolateAndZone { ...@@ -114,6 +115,7 @@ class LocalFactoryTest : public TestWithIsolateAndZone {
UnoptimizedCompileState state_; UnoptimizedCompileState state_;
ParseInfo parse_info_; ParseInfo parse_info_;
LocalIsolate local_isolate_; LocalIsolate local_isolate_;
UnparkedScope unparked_scope_;
Handle<String> source_string_; Handle<String> source_string_;
Handle<Script> script_; Handle<Script> script_;
}; };
......
...@@ -43,7 +43,6 @@ class ParkedThread final : public v8::base::Thread { ...@@ -43,7 +43,6 @@ class ParkedThread final : public v8::base::Thread {
LocalHeap local_heap(heap_); LocalHeap local_heap(heap_);
if (mutex_) { if (mutex_) {
ParkedScope scope(&local_heap);
base::MutexGuard guard(mutex_); base::MutexGuard guard(mutex_);
} }
} }
...@@ -100,6 +99,7 @@ class RunningThread final : public v8::base::Thread { ...@@ -100,6 +99,7 @@ class RunningThread final : public v8::base::Thread {
void Run() override { void Run() override {
LocalHeap local_heap(heap_); LocalHeap local_heap(heap_);
UnparkedScope unparked_scope(&local_heap);
for (int i = 0; i < kRuns; i++) { for (int i = 0; i < kRuns; i++) {
counter_->fetch_add(1); counter_->fetch_add(1);
...@@ -148,6 +148,7 @@ TEST_F(SafepointTest, SkipLocalHeapOfThisThread) { ...@@ -148,6 +148,7 @@ TEST_F(SafepointTest, SkipLocalHeapOfThisThread) {
EnsureFlagLocalHeapsEnabled(); EnsureFlagLocalHeapsEnabled();
Heap* heap = i_isolate()->heap(); Heap* heap = i_isolate()->heap();
LocalHeap local_heap(heap); LocalHeap local_heap(heap);
UnparkedScope unparked_scope(&local_heap);
{ {
SafepointScope scope(heap); SafepointScope scope(heap);
local_heap.Safepoint(); local_heap.Safepoint();
......
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