Reland^2 r22105 "Remove static initializer from isolate"
Make Isolate::UncheckedCurrent() return NULL if Isolate wasn't yet initialized to avoid reentrancy when running with the profiler BUG=none R=dcarney@chromium.org LOG=n Review URL: https://codereview.chromium.org/365863003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22167 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
44d6ef37ab
commit
d8aefde617
@ -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<base::Mutex> lock_guard(&process_wide_mutex_);
|
||||
base::LockGuard<base::Mutex> 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<base::Mutex> lock_guard(&process_wide_mutex_);
|
||||
base::LockGuard<base::Mutex> lock_guard(process_wide_mutex_.Pointer());
|
||||
per_thread = thread_data_table_->Lookup(this, thread_id);
|
||||
}
|
||||
return per_thread;
|
||||
}
|
||||
|
||||
|
||||
void Isolate::SetCrashIfDefaultIsolateInitialized() {
|
||||
base::LockGuard<base::Mutex> lock_guard(&process_wide_mutex_);
|
||||
CHECK(default_isolate_status_ != kDefaultIsolateInitialized);
|
||||
default_isolate_status_ = kDefaultIsolateCrashIfInitialized;
|
||||
}
|
||||
|
||||
|
||||
void Isolate::EnsureDefaultIsolate() {
|
||||
base::LockGuard<base::Mutex> lock_guard(&process_wide_mutex_);
|
||||
CHECK(default_isolate_status_ != kDefaultIsolateCrashIfInitialized);
|
||||
void Isolate::EnsureInitialized() {
|
||||
base::LockGuard<base::Mutex> 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<base::Mutex> lock_guard(&process_wide_mutex_);
|
||||
{
|
||||
base::LockGuard<base::Mutex> 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);
|
||||
}
|
||||
|
@ -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<PerIsolateThreadData*>(
|
||||
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<Isolate*>(
|
||||
base::Thread::GetExistingThreadLocal(isolate_key_));
|
||||
ASSERT(isolate != NULL);
|
||||
@ -461,6 +463,17 @@ class Isolate {
|
||||
}
|
||||
|
||||
INLINE(static Isolate* UncheckedCurrent()) {
|
||||
EnsureInitialized();
|
||||
return reinterpret_cast<Isolate*>(
|
||||
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<Isolate*>(
|
||||
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_;
|
||||
|
@ -317,7 +317,6 @@ void DumpException(Handle<Message> 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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)/../)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user