Index: src/v8threads.cc |
diff --git a/src/v8threads.cc b/src/v8threads.cc |
index 4b033fcf0bd703cf12b5bdccfb116784b5a31d9a..26169b50be6c51c590737d003d3a924a14642d2d 100644 |
--- a/src/v8threads.cc |
+++ b/src/v8threads.cc |
@@ -43,90 +43,94 @@ bool Locker::active_ = false; |
// Constructor for the Locker object. Once the Locker is constructed the |
-// 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); |
- |
+// 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(); |
+ } |
// 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->IsInitialized()) { |
+ if (!isolate_->IsInitialized()) { |
+ isolate_->Enter(); |
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); |
+ } |
+ if (isolate_->IsDefaultIsolate()) { |
+ // This only enters if not yet entered. |
+ internal::Isolate::EnterDefaultIsolate(); |
} |
} |
- ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); |
+ ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread()); |
} |
-bool Locker::IsLocked() { |
- return internal::Isolate::Current()->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(); |
} |
Locker::~Locker() { |
- // TODO(isolate): this should use a field storing the isolate it |
- // locked instead. |
- internal::Isolate* isolate = internal::Isolate::Current(); |
- ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); |
+ ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread()); |
if (has_lock_) { |
+ if (isolate_->IsDefaultIsolate()) { |
+ isolate_->Exit(); |
+ } |
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() { |
- internal::Isolate* isolate = internal::Isolate::Current(); |
- ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); |
- isolate->thread_manager()->ArchiveThread(); |
- 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()); |
+ if (isolate_->IsDefaultIsolate()) { |
+ isolate_->Exit(); |
+ } |
+ isolate_->thread_manager()->ArchiveThread(); |
+ isolate_->thread_manager()->Unlock(); |
} |
Unlocker::~Unlocker() { |
- // 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(); |
+ ASSERT(!isolate_->thread_manager()->IsLockedByCurrentThread()); |
+ isolate_->thread_manager()->Lock(); |
+ isolate_->thread_manager()->RestoreThread(); |
+ if (isolate_->IsDefaultIsolate()) { |
+ isolate_->Enter(); |
+ } |
} |
@@ -144,17 +148,20 @@ 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(); |
- ASSERT(Isolate::CurrentPerIsolateThreadData()->thread_state() == |
- lazily_archived_thread_state_); |
+ Isolate::PerIsolateThreadData* per_thread = |
+ isolate_->FindPerThreadDataForThisThread(); |
+ ASSERT(per_thread != NULL); |
+ ASSERT(per_thread->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; |
- Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL); |
+ per_thread->set_thread_state(NULL); |
return true; |
} |
@@ -168,7 +175,7 @@ bool ThreadManager::RestoreThread() { |
EagerlyArchiveThread(); |
} |
Isolate::PerIsolateThreadData* per_thread = |
- Isolate::CurrentPerIsolateThreadData(); |
+ isolate_->FindPerThreadDataForThisThread(); |
if (per_thread == NULL || per_thread->thread_state() == NULL) { |
// This is a new thread. |
isolate_->stack_guard()->InitThread(access); |
@@ -178,7 +185,7 @@ bool ThreadManager::RestoreThread() { |
char* from = state->data(); |
from = isolate_->handle_scope_implementer()->RestoreThread(from); |
from = isolate_->RestoreThread(from); |
- from = Relocatable::RestoreState(from); |
+ from = Relocatable::RestoreState(isolate_, from); |
#ifdef ENABLE_DEBUGGER_SUPPORT |
from = isolate_->debug()->RestoreDebug(from); |
#endif |
@@ -300,9 +307,12 @@ ThreadManager::~ThreadManager() { |
void ThreadManager::ArchiveThread() { |
ASSERT(lazily_archived_thread_.Equals(ThreadId::Invalid())); |
ASSERT(!IsArchived()); |
+ ASSERT(IsLockedByCurrentThread()); |
ThreadState* state = GetFreeThreadState(); |
state->Unlink(); |
- Isolate::CurrentPerIsolateThreadData()->set_thread_state(state); |
+ Isolate::PerIsolateThreadData* per_thread = |
+ isolate_->FindOrAllocatePerThreadDataForThisThread(); |
+ per_thread->set_thread_state(state); |
lazily_archived_thread_ = ThreadId::Current(); |
lazily_archived_thread_state_ = state; |
ASSERT(state->id().Equals(ThreadId::Invalid())); |
@@ -312,6 +322,7 @@ void ThreadManager::ArchiveThread() { |
void ThreadManager::EagerlyArchiveThread() { |
+ ASSERT(IsLockedByCurrentThread()); |
ThreadState* state = lazily_archived_thread_state_; |
state->LinkInto(ThreadState::IN_USE_LIST); |
char* to = state->data(); |
@@ -319,7 +330,7 @@ void ThreadManager::EagerlyArchiveThread() { |
// in ThreadManager::Iterate(ObjectVisitor*). |
to = isolate_->handle_scope_implementer()->ArchiveThread(to); |
to = isolate_->ArchiveThread(to); |
- to = Relocatable::ArchiveState(to); |
+ to = Relocatable::ArchiveState(isolate_, to); |
#ifdef ENABLE_DEBUGGER_SUPPORT |
to = isolate_->debug()->ArchiveDebug(to); |
#endif |
@@ -344,11 +355,11 @@ void ThreadManager::FreeThreadResources() { |
bool ThreadManager::IsArchived() { |
- Isolate::PerIsolateThreadData* data = Isolate::CurrentPerIsolateThreadData(); |
+ Isolate::PerIsolateThreadData* data = |
+ isolate_->FindPerThreadDataForThisThread(); |
return data != NULL && data->thread_state() != NULL; |
} |
- |
void ThreadManager::Iterate(ObjectVisitor* v) { |
// Expecting no threads during serialization/deserialization |
for (ThreadState* state = FirstThreadStateInUse(); |