1c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org// Copyright 2012 the V8 project authors. All rights reserved. 243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Redistribution and use in source and binary forms, with or without 343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// modification, are permitted provided that the following conditions are 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// met: 543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions of source code must retain the above copyright 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// notice, this list of conditions and the following disclaimer. 843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Redistributions in binary form must reproduce the above 943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// copyright notice, this list of conditions and the following 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// disclaimer in the documentation and/or other materials provided 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// with the distribution. 1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// * Neither the name of Google Inc. nor the names of its 1343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// contributors may be used to endorse or promote products derived 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// from this software without specific prior written permission. 1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// 1643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8.h" 2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "api.h" 31ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org#include "bootstrapper.h" 3243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "debug.h" 3343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "execution.h" 3443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "v8threads.h" 353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org#include "regexp-stack.h" 3643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 3743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansennamespace v8 { 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 39ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 40ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// Track whether this V8 instance has ever called v8::Locker. This allows the 41ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org// API code to verify that the lock is always held when V8 is being entered. 42ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.orgbool Locker::active_ = false; 43ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 44ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 4546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgLocker::Locker() { 4646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org Initialize(i::Isolate::GetDefaultIsolateForLocking()); 4746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org} 4846a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 4946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 5046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org// Once the Locker is initialized, the current thread will be guaranteed to have 5146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org// the lock for a given isolate. 5246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgvoid Locker::Initialize(v8::Isolate* isolate) { 5346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org ASSERT(isolate != NULL); 5446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org has_lock_= false; 5546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org top_level_ = true; 5646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org isolate_ = reinterpret_cast<i::Isolate*>(isolate); 57ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // Record that the Locker has been used at least once. 58ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org active_ = true; 5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Get the big lock if necessary. 601c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org if (!isolate_->thread_manager()->IsLockedByCurrentThread()) { 611c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->thread_manager()->Lock(); 6243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen has_lock_ = true; 63ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 64c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // Make sure that V8 is initialized. Archiving of threads interferes 65c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // with deserialization by adding additional root pointers, so we must 66c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // initialize here, before anyone can call ~Locker() or Unlocker(). 671c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org if (!isolate_->IsInitialized()) { 681c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->Enter(); 69c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org V8::Initialize(); 701c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->Exit(); 71c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } 721c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org 7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // This may be a locker within an unlocker in which case we have to 7443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // get the saved state for this thread and restore it. 751c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org if (isolate_->thread_manager()->RestoreThread()) { 7643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen top_level_ = false; 77c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } else { 781c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org internal::ExecutionAccess access(isolate_); 791c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->stack_guard()->ClearThread(access); 801c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->stack_guard()->InitThread(access); 811c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org } 821c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org if (isolate_->IsDefaultIsolate()) { 831c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org // This only enters if not yet entered. 841c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org internal::Isolate::EnterDefaultIsolate(); 8543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 871c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread()); 8843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 8943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 911c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.orgbool Locker::IsLocked(v8::Isolate* isolate) { 9246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org ASSERT(isolate != NULL); 931c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org i::Isolate* internal_isolate = reinterpret_cast<i::Isolate*>(isolate); 941c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org return internal_isolate->thread_manager()->IsLockedByCurrentThread(); 9543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 9643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 9743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 987c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.orgbool Locker::IsActive() { 997c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org return active_; 1007c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org} 1017c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 1027c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org 10343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenLocker::~Locker() { 1041c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread()); 10543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (has_lock_) { 1061c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org if (isolate_->IsDefaultIsolate()) { 1071c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->Exit(); 1081c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org } 109c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org if (top_level_) { 1101c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->thread_manager()->FreeThreadResources(); 111c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org } else { 1121c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->thread_manager()->ArchiveThread(); 11343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 1141c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->thread_manager()->Unlock(); 11543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 11643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 11743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 11946a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgUnlocker::Unlocker() { 12046a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org Initialize(i::Isolate::GetDefaultIsolateForLocking()); 12146a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org} 12246a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 12346a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org 12446a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.orgvoid Unlocker::Initialize(v8::Isolate* isolate) { 12546a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org ASSERT(isolate != NULL); 12646a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org isolate_ = reinterpret_cast<i::Isolate*>(isolate); 1271c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ASSERT(isolate_->thread_manager()->IsLockedByCurrentThread()); 1281c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org if (isolate_->IsDefaultIsolate()) { 1291c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->Exit(); 1301c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org } 1311c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->thread_manager()->ArchiveThread(); 1321c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->thread_manager()->Unlock(); 13343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 13443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 13643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenUnlocker::~Unlocker() { 1371c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ASSERT(!isolate_->thread_manager()->IsLockedByCurrentThread()); 1381c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->thread_manager()->Lock(); 1391c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->thread_manager()->RestoreThread(); 1401c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org if (isolate_->IsDefaultIsolate()) { 1411c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->Enter(); 1421c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org } 14343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 14443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 14543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 14643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Locker::StartPreemption(int every_n_ms) { 14743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen v8::internal::ContextSwitcher::StartPreemption(every_n_ms); 14843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 14943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid Locker::StopPreemption() { 15243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen v8::internal::ContextSwitcher::StopPreemption(); 15343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 15443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansennamespace internal { 15743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 15943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenbool ThreadManager::RestoreThread() { 1601c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ASSERT(IsLockedByCurrentThread()); 1612efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org // First check whether the current thread has been 'lazily archived', i.e. 16243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // not archived at all. If that is the case we put the state storage we 16343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // had prepared back in the free list, since we didn't need it after all. 164a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org if (lazily_archived_thread_.Equals(ThreadId::Current())) { 165a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org lazily_archived_thread_ = ThreadId::Invalid(); 1661c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Isolate::PerIsolateThreadData* per_thread = 1671c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->FindPerThreadDataForThisThread(); 1681c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ASSERT(per_thread != NULL); 1691c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ASSERT(per_thread->thread_state() == lazily_archived_thread_state_); 170a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org lazily_archived_thread_state_->set_id(ThreadId::Invalid()); 17143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST); 17243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen lazily_archived_thread_state_ = NULL; 1731c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org per_thread->set_thread_state(NULL); 17443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 17543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 176ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 177ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // Make sure that the preemption thread cannot modify the thread state while 178ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org // it is being archived or restored. 179ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ExecutionAccess access(isolate_); 180ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org 18143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // If there is another thread that was lazily archived then we have to really 18243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // archive it now. 18343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (lazily_archived_thread_.IsValid()) { 18443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen EagerlyArchiveThread(); 18543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 186ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate::PerIsolateThreadData* per_thread = 1871c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->FindPerThreadDataForThisThread(); 188ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (per_thread == NULL || per_thread->thread_state() == NULL) { 189c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org // This is a new thread. 190ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->stack_guard()->InitThread(access); 19143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return false; 19243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 193ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ThreadState* state = per_thread->thread_state(); 19443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char* from = state->data(); 195ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org from = isolate_->handle_scope_implementer()->RestoreThread(from); 196ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org from = isolate_->RestoreThread(from); 1971c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org from = Relocatable::RestoreState(isolate_, from); 19865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 199ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org from = isolate_->debug()->RestoreDebug(from); 20065dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif 201ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org from = isolate_->stack_guard()->RestoreStackGuard(from); 202ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org from = isolate_->regexp_stack()->RestoreStack(from); 203ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org from = isolate_->bootstrapper()->RestoreState(from); 204ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org per_thread->set_thread_state(NULL); 205c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org if (state->terminate_on_restore()) { 206ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->stack_guard()->TerminateExecution(); 207c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org state->set_terminate_on_restore(false); 208c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org } 209a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org state->set_id(ThreadId::Invalid()); 21043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen state->Unlink(); 21143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen state->LinkInto(ThreadState::FREE_LIST); 21243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return true; 21343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 21443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 21643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ThreadManager::Lock() { 21743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mutex_->Lock(); 218a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org mutex_owner_ = ThreadId::Current(); 21943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ASSERT(IsLockedByCurrentThread()); 22043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 22143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ThreadManager::Unlock() { 224a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org mutex_owner_ = ThreadId::Invalid(); 22543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen mutex_->Unlock(); 22643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 22743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 22943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenstatic int ArchiveSpacePerThread() { 23043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return HandleScopeImplementer::ArchiveSpacePerThread() + 231ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate::ArchiveSpacePerThread() + 23265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 23343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Debug::ArchiveSpacePerThread() + 23465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif 2353291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org StackGuard::ArchiveSpacePerThread() + 236ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org RegExpStack::ArchiveSpacePerThread() + 237c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Bootstrapper::ArchiveSpacePerThread() + 238c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org Relocatable::ArchiveSpacePerThread(); 23943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 24043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 24143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 242ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgThreadState::ThreadState(ThreadManager* thread_manager) 243a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org : id_(ThreadId::Invalid()), 244ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org terminate_on_restore_(false), 245c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org data_(NULL), 246ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org next_(this), 247ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org previous_(this), 248ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org thread_manager_(thread_manager) { 24943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 25043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 25143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 252c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgThreadState::~ThreadState() { 253c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org DeleteArray<char>(data_); 254c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org} 255c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 256c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 25743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ThreadState::AllocateSpace() { 25843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data_ = NewArray<char>(ArchiveSpacePerThread()); 25943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 26043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ThreadState::Unlink() { 26343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen next_->previous_ = previous_; 26443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen previous_->next_ = next_; 26543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 26643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 26843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ThreadState::LinkInto(List list) { 26943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ThreadState* flying_anchor = 270ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org list == FREE_LIST ? thread_manager_->free_anchor_ 271ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : thread_manager_->in_use_anchor_; 27243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen next_ = flying_anchor->next_; 27343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen previous_ = flying_anchor; 27443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen flying_anchor->next_ = this; 27543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen next_->previous_ = this; 27643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 27743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 27843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 279ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgThreadState* ThreadManager::GetFreeThreadState() { 28043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ThreadState* gotten = free_anchor_->next_; 28143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen if (gotten == free_anchor_) { 282ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ThreadState* new_thread_state = new ThreadState(this); 28343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen new_thread_state->AllocateSpace(); 28443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return new_thread_state; 28543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 28643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return gotten; 28743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 28843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Gets the first in the list of archived threads. 291ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgThreadState* ThreadManager::FirstThreadStateInUse() { 29243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return in_use_anchor_->Next(); 29343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 29443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 29643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenThreadState* ThreadState::Next() { 297ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (next_ == thread_manager_->in_use_anchor_) return NULL; 29843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return next_; 29943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 30043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 30143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 302a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// Thread ids must start with 1, because in TLS having thread id 0 can't 303a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// be distinguished from not having a thread id at all (since NULL is 304a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org// defined as 0.) 305ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgThreadManager::ThreadManager() 306ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org : mutex_(OS::CreateMutex()), 307a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org mutex_owner_(ThreadId::Invalid()), 308a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org lazily_archived_thread_(ThreadId::Invalid()), 309ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org lazily_archived_thread_state_(NULL), 310ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org free_anchor_(NULL), 311ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org in_use_anchor_(NULL) { 312ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org free_anchor_ = new ThreadState(this); 313ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org in_use_anchor_ = new ThreadState(this); 314ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 315ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 316ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org 317ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgThreadManager::~ThreadManager() { 31828a37086dc5bb171203246e0d9701882d56d6e81rossberg@chromium.org delete mutex_; 319c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org DeleteThreadStateList(free_anchor_); 320c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org DeleteThreadStateList(in_use_anchor_); 321c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org} 322c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 323c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 324c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgvoid ThreadManager::DeleteThreadStateList(ThreadState* anchor) { 325c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org // The list starts and ends with the anchor. 326c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org for (ThreadState* current = anchor->next_; current != anchor;) { 327c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org ThreadState* next = current->next_; 328c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org delete current; 329c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org current = next; 330c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org } 331c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org delete anchor; 332ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org} 33343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 33543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ThreadManager::ArchiveThread() { 336a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org ASSERT(lazily_archived_thread_.Equals(ThreadId::Invalid())); 337a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org ASSERT(!IsArchived()); 3381c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ASSERT(IsLockedByCurrentThread()); 339ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org ThreadState* state = GetFreeThreadState(); 34043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen state->Unlink(); 3411c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Isolate::PerIsolateThreadData* per_thread = 3421c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->FindOrAllocatePerThreadDataForThisThread(); 3431c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org per_thread->set_thread_state(state); 344a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org lazily_archived_thread_ = ThreadId::Current(); 34543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen lazily_archived_thread_state_ = state; 346a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org ASSERT(state->id().Equals(ThreadId::Invalid())); 347bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org state->set_id(CurrentId()); 348a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org ASSERT(!state->id().Equals(ThreadId::Invalid())); 34943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 35043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 35243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ThreadManager::EagerlyArchiveThread() { 3531c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org ASSERT(IsLockedByCurrentThread()); 35443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen ThreadState* state = lazily_archived_thread_state_; 35543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen state->LinkInto(ThreadState::IN_USE_LIST); 35643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char* to = state->data(); 35771affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // Ensure that data containing GC roots are archived first, and handle them 35871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org // in ThreadManager::Iterate(ObjectVisitor*). 359ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org to = isolate_->handle_scope_implementer()->ArchiveThread(to); 360ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org to = isolate_->ArchiveThread(to); 3611c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org to = Relocatable::ArchiveState(isolate_, to); 36265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 363ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org to = isolate_->debug()->ArchiveDebug(to); 36465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif 365ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org to = isolate_->stack_guard()->ArchiveStackGuard(to); 366ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org to = isolate_->regexp_stack()->ArchiveStack(to); 367ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org to = isolate_->bootstrapper()->ArchiveState(to); 368a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org lazily_archived_thread_ = ThreadId::Invalid(); 36943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen lazily_archived_thread_state_ = NULL; 37043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 37143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 37243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 373c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.orgvoid ThreadManager::FreeThreadResources() { 374ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->handle_scope_implementer()->FreeThreadResources(); 375ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->FreeThreadResources(); 376c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org#ifdef ENABLE_DEBUGGER_SUPPORT 377ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->debug()->FreeThreadResources(); 378c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org#endif 379ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->stack_guard()->FreeThreadResources(); 380ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->regexp_stack()->FreeThreadResources(); 381ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->bootstrapper()->FreeThreadResources(); 382c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org} 383c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 384c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org 385a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.orgbool ThreadManager::IsArchived() { 3861c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org Isolate::PerIsolateThreadData* data = 3871c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org isolate_->FindPerThreadDataForThisThread(); 388ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org return data != NULL && data->thread_state() != NULL; 389a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org} 390a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 391e0e1b0d3e70c933d36ed381d511e9fda39f2a751mstarzinger@chromium.org 39243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ThreadManager::Iterate(ObjectVisitor* v) { 39343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen // Expecting no threads during serialization/deserialization 394ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org for (ThreadState* state = FirstThreadStateInUse(); 39543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen state != NULL; 39643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen state = state->Next()) { 39743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen char* data = state->data(); 39843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen data = HandleScopeImplementer::Iterate(v, data); 399ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org data = isolate_->Iterate(v, data); 400c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org data = Relocatable::Iterate(v, data); 40143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 40243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 40343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 40443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 4051af7e1b5f676e5556c041fe09a5c4f5a906f27a0lrn@chromium.orgvoid ThreadManager::IterateArchivedThreads(ThreadVisitor* v) { 406ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org for (ThreadState* state = FirstThreadStateInUse(); 407cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org state != NULL; 408cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org state = state->Next()) { 409cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org char* data = state->data(); 410cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org data += HandleScopeImplementer::ArchiveSpacePerThread(); 411ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate_->IterateThread(v, data); 412cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org } 413cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org} 414cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org 415cec079d8ed1f0920a0ea3dc9a3e81966013287c1whesse@chromium.org 416a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.orgThreadId ThreadManager::CurrentId() { 417a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org return ThreadId::Current(); 418a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org} 419a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 420a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org 421a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.orgvoid ThreadManager::TerminateExecution(ThreadId thread_id) { 422ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org for (ThreadState* state = FirstThreadStateInUse(); 423c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org state != NULL; 424c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org state = state->Next()) { 425a9aa5fa8ae2a2b43a94e6462ded2cd51445e9ee3ager@chromium.org if (thread_id.Equals(state->id())) { 426c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org state->set_terminate_on_restore(true); 427c81c894dabeceb472d668027ca59e73096f5cfafsgjesse@chromium.org } 428bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org } 429bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org} 430bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 431bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org 432ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.orgContextSwitcher::ContextSwitcher(Isolate* isolate, int every_n_ms) 4336d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org : Thread("v8:CtxtSwitcher"), 4345d00b60c201d860c74821f553fdc34f4e057b411lrn@chromium.org keep_going_(true), 4356d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org sleep_ms_(every_n_ms), 4366d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org isolate_(isolate) { 43743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 43843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 43943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 44037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com// Set the scheduling interval of V8 threads. This function starts the 44137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com// ContextSwitcher thread if needed. 44243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ContextSwitcher::StartPreemption(int every_n_ms) { 443ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate = Isolate::Current(); 444d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com ASSERT(Locker::IsLocked(reinterpret_cast<v8::Isolate*>(isolate))); 445ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (isolate->context_switcher() == NULL) { 44637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // If the ContextSwitcher thread is not running at the moment start it now. 447ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->set_context_switcher(new ContextSwitcher(isolate, every_n_ms)); 448ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->context_switcher()->Start(); 44943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } else { 45037abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // ContextSwitcher thread is already running, so we just change the 45137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // scheduling interval. 452ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->context_switcher()->sleep_ms_ = every_n_ms; 45343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 45443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 45543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 45737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com// Disable preemption of V8 threads. If multiple threads want to use V8 they 45837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com// must cooperatively schedule amongst them from this point on. 45943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ContextSwitcher::StopPreemption() { 460ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org Isolate* isolate = Isolate::Current(); 461d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com ASSERT(Locker::IsLocked(reinterpret_cast<v8::Isolate*>(isolate))); 462ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org if (isolate->context_switcher() != NULL) { 46337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // The ContextSwitcher thread is running. We need to stop it and release 46437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // its resources. 465ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->context_switcher()->keep_going_ = false; 466ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org // Wait for the ContextSwitcher thread to exit. 467ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->context_switcher()->Join(); 46837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // Thread has exited, now we can delete it. 469ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org delete(isolate->context_switcher()); 470ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate->set_context_switcher(NULL); 47143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 47243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 47343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 47537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com// Main loop of the ContextSwitcher thread: Preempt the currently running V8 47637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com// thread at regular intervals. 47743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ContextSwitcher::Run() { 47843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen while (keep_going_) { 47943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen OS::Sleep(sleep_ms_); 480ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org isolate()->stack_guard()->Preempt(); 48143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen } 48243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 48343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 48537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com// Acknowledge the preemption by the receiving thread. 48643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenvoid ContextSwitcher::PreemptionReceived() { 48746a2a51ad190697e0f62c3060ce02a9de5820a07yangguo@chromium.org ASSERT(Locker::IsLocked(i::Isolate::GetDefaultIsolateForLocking())); 48837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // There is currently no accounting being done for this. But could be in the 48937abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com // future, which is why we leave this in. 49043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 49143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 49243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 49343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} // namespace internal 49443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} // namespace v8 495