Index: src/v8threads.cc |
diff --git a/src/v8threads.cc b/src/v8threads.cc |
index e2879748029785c0ec5fa196356cceccbbc11cc6..4b033fcf0bd703cf12b5bdccfb116784b5a31d9a 100644 |
--- a/src/v8threads.cc |
+++ b/src/v8threads.cc |
@@ -43,85 +43,90 @@ bool Locker::active_ = false; |
// Constructor for the Locker object. Once the Locker is constructed the |
-// current thread will be guaranteed to have the lock for a given isolate. |
-Locker::Locker(v8::Isolate* isolate) |
- : has_lock_(false), |
- top_level_(false), |
- isolate_(reinterpret_cast<i::Isolate*>(isolate)) { |
- if (isolate_ == NULL) { |
- isolate_ = i::Isolate::GetDefaultIsolateForLocking(); |
- } |
+// current thread will be guaranteed to have the big V8 lock. |
+Locker::Locker() : has_lock_(false), top_level_(true) { |
+ // TODO(isolates): When Locker has Isolate parameter and it is provided, grab |
+ // that one instead of using the current one. |
+ // We pull default isolate for Locker constructor w/o p[arameter. |
+ // A thread should not enter an isolate before acquiring a lock, |
+ // in cases which mandate using Lockers. |
+ // So getting a lock is the first thing threads do in a scenario where |
+ // multple threads share an isolate. Hence, we need to access |
+ // 'locking isolate' before we can actually enter into default isolate. |
+ internal::Isolate* isolate = internal::Isolate::GetDefaultIsolateForLocking(); |
+ ASSERT(isolate != NULL); |
+ |
// Record that the Locker has been used at least once. |
active_ = true; |
// Get the big lock if necessary. |
- if (!isolate_->thread_manager()->IsLockedByCurrentThread()) { |
- isolate_->thread_manager()->Lock(); |
+ if (!isolate->thread_manager()->IsLockedByCurrentThread()) { |
+ isolate->thread_manager()->Lock(); |
has_lock_ = true; |
+ if (isolate->IsDefaultIsolate()) { |
+ // This only enters if not yet entered. |
+ internal::Isolate::EnterDefaultIsolate(); |
+ } |
+ |
+ ASSERT(internal::Thread::HasThreadLocal( |
+ internal::Isolate::thread_id_key())); |
+ |
// Make sure that V8 is initialized. Archiving of threads interferes |
// with deserialization by adding additional root pointers, so we must |
// initialize here, before anyone can call ~Locker() or Unlocker(). |
- if (isolate_->IsDefaultIsolate()) { |
- // This only enters if not yet entered. |
- internal::Isolate::EnterDefaultIsolate(); |
- } else if (!isolate_->IsInitialized()) { |
- isolate_->Enter(); |
+ if (!isolate->IsInitialized()) { |
V8::Initialize(); |
- isolate_->Exit(); |
} |
- |
// This may be a locker within an unlocker in which case we have to |
// get the saved state for this thread and restore it. |
- if (isolate_->thread_manager()->RestoreThread()) { |
+ if (isolate->thread_manager()->RestoreThread()) { |
top_level_ = false; |
} else { |
- internal::ExecutionAccess access(isolate_); |
- isolate_->stack_guard()->ClearThread(access); |
- isolate_->stack_guard()->InitThread(access); |
+ internal::ExecutionAccess access(isolate); |
+ isolate->stack_guard()->ClearThread(access); |
+ isolate->stack_guard()->InitThread(access); |
} |
} |
- ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread()); |
+ ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); |
} |
-bool Locker::IsLocked(v8::Isolate* isolate) { |
- i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); |
- if (internal_isolate == NULL) { |
- internal_isolate = i::Isolate::GetDefaultIsolateForLocking(); |
- } |
- return internal_isolate->thread_manager()->IsLockedByCurrentThread(); |
+bool Locker::IsLocked() { |
+ return internal::Isolate::Current()->thread_manager()-> |
+ IsLockedByCurrentThread(); |
} |
Locker::~Locker() { |
- ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread()); |
+ // TODO(isolate): this should use a field storing the isolate it |
+ // locked instead. |
+ internal::Isolate* isolate = internal::Isolate::Current(); |
+ ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); |
if (has_lock_) { |
if (top_level_) { |
- isolate_->thread_manager()->FreeThreadResources(); |
+ isolate->thread_manager()->FreeThreadResources(); |
} else { |
- isolate_->thread_manager()->ArchiveThread(); |
+ isolate->thread_manager()->ArchiveThread(); |
} |
- isolate_->thread_manager()->Unlock(); |
+ isolate->thread_manager()->Unlock(); |
} |
} |
-Unlocker::Unlocker(v8::Isolate* isolate) |
- : isolate_(reinterpret_cast<i::Isolate*>(isolate)) { |
- if (isolate_ == NULL) { |
- isolate_ = i::Isolate::GetDefaultIsolateForLocking(); |
- } |
- |
- ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread()); |
- isolate_->thread_manager()->ArchiveThread(); |
- isolate_->thread_manager()->Unlock(); |
+Unlocker::Unlocker() { |
+ internal::Isolate* isolate = internal::Isolate::Current(); |
+ ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); |
+ isolate->thread_manager()->ArchiveThread(); |
+ isolate->thread_manager()->Unlock(); |
} |
Unlocker::~Unlocker() { |
- ASSERT(!isolate_->thread_manager()->IsLockedByCurrentThread()); |
- isolate_->thread_manager()->Lock(); |
- isolate_->thread_manager()->RestoreThread(); |
+ // TODO(isolates): check it's the isolate we unlocked. |
+ internal::Isolate* isolate = internal::Isolate::Current(); |
+ ASSERT(!isolate->thread_manager()->IsLockedByCurrentThread()); |
+ isolate->thread_manager()->Lock(); |
+ isolate->thread_manager()->RestoreThread(); |
} |
@@ -139,20 +144,17 @@ namespace internal { |
bool ThreadManager::RestoreThread() { |
- ASSERT(IsLockedByCurrentThread()); |
// First check whether the current thread has been 'lazily archived', ie |
// not archived at all. If that is the case we put the state storage we |
// had prepared back in the free list, since we didn't need it after all. |
if (lazily_archived_thread_.Equals(ThreadId::Current())) { |
lazily_archived_thread_ = ThreadId::Invalid(); |
- Isolate::PerIsolateThreadData* per_thread = |
- isolate_->FindPerThreadDataForThisThread(); |
- ASSERT(per_thread != NULL); |
- ASSERT(per_thread->thread_state() == lazily_archived_thread_state_); |
+ ASSERT(Isolate::CurrentPerIsolateThreadData()->thread_state() == |
+ lazily_archived_thread_state_); |
lazily_archived_thread_state_->set_id(ThreadId::Invalid()); |
lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST); |
lazily_archived_thread_state_ = NULL; |
- per_thread->set_thread_state(NULL); |
+ Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL); |
return true; |
} |
@@ -166,7 +168,7 @@ bool ThreadManager::RestoreThread() { |
EagerlyArchiveThread(); |
} |
Isolate::PerIsolateThreadData* per_thread = |
- isolate_->FindPerThreadDataForThisThread(); |
+ Isolate::CurrentPerIsolateThreadData(); |
if (per_thread == NULL || per_thread->thread_state() == NULL) { |
// This is a new thread. |
isolate_->stack_guard()->InitThread(access); |
@@ -176,7 +178,7 @@ bool ThreadManager::RestoreThread() { |
char* from = state->data(); |
from = isolate_->handle_scope_implementer()->RestoreThread(from); |
from = isolate_->RestoreThread(from); |
- from = Relocatable::RestoreState(isolate_, from); |
+ from = Relocatable::RestoreState(from); |
#ifdef ENABLE_DEBUGGER_SUPPORT |
from = isolate_->debug()->RestoreDebug(from); |
#endif |
@@ -298,12 +300,9 @@ ThreadManager::~ThreadManager() { |
void ThreadManager::ArchiveThread() { |
ASSERT(lazily_archived_thread_.Equals(ThreadId::Invalid())); |
ASSERT(!IsArchived()); |
- ASSERT(IsLockedByCurrentThread()); |
ThreadState* state = GetFreeThreadState(); |
state->Unlink(); |
- Isolate::PerIsolateThreadData* per_thread = |
- isolate_->FindOrAllocatePerThreadDataForThisThread(); |
- per_thread->set_thread_state(state); |
+ Isolate::CurrentPerIsolateThreadData()->set_thread_state(state); |
lazily_archived_thread_ = ThreadId::Current(); |
lazily_archived_thread_state_ = state; |
ASSERT(state->id().Equals(ThreadId::Invalid())); |
@@ -313,7 +312,6 @@ void ThreadManager::ArchiveThread() { |
void ThreadManager::EagerlyArchiveThread() { |
- ASSERT(IsLockedByCurrentThread()); |
ThreadState* state = lazily_archived_thread_state_; |
state->LinkInto(ThreadState::IN_USE_LIST); |
char* to = state->data(); |
@@ -321,7 +319,7 @@ void ThreadManager::EagerlyArchiveThread() { |
// in ThreadManager::Iterate(ObjectVisitor*). |
to = isolate_->handle_scope_implementer()->ArchiveThread(to); |
to = isolate_->ArchiveThread(to); |
- to = Relocatable::ArchiveState(isolate_, to); |
+ to = Relocatable::ArchiveState(to); |
#ifdef ENABLE_DEBUGGER_SUPPORT |
to = isolate_->debug()->ArchiveDebug(to); |
#endif |
@@ -346,11 +344,11 @@ void ThreadManager::FreeThreadResources() { |
bool ThreadManager::IsArchived() { |
- Isolate::PerIsolateThreadData* data = |
- isolate_->FindPerThreadDataForThisThread(); |
+ Isolate::PerIsolateThreadData* data = Isolate::CurrentPerIsolateThreadData(); |
return data != NULL && data->thread_state() != NULL; |
} |
+ |
void ThreadManager::Iterate(ObjectVisitor* v) { |
// Expecting no threads during serialization/deserialization |
for (ThreadState* state = FirstThreadStateInUse(); |