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

Unified Diff: src/v8threads.cc

Issue 435003: Patch for allowing several V8 instances in process:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years 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
« no previous file with comments | « src/v8threads.h ('k') | src/x64/assembler-x64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/v8threads.cc
===================================================================
--- src/v8threads.cc (revision 3427)
+++ src/v8threads.cc (working copy)
@@ -36,22 +36,13 @@
namespace v8 {
-static internal::Thread::LocalStorageKey thread_state_key =
- internal::Thread::CreateThreadLocalKey();
-static internal::Thread::LocalStorageKey thread_id_key =
- internal::Thread::CreateThreadLocalKey();
-
-
-// Track whether this V8 instance has ever called v8::Locker. This allows the
-// API code to verify that the lock is always held when V8 is being entered.
-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) {
+ internal::V8Context* const v8context = v8_context();
+
// Record that the Locker has been used at least once.
- active_ = true;
+ v8context->v8_data_.active_ = true;
// Get the big lock if necessary.
if (!internal::ThreadManager::IsLockedByCurrentThread()) {
internal::ThreadManager::Lock();
@@ -78,6 +69,9 @@
internal::ThreadManager::AssignId();
}
+bool Locker::IsActive() {
+ return v8_context()->v8_data_.active_;
+}
bool Locker::IsLocked() {
return internal::ThreadManager::IsLockedByCurrentThread();
@@ -125,17 +119,21 @@
bool ThreadManager::RestoreThread() {
+ ThreadManagerData& thread_manager_data = v8_context()->thread_manager_data_;
// 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_.IsSelf()) {
- lazily_archived_thread_.Initialize(ThreadHandle::INVALID);
- ASSERT(Thread::GetThreadLocal(thread_state_key) ==
- lazily_archived_thread_state_);
- lazily_archived_thread_state_->set_id(kInvalidId);
- lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST);
- lazily_archived_thread_state_ = NULL;
- Thread::SetThreadLocal(thread_state_key, NULL);
+ if (thread_manager_data.lazily_archived_thread_.IsSelf()) {
+ thread_manager_data.lazily_archived_thread_.Initialize(
+ ThreadHandle::INVALID);
+ ASSERT(Thread::GetThreadLocal(thread_manager_data.thread_state_key_) ==
+ thread_manager_data.lazily_archived_thread_state_);
+ thread_manager_data.lazily_archived_thread_state_->set_id(kInvalidId);
+ thread_manager_data.lazily_archived_thread_state_->LinkInto(
+ ThreadState::FREE_LIST);
+
+ thread_manager_data.lazily_archived_thread_state_ = NULL;
+ Thread::SetThreadLocal(thread_manager_data.thread_state_key_, NULL);
return true;
}
@@ -145,11 +143,11 @@
// If there is another thread that was lazily archived then we have to really
// archive it now.
- if (lazily_archived_thread_.IsValid()) {
+ if (thread_manager_data.lazily_archived_thread_.IsValid()) {
EagerlyArchiveThread();
}
- ThreadState* state =
- reinterpret_cast<ThreadState*>(Thread::GetThreadLocal(thread_state_key));
+ ThreadState* state = reinterpret_cast<ThreadState*>(
+ Thread::GetThreadLocal(thread_manager_data.thread_state_key_));
if (state == NULL) {
// This is a new thread.
StackGuard::InitThread(access);
@@ -165,7 +163,7 @@
from = StackGuard::RestoreStackGuard(from);
from = RegExpStack::RestoreStack(from);
from = Bootstrapper::RestoreState(from);
- Thread::SetThreadLocal(thread_state_key, NULL);
+ Thread::SetThreadLocal(thread_manager_data.thread_state_key_, NULL);
if (state->terminate_on_restore()) {
StackGuard::TerminateExecution();
state->set_terminate_on_restore(false);
@@ -178,15 +176,17 @@
void ThreadManager::Lock() {
- mutex_->Lock();
- mutex_owner_.Initialize(ThreadHandle::SELF);
+ v8_context()->thread_manager_data_.mutex_->Lock();
+ v8_context()->thread_manager_data_.mutex_owner_.Initialize(
+ ThreadHandle::SELF);
ASSERT(IsLockedByCurrentThread());
}
void ThreadManager::Unlock() {
- mutex_owner_.Initialize(ThreadHandle::INVALID);
- mutex_->Unlock();
+ v8_context()->thread_manager_data_.mutex_owner_.Initialize(
+ ThreadHandle::INVALID);
+ v8_context()->thread_manager_data_.mutex_->Unlock();
}
@@ -203,8 +203,6 @@
}
-ThreadState* ThreadState::free_anchor_ = new ThreadState();
-ThreadState* ThreadState::in_use_anchor_ = new ThreadState();
ThreadState::ThreadState() : id_(ThreadManager::kInvalidId),
@@ -225,8 +223,9 @@
void ThreadState::LinkInto(List list) {
- ThreadState* flying_anchor =
- list == FREE_LIST ? free_anchor_ : in_use_anchor_;
+ ThreadState* flying_anchor = list == FREE_LIST ?
+ v8_context()->thread_manager_data_.free_anchor_
+ : v8_context()->thread_manager_data_.in_use_anchor_;
next_ = flying_anchor->next_;
previous_ = flying_anchor;
flying_anchor->next_ = this;
@@ -235,8 +234,8 @@
ThreadState* ThreadState::GetFree() {
- ThreadState* gotten = free_anchor_->next_;
- if (gotten == free_anchor_) {
+ ThreadState* gotten = v8_context()->thread_manager_data_.free_anchor_->next_;
+ if (gotten == v8_context()->thread_manager_data_.free_anchor_) {
ThreadState* new_thread_state = new ThreadState();
new_thread_state->AllocateSpace();
return new_thread_state;
@@ -247,34 +246,43 @@
// Gets the first in the list of archived threads.
ThreadState* ThreadState::FirstInUse() {
- return in_use_anchor_->Next();
+ return v8_context()->thread_manager_data_.in_use_anchor_->Next();
}
ThreadState* ThreadState::Next() {
- if (next_ == in_use_anchor_) return NULL;
+ if (next_ == v8_context()->thread_manager_data_.in_use_anchor_) return NULL;
return next_;
}
+ThreadManagerData::ThreadManagerData()
// Thread ids must start with 1, because in TLS having thread id 0 can't
// be distinguished from not having a thread id at all (since NULL is
// defined as 0.)
-int ThreadManager::last_id_ = 0;
-Mutex* ThreadManager::mutex_ = OS::CreateMutex();
-ThreadHandle ThreadManager::mutex_owner_(ThreadHandle::INVALID);
-ThreadHandle ThreadManager::lazily_archived_thread_(ThreadHandle::INVALID);
-ThreadState* ThreadManager::lazily_archived_thread_state_ = NULL;
+ :last_id_(0),
+ mutex_(OS::CreateMutex()),
+ mutex_owner_(ThreadHandle::INVALID),
+ lazily_archived_thread_(ThreadHandle::INVALID),
+ lazily_archived_thread_state_(NULL),
+ free_anchor_(new ThreadState()),
+ in_use_anchor_(new ThreadState()),
+ singleton_(NULL),
+ thread_state_key_(Thread::CreateThreadLocalKey()),
+ thread_id_key_(Thread::CreateThreadLocalKey()) {
+}
-
void ThreadManager::ArchiveThread() {
- ASSERT(!lazily_archived_thread_.IsValid());
+ ThreadManagerData& thread_manager_data = v8_context()->thread_manager_data_;
+ ASSERT(!thread_manager_data.lazily_archived_thread_.IsValid());
ASSERT(!IsArchived());
ThreadState* state = ThreadState::GetFree();
state->Unlink();
- Thread::SetThreadLocal(thread_state_key, reinterpret_cast<void*>(state));
- lazily_archived_thread_.Initialize(ThreadHandle::SELF);
- lazily_archived_thread_state_ = state;
+ Thread::SetThreadLocal(thread_manager_data .thread_state_key_,
+ reinterpret_cast<void*>(state));
+
+ thread_manager_data.lazily_archived_thread_.Initialize(ThreadHandle::SELF);
+ thread_manager_data.lazily_archived_thread_state_ = state;
ASSERT(state->id() == kInvalidId);
state->set_id(CurrentId());
ASSERT(state->id() != kInvalidId);
@@ -282,7 +290,8 @@
void ThreadManager::EagerlyArchiveThread() {
- ThreadState* state = lazily_archived_thread_state_;
+ ThreadManagerData& thread_manager_data = v8_context()->thread_manager_data_;
+ ThreadState* state = thread_manager_data.lazily_archived_thread_state_;
state->LinkInto(ThreadState::IN_USE_LIST);
char* to = state->data();
// Ensure that data containing GC roots are archived first, and handle them
@@ -296,8 +305,8 @@
to = StackGuard::ArchiveStackGuard(to);
to = RegExpStack::ArchiveStack(to);
to = Bootstrapper::ArchiveState(to);
- lazily_archived_thread_.Initialize(ThreadHandle::INVALID);
- lazily_archived_thread_state_ = NULL;
+ thread_manager_data.lazily_archived_thread_.Initialize(ThreadHandle::INVALID);
+ thread_manager_data.lazily_archived_thread_state_ = NULL;
}
@@ -314,7 +323,8 @@
bool ThreadManager::IsArchived() {
- return Thread::HasThreadLocal(thread_state_key);
+ return Thread::HasThreadLocal(
+ v8_context()->thread_manager_data_.thread_state_key_);
}
@@ -354,23 +364,26 @@
int ThreadManager::CurrentId() {
- return Thread::GetThreadLocalInt(thread_id_key);
+ return Thread::GetThreadLocalInt(
+ v8_context()->thread_manager_data_.thread_id_key_);
}
void ThreadManager::AssignId() {
if (!HasId()) {
ASSERT(Locker::IsLocked());
- int thread_id = ++last_id_;
+ ThreadManagerData& thread_manager_data = v8_context()->thread_manager_data_;
+ int thread_id = ++thread_manager_data.last_id_;
ASSERT(thread_id > 0); // see the comment near last_id_ definition.
- Thread::SetThreadLocalInt(thread_id_key, thread_id);
+ Thread::SetThreadLocalInt(thread_manager_data.thread_id_key_, thread_id);
Top::set_thread_id(thread_id);
}
}
bool ThreadManager::HasId() {
- return Thread::HasThreadLocal(thread_id_key);
+ return Thread::HasThreadLocal(
+ v8_context()->thread_manager_data_.thread_id_key_);
}
@@ -384,12 +397,6 @@
}
}
-
-// This is the ContextSwitcher singleton. There is at most a single thread
-// running which delivers preemption events to V8 threads.
-ContextSwitcher* ContextSwitcher::singleton_ = NULL;
-
-
ContextSwitcher::ContextSwitcher(int every_n_ms)
: keep_going_(true),
sleep_ms_(every_n_ms) {
@@ -400,14 +407,15 @@
// ContextSwitcher thread if needed.
void ContextSwitcher::StartPreemption(int every_n_ms) {
ASSERT(Locker::IsLocked());
- if (singleton_ == NULL) {
+ ContextSwitcher* & singleton = v8_context()->thread_manager_data_.singleton_;
+ if (singleton == NULL) {
// If the ContextSwitcher thread is not running at the moment start it now.
- singleton_ = new ContextSwitcher(every_n_ms);
- singleton_->Start();
+ singleton = new ContextSwitcher(every_n_ms);
+ singleton->Start();
} else {
// ContextSwitcher thread is already running, so we just change the
// scheduling interval.
- singleton_->sleep_ms_ = every_n_ms;
+ singleton->sleep_ms_ = every_n_ms;
}
}
@@ -416,14 +424,15 @@
// must cooperatively schedule amongst them from this point on.
void ContextSwitcher::StopPreemption() {
ASSERT(Locker::IsLocked());
- if (singleton_ != NULL) {
+ ContextSwitcher* & singleton = v8_context()->thread_manager_data_.singleton_;
+ if (singleton != NULL) {
// The ContextSwitcher thread is running. We need to stop it and release
// its resources.
- singleton_->keep_going_ = false;
- singleton_->Join(); // Wait for the ContextSwitcher thread to exit.
+ singleton->keep_going_ = false;
+ singleton->Join(); // Wait for the ContextSwitcher thread to exit.
// Thread has exited, now we can delete it.
- delete(singleton_);
- singleton_ = NULL;
+ delete(singleton);
+ singleton = NULL;
}
}
« no previous file with comments | « src/v8threads.h ('k') | src/x64/assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698