Commit 8741040e authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[ptr-compr] Prepare Isolate for pointer-compression friendly creation/deletion

In order to ensure that Isolate::New()/Isolate::Delete() are the bottlenecks
this CL also makes the Isolate class final.

Bug: v8:8182
Change-Id: I6bb170363a1210f66d63f4bcc46ea06fb5000d50
Reviewed-on: https://chromium-review.googlesource.com/c/1301481
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57041}
parent 2690e2fc
......@@ -572,8 +572,8 @@ SnapshotCreator::SnapshotCreator(Isolate* isolate,
SnapshotCreator::SnapshotCreator(const intptr_t* external_references,
StartupData* existing_snapshot)
: SnapshotCreator(reinterpret_cast<Isolate*>(new i::Isolate()),
external_references, existing_snapshot) {}
: SnapshotCreator(Isolate::Allocate(), external_references,
existing_snapshot) {}
SnapshotCreator::~SnapshotCreator() {
SnapshotCreatorData* data = SnapshotCreatorData::cast(data_);
......@@ -8141,7 +8141,7 @@ Isolate* Isolate::GetCurrent() {
// static
Isolate* Isolate::Allocate() {
return reinterpret_cast<Isolate*>(new i::Isolate());
return reinterpret_cast<Isolate*>(i::Isolate::New());
}
// static
......@@ -8228,7 +8228,7 @@ void Isolate::Dispose() {
"Disposing the isolate that is entered by a thread.")) {
return;
}
isolate->TearDown();
i::Isolate::Delete(isolate);
}
void Isolate::DumpAndResetStats() {
......
......@@ -2645,6 +2645,42 @@ class VerboseAccountingAllocator : public AccountingAllocator {
std::atomic<size_t> Isolate::non_disposed_isolates_;
#endif // DEBUG
// static
Isolate* Isolate::New() {
Isolate* isolate = new Isolate();
#ifdef DEBUG
non_disposed_isolates_++;
#endif // DEBUG
return isolate;
}
// static
void Isolate::Delete(Isolate* isolate) {
DCHECK_NOT_NULL(isolate);
// Temporarily set this isolate as current so that various parts of
// the isolate can access it in their destructors without having a
// direct pointer. We don't use Enter/Exit here to avoid
// initializing the thread data.
PerIsolateThreadData* saved_data = isolate->CurrentPerIsolateThreadData();
DCHECK_EQ(base::Relaxed_Load(&isolate_key_created_), 1);
Isolate* saved_isolate = reinterpret_cast<Isolate*>(
base::Thread::GetThreadLocal(isolate->isolate_key_));
SetIsolateThreadLocals(isolate, nullptr);
isolate->Deinit();
#ifdef DEBUG
non_disposed_isolates_--;
#endif // DEBUG
delete isolate;
// Restore the previous current isolate.
SetIsolateThreadLocals(saved_isolate, saved_data);
}
Isolate::Isolate()
: entry_stack_(nullptr),
stack_trace_nesting_level_(0),
......@@ -2732,10 +2768,6 @@ Isolate::Isolate()
thread_manager_ = new ThreadManager();
thread_manager_->isolate_ = this;
#ifdef DEBUG
non_disposed_isolates_++;
#endif // DEBUG
handle_scope_data_.Initialize();
#define ISOLATE_INIT_EXECUTE(type, name, initial_value) \
......@@ -2785,42 +2817,6 @@ void Isolate::CheckIsolateLayout() {
Internals::kExternalMemoryAtLastMarkCompactOffset);
}
void Isolate::TearDown() {
TRACE_ISOLATE(tear_down);
tracing_cpu_profiler_.reset();
if (FLAG_stress_sampling_allocation_profiler > 0) {
heap_profiler()->StopSamplingHeapProfiler();
}
// Temporarily set this isolate as current so that various parts of
// the isolate can access it in their destructors without having a
// direct pointer. We don't use Enter/Exit here to avoid
// initializing the thread data.
PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData();
DCHECK_EQ(base::Relaxed_Load(&isolate_key_created_), 1);
Isolate* saved_isolate =
reinterpret_cast<Isolate*>(base::Thread::GetThreadLocal(isolate_key_));
SetIsolateThreadLocals(this, nullptr);
Deinit();
{
base::MutexGuard lock_guard(&thread_data_table_mutex_);
thread_data_table_.RemoveAllThreads();
}
#ifdef DEBUG
non_disposed_isolates_--;
#endif // DEBUG
delete this;
// Restore the previous current isolate.
SetIsolateThreadLocals(saved_isolate, saved_data);
}
void Isolate::ClearSerializerData() {
delete external_reference_map_;
external_reference_map_ = nullptr;
......@@ -2837,6 +2833,11 @@ bool Isolate::LogObjectRelocation() {
void Isolate::Deinit() {
TRACE_ISOLATE(deinit);
tracing_cpu_profiler_.reset();
if (FLAG_stress_sampling_allocation_profiler > 0) {
heap_profiler()->StopSamplingHeapProfiler();
}
debug()->Unload();
wasm_engine()->DeleteCompileJobsOnIsolate(this);
......@@ -2922,6 +2923,11 @@ void Isolate::Deinit() {
compiler_cache_ = nullptr;
ClearSerializerData();
{
base::MutexGuard lock_guard(&thread_data_table_mutex_);
thread_data_table_.RemoveAllThreads();
}
}
......
......@@ -554,14 +554,12 @@ typedef std::vector<HeapObject*> DebugObjectCache;
// Factory's members available to Isolate directly.
class V8_EXPORT_PRIVATE HiddenFactory : private Factory {};
class Isolate : private HiddenFactory {
class Isolate final : private HiddenFactory {
// These forward declarations are required to make the friend declarations in
// PerIsolateThreadData work on some older versions of gcc.
class ThreadDataTable;
class EntryStackItem;
public:
~Isolate();
// A thread has a PerIsolateThreadData instance for each isolate that it has
// entered. That instance is allocated when the isolate is initially entered
// and reused on subsequent entries.
......@@ -615,6 +613,16 @@ class Isolate : private HiddenFactory {
static void InitializeOncePerProcess();
// Creates Isolate object. Must be used instead of constructing Isolate with
// new operator.
static Isolate* New();
// Deletes Isolate object. Must be used instead of delete operator.
// Destroys the non-default isolates.
// Sets default isolate into "has_been_disposed" state rather then destroying,
// for legacy API reasons.
static void Delete(Isolate* isolate);
// Returns the PerIsolateThreadData for the current thread (or nullptr if one
// is not currently set).
static PerIsolateThreadData* CurrentPerIsolateThreadData() {
......@@ -649,17 +657,23 @@ class Isolate : private HiddenFactory {
// True if at least one thread Enter'ed this isolate.
bool IsInUse() { return entry_stack_ != nullptr; }
// Destroys the non-default isolates.
// Sets default isolate into "has_been_disposed" state rather then destroying,
// for legacy API reasons.
void TearDown();
void ReleaseSharedPtrs();
void ClearSerializerData();
bool LogObjectRelocation();
// Initializes the current thread to run this Isolate.
// Not thread-safe. Multiple threads should not Enter/Exit the same isolate
// at the same time, this should be prevented using external locking.
void Enter();
// Exits the current thread. The previosuly entered Isolate is restored
// for the thread.
// Not thread-safe. Multiple threads should not Enter/Exit the same isolate
// at the same time, this should be prevented using external locking.
void Exit();
// Find the PerThread for this particular (isolate, thread) combination
// If one does not yet exist, return null.
PerIsolateThreadData* FindPerThreadDataForThisThread();
......@@ -1260,6 +1274,8 @@ class Isolate : private HiddenFactory {
bool IsNoElementsProtectorIntact(Context* context);
bool IsNoElementsProtectorIntact();
bool IsArrayOrObjectOrStringPrototype(Object* object);
inline bool IsArraySpeciesLookupChainIntact();
inline bool IsTypedArraySpeciesLookupChainIntact();
inline bool IsPromiseSpeciesLookupChainIntact();
......@@ -1625,15 +1641,11 @@ class Isolate : private HiddenFactory {
void SetIdle(bool is_idle);
protected:
private:
Isolate();
~Isolate();
void CheckIsolateLayout();
bool IsArrayOrObjectOrStringPrototype(Object* object);
private:
friend struct GlobalState;
friend struct InitializeGlobalState;
class ThreadDataTable {
public:
......@@ -1699,17 +1711,6 @@ class Isolate : private HiddenFactory {
// If one does not yet exist, allocate a new one.
PerIsolateThreadData* FindOrAllocatePerThreadDataForThisThread();
// Initializes the current thread to run this Isolate.
// Not thread-safe. Multiple threads should not Enter/Exit the same isolate
// at the same time, this should be prevented using external locking.
void Enter();
// Exits the current thread. The previosuly entered Isolate is restored
// for the thread.
// Not thread-safe. Multiple threads should not Enter/Exit the same isolate
// at the same time, this should be prevented using external locking.
void Exit();
void InitializeThreadLocal();
void MarkCompactPrologue(bool is_compacting,
......@@ -1957,20 +1958,12 @@ class Isolate : private HiddenFactory {
base::Mutex thread_data_table_mutex_;
ThreadDataTable thread_data_table_;
friend class ExecutionAccess;
friend class HandleScopeImplementer;
friend class heap::HeapTester;
friend class OptimizingCompileDispatcher;
friend class Simulator;
friend class StackGuard;
friend class SweeperThread;
friend class TestIsolate;
friend class TestSerializer;
friend class ThreadId;
friend class ThreadManager;
friend class v8::Isolate;
friend class v8::Locker;
friend class v8::SnapshotCreator;
friend class v8::Unlocker;
DISALLOW_COPY_AND_ASSIGN(Isolate);
};
......
This diff is collapsed.
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