Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Unified Diff: src/v8threads.cc

Issue 6788023: Per-isolate v8::Locker and v8::Unlocker (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: New tests for IsLocker Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/v8threads.cc
diff --git a/src/v8threads.cc b/src/v8threads.cc
index 4b033fcf0bd703cf12b5bdccfb116784b5a31d9a..0f73338b765c641c64c9ed390f17a82d6d495e0e 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -44,89 +44,109 @@ 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.
+Locker::Locker()
+ : has_lock_(false), top_level_(true),
Vitaly Repeshko 2011/04/15 00:29:39 nit: Reformat with one initializer per line if the
Dmitry Lomov 2011/04/19 01:50:47 Done.
+ isolate_(internal::Isolate::GetDefaultIsolateForLocking()) {
+ // We pull default isolate for Locker constructor w/o parameter.
// 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);
+ ASSERT(isolate_ != NULL);
+ Init();
+}
+
Vitaly Repeshko 2011/04/15 00:29:39 nit: Two blank lines.
Dmitry Lomov 2011/04/19 01:50:47 Done.
+Locker::Locker(v8::Isolate* isolate)
+ : has_lock_(false), top_level_(false),
+ isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
+ ASSERT(isolate_ != NULL);
+ Init();
+}
+void Locker::Init() {
// Record that the Locker has been used at least once.
active_ = true;
+
+ isolate_->EnsurePreinitializedForThisThread();
// 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_->IsDefaultIsolate()) {
+ // This only enters if not yet entered.
+ internal::Isolate::EnterDefaultIsolate();
+ } else if (!isolate_->IsInitialized()) {
+ isolate_->Enter();
V8::Initialize();
Vitaly Repeshko 2011/04/15 00:29:39 I really don't like that we're doing a global init
Dmitry Lomov 2011/04/19 01:50:47 Done.
+ 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() {
- return internal::Isolate::Current()->thread_manager()->
- IsLockedByCurrentThread();
+ return IsLocked(reinterpret_cast<v8::Isolate*>(
+ i::Isolate::GetDefaultIsolateForLocking()));
+}
+
+bool Locker::IsLocked(v8::Isolate* isolate) {
+ i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ internal_isolate->EnsurePreinitializedForThisThread();
+ 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 (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() : isolate_(i::Isolate::GetDefaultIsolateForLocking()) {
+ Init();
+}
+
+Unlocker::Unlocker(v8::Isolate* isolate)
+ : isolate_(reinterpret_cast<i::Isolate*>(isolate)) {
+ Init();
+}
+
+
+void Unlocker::Init() {
+ ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread());
+ 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();
}
@@ -143,18 +163,22 @@ void Locker::StopPreemption() {
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;
}
@@ -164,11 +188,11 @@ bool ThreadManager::RestoreThread() {
// If there is another thread that was lazily archived then we have to really
// archive it now.
- if (lazily_archived_thread_.IsValid()) {
+ if (!lazily_archived_thread_.Equals(ThreadId::Invalid())) {
Vitaly Repeshko 2011/04/15 00:29:39 Accidental edit? IsValid() should work.
Dmitry Lomov 2011/04/19 01:50:47 Done.
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 +202,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 +324,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 +339,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 +347,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 +372,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();

Powered by Google App Engine
This is Rietveld 408576698