diff --git a/src/isolate.cc b/src/isolate.cc index 1b7baa01ae..8f2fa4aa09 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -46,6 +46,7 @@ int ThreadId::AllocateThreadId() { int ThreadId::GetCurrentThreadId() { + Isolate::EnsureInitialized(); int thread_id = base::Thread::GetThreadLocalInt(Isolate::thread_id_key_); if (thread_id == 0) { thread_id = AllocateThreadId(); @@ -104,24 +105,17 @@ base::Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; #ifdef DEBUG base::Thread::LocalStorageKey PerThreadAssertScopeBase::thread_local_key; #endif // DEBUG -base::Mutex Isolate::process_wide_mutex_; -// TODO(dcarney): Remove with default isolate. -enum DefaultIsolateStatus { - kDefaultIsolateUninitialized, - kDefaultIsolateInitialized, - kDefaultIsolateCrashIfInitialized -}; -static DefaultIsolateStatus default_isolate_status_ - = kDefaultIsolateUninitialized; +base::LazyMutex Isolate::process_wide_mutex_ = LAZY_MUTEX_INITIALIZER; Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL; base::Atomic32 Isolate::isolate_counter_ = 0; Isolate::PerIsolateThreadData* Isolate::FindOrAllocatePerThreadDataForThisThread() { + EnsureInitialized(); ThreadId thread_id = ThreadId::Current(); PerIsolateThreadData* per_thread = NULL; { - base::LockGuard lock_guard(&process_wide_mutex_); + base::LockGuard lock_guard(process_wide_mutex_.Pointer()); per_thread = thread_data_table_->Lookup(this, thread_id); if (per_thread == NULL) { per_thread = new PerIsolateThreadData(this, thread_id); @@ -141,25 +135,18 @@ Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() { Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThread( ThreadId thread_id) { + EnsureInitialized(); PerIsolateThreadData* per_thread = NULL; { - base::LockGuard lock_guard(&process_wide_mutex_); + base::LockGuard lock_guard(process_wide_mutex_.Pointer()); per_thread = thread_data_table_->Lookup(this, thread_id); } return per_thread; } -void Isolate::SetCrashIfDefaultIsolateInitialized() { - base::LockGuard lock_guard(&process_wide_mutex_); - CHECK(default_isolate_status_ != kDefaultIsolateInitialized); - default_isolate_status_ = kDefaultIsolateCrashIfInitialized; -} - - -void Isolate::EnsureDefaultIsolate() { - base::LockGuard lock_guard(&process_wide_mutex_); - CHECK(default_isolate_status_ != kDefaultIsolateCrashIfInitialized); +void Isolate::EnsureInitialized() { + base::LockGuard lock_guard(process_wide_mutex_.Pointer()); if (thread_data_table_ == NULL) { isolate_key_ = base::Thread::CreateThreadLocalKey(); thread_id_key_ = base::Thread::CreateThreadLocalKey(); @@ -172,12 +159,6 @@ void Isolate::EnsureDefaultIsolate() { } } -struct StaticInitializer { - StaticInitializer() { - Isolate::EnsureDefaultIsolate(); - } -} static_initializer; - Address Isolate::get_address_from_id(Isolate::AddressId id) { return isolate_addresses_[id]; @@ -1534,7 +1515,8 @@ void Isolate::TearDown() { Deinit(); - { base::LockGuard lock_guard(&process_wide_mutex_); + { + base::LockGuard lock_guard(process_wide_mutex_.Pointer()); thread_data_table_->RemoveAllThreads(this); } @@ -1635,6 +1617,7 @@ void Isolate::PushToPartialSnapshotCache(Object* obj) { void Isolate::SetIsolateThreadLocals(Isolate* isolate, PerIsolateThreadData* data) { + EnsureInitialized(); base::Thread::SetThreadLocal(isolate_key_, isolate); base::Thread::SetThreadLocal(per_isolate_thread_data_key_, data); } diff --git a/src/isolate.h b/src/isolate.h index 175b1379e9..4fc2fb4f6d 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -448,12 +448,14 @@ class Isolate { // Returns the PerIsolateThreadData for the current thread (or NULL if one is // not currently set). static PerIsolateThreadData* CurrentPerIsolateThreadData() { + EnsureInitialized(); return reinterpret_cast( base::Thread::GetThreadLocal(per_isolate_thread_data_key_)); } // Returns the isolate inside which the current thread is running. INLINE(static Isolate* Current()) { + EnsureInitialized(); Isolate* isolate = reinterpret_cast( base::Thread::GetExistingThreadLocal(isolate_key_)); ASSERT(isolate != NULL); @@ -461,6 +463,17 @@ class Isolate { } INLINE(static Isolate* UncheckedCurrent()) { + EnsureInitialized(); + return reinterpret_cast( + base::Thread::GetThreadLocal(isolate_key_)); + } + + // Like UncheckCurrent, but returns NULL if called reentrantly during + // initialization. + INLINE(static Isolate* UncheckedReentrantCurrent()) { + if (!process_wide_mutex_.Pointer()->TryLock()) return NULL; + process_wide_mutex_.Pointer()->Unlock(); + EnsureInitialized(); return reinterpret_cast( base::Thread::GetThreadLocal(isolate_key_)); } @@ -486,13 +499,6 @@ class Isolate { static void GlobalTearDown(); - static void SetCrashIfDefaultIsolateInitialized(); - // Ensures that process-wide resources and the default isolate have been - // allocated. It is only necessary to call this method in rare cases, for - // example if you are using V8 from within the body of a static initializer. - // Safe to call multiple times. - static void EnsureDefaultIsolate(); - // Find the PerThread for this particular (isolate, thread) combination // If one does not yet exist, return null. PerIsolateThreadData* FindPerThreadDataForThisThread(); @@ -505,11 +511,13 @@ class Isolate { // Used internally for V8 threads that do not execute JavaScript but still // are part of the domain of an isolate (like the context switcher). static base::Thread::LocalStorageKey isolate_key() { + EnsureInitialized(); return isolate_key_; } // Returns the key used to store process-wide thread IDs. static base::Thread::LocalStorageKey thread_id_key() { + EnsureInitialized(); return thread_id_key_; } @@ -1090,6 +1098,8 @@ class Isolate { void CountUsage(v8::Isolate::UseCounterFeature feature); private: + static void EnsureInitialized(); + Isolate(); friend struct GlobalState; @@ -1149,7 +1159,7 @@ class Isolate { }; // This mutex protects highest_thread_id_ and thread_data_table_. - static base::Mutex process_wide_mutex_; + static base::LazyMutex process_wide_mutex_; static base::Thread::LocalStorageKey per_isolate_thread_data_key_; static base::Thread::LocalStorageKey isolate_key_; diff --git a/src/mksnapshot.cc b/src/mksnapshot.cc index 69306e14dc..9099398cef 100644 --- a/src/mksnapshot.cc +++ b/src/mksnapshot.cc @@ -317,7 +317,6 @@ void DumpException(Handle message) { int main(int argc, char** argv) { V8::InitializeICU(); - i::Isolate::SetCrashIfDefaultIsolateInitialized(); i::CpuFeatures::Probe(true); // By default, log code create information in the snapshot. diff --git a/src/sampler.cc b/src/sampler.cc index 7ee7216c2f..0ed4b37962 100644 --- a/src/sampler.cc +++ b/src/sampler.cc @@ -331,7 +331,7 @@ void SignalHandler::HandleProfilerSignal(int signal, siginfo_t* info, #else USE(info); if (signal != SIGPROF) return; - Isolate* isolate = Isolate::UncheckedCurrent(); + Isolate* isolate = Isolate::UncheckedReentrantCurrent(); if (isolate == NULL || !isolate->IsInitialized() || !isolate->IsInUse()) { // We require a fully initialized and entered isolate. return; diff --git a/test/cctest/cctest.cc b/test/cctest/cctest.cc index 0be152064e..f51f7e4b5a 100644 --- a/test/cctest/cctest.cc +++ b/test/cctest/cctest.cc @@ -138,7 +138,6 @@ static void SuggestTestHarness(int tests) { int main(int argc, char* argv[]) { v8::V8::InitializeICU(); - i::Isolate::SetCrashIfDefaultIsolateInitialized(); v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true); diff --git a/tools/check-static-initializers.sh b/tools/check-static-initializers.sh index 11ba080d5a..da43170f6e 100755 --- a/tools/check-static-initializers.sh +++ b/tools/check-static-initializers.sh @@ -32,8 +32,7 @@ # Allow: # - _GLOBAL__I__ZN2v810LineEditor6first_E # - _GLOBAL__I__ZN2v88internal32AtomicOps_Internalx86CPUFeaturesE -# - _GLOBAL__I__ZN2v88internal8ThreadId18highest_thread_id_E -expected_static_init_count=3 +expected_static_init_count=2 v8_root=$(readlink -f $(dirname $BASH_SOURCE)/../)