| OLD | NEW |
| 1 // Copyright 2008 the V8 project authors. All rights reserved. | 1 // Copyright 2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 // This only enters if not yet entered. | 67 // This only enters if not yet entered. |
| 68 internal::Isolate::EnterDefaultIsolate(); | 68 internal::Isolate::EnterDefaultIsolate(); |
| 69 } | 69 } |
| 70 | 70 |
| 71 ASSERT(internal::Thread::HasThreadLocal( | 71 ASSERT(internal::Thread::HasThreadLocal( |
| 72 internal::Isolate::thread_id_key())); | 72 internal::Isolate::thread_id_key())); |
| 73 | 73 |
| 74 // Make sure that V8 is initialized. Archiving of threads interferes | 74 // Make sure that V8 is initialized. Archiving of threads interferes |
| 75 // with deserialization by adding additional root pointers, so we must | 75 // with deserialization by adding additional root pointers, so we must |
| 76 // initialize here, before anyone can call ~Locker() or Unlocker(). | 76 // initialize here, before anyone can call ~Locker() or Unlocker(). |
| 77 if (!internal::V8::IsRunning()) { | 77 if (!isolate->IsInitialized()) { |
| 78 V8::Initialize(); | 78 V8::Initialize(); |
| 79 } | 79 } |
| 80 // This may be a locker within an unlocker in which case we have to | 80 // This may be a locker within an unlocker in which case we have to |
| 81 // get the saved state for this thread and restore it. | 81 // get the saved state for this thread and restore it. |
| 82 if (isolate->thread_manager()->RestoreThread()) { | 82 if (isolate->thread_manager()->RestoreThread()) { |
| 83 top_level_ = false; | 83 top_level_ = false; |
| 84 } else { | 84 } else { |
| 85 internal::ExecutionAccess access; | 85 internal::ExecutionAccess access(isolate); |
| 86 isolate->stack_guard()->ClearThread(access); | 86 isolate->stack_guard()->ClearThread(access); |
| 87 isolate->stack_guard()->InitThread(access); | 87 isolate->stack_guard()->InitThread(access); |
| 88 } | 88 } |
| 89 } | 89 } |
| 90 ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); | 90 ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); |
| 91 } | 91 } |
| 92 | 92 |
| 93 | 93 |
| 94 bool Locker::IsLocked() { | 94 bool Locker::IsLocked() { |
| 95 return internal::Isolate::Current()->thread_manager()-> | 95 return internal::Isolate::Current()->thread_manager()-> |
| 96 IsLockedByCurrentThread(); | 96 IsLockedByCurrentThread(); |
| 97 } | 97 } |
| 98 | 98 |
| 99 | 99 |
| 100 Locker::~Locker() { | 100 Locker::~Locker() { |
| 101 // TODO(isolate): this should use a field storing the isolate it |
| 102 // locked instead. |
| 101 internal::Isolate* isolate = internal::Isolate::Current(); | 103 internal::Isolate* isolate = internal::Isolate::Current(); |
| 102 ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); | 104 ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); |
| 103 if (has_lock_) { | 105 if (has_lock_) { |
| 104 if (top_level_) { | 106 if (top_level_) { |
| 105 isolate->thread_manager()->FreeThreadResources(); | 107 isolate->thread_manager()->FreeThreadResources(); |
| 106 } else { | 108 } else { |
| 107 isolate->thread_manager()->ArchiveThread(); | 109 isolate->thread_manager()->ArchiveThread(); |
| 108 } | 110 } |
| 109 isolate->thread_manager()->Unlock(); | 111 isolate->thread_manager()->Unlock(); |
| 110 } | 112 } |
| 111 } | 113 } |
| 112 | 114 |
| 113 | 115 |
| 114 Unlocker::Unlocker() { | 116 Unlocker::Unlocker() { |
| 115 internal::Isolate* isolate = internal::Isolate::Current(); | 117 internal::Isolate* isolate = internal::Isolate::Current(); |
| 116 ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); | 118 ASSERT(isolate->thread_manager()->IsLockedByCurrentThread()); |
| 117 isolate->thread_manager()->ArchiveThread(); | 119 isolate->thread_manager()->ArchiveThread(); |
| 118 isolate->thread_manager()->Unlock(); | 120 isolate->thread_manager()->Unlock(); |
| 119 } | 121 } |
| 120 | 122 |
| 121 | 123 |
| 122 Unlocker::~Unlocker() { | 124 Unlocker::~Unlocker() { |
| 125 // TODO(isolates): check it's the isolate we unlocked. |
| 123 internal::Isolate* isolate = internal::Isolate::Current(); | 126 internal::Isolate* isolate = internal::Isolate::Current(); |
| 124 ASSERT(!isolate->thread_manager()->IsLockedByCurrentThread()); | 127 ASSERT(!isolate->thread_manager()->IsLockedByCurrentThread()); |
| 125 isolate->thread_manager()->Lock(); | 128 isolate->thread_manager()->Lock(); |
| 126 isolate->thread_manager()->RestoreThread(); | 129 isolate->thread_manager()->RestoreThread(); |
| 127 } | 130 } |
| 128 | 131 |
| 129 | 132 |
| 130 void Locker::StartPreemption(int every_n_ms) { | 133 void Locker::StartPreemption(int every_n_ms) { |
| 131 v8::internal::ContextSwitcher::StartPreemption(every_n_ms); | 134 v8::internal::ContextSwitcher::StartPreemption(every_n_ms); |
| 132 } | 135 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 150 lazily_archived_thread_state_); | 153 lazily_archived_thread_state_); |
| 151 lazily_archived_thread_state_->set_id(kInvalidId); | 154 lazily_archived_thread_state_->set_id(kInvalidId); |
| 152 lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST); | 155 lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST); |
| 153 lazily_archived_thread_state_ = NULL; | 156 lazily_archived_thread_state_ = NULL; |
| 154 Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL); | 157 Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL); |
| 155 return true; | 158 return true; |
| 156 } | 159 } |
| 157 | 160 |
| 158 // Make sure that the preemption thread cannot modify the thread state while | 161 // Make sure that the preemption thread cannot modify the thread state while |
| 159 // it is being archived or restored. | 162 // it is being archived or restored. |
| 160 ExecutionAccess access; | 163 ExecutionAccess access(isolate_); |
| 161 | 164 |
| 162 // If there is another thread that was lazily archived then we have to really | 165 // If there is another thread that was lazily archived then we have to really |
| 163 // archive it now. | 166 // archive it now. |
| 164 if (lazily_archived_thread_.IsValid()) { | 167 if (lazily_archived_thread_.IsValid()) { |
| 165 EagerlyArchiveThread(); | 168 EagerlyArchiveThread(); |
| 166 } | 169 } |
| 167 Isolate::PerIsolateThreadData* per_thread = | 170 Isolate::PerIsolateThreadData* per_thread = |
| 168 Isolate::CurrentPerIsolateThreadData(); | 171 Isolate::CurrentPerIsolateThreadData(); |
| 169 if (per_thread == NULL || per_thread->thread_state() == NULL) { | 172 if (per_thread == NULL || per_thread->thread_state() == NULL) { |
| 170 // This is a new thread. | 173 // This is a new thread. |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 283 lazily_archived_thread_(ThreadHandle::INVALID), | 286 lazily_archived_thread_(ThreadHandle::INVALID), |
| 284 lazily_archived_thread_state_(NULL), | 287 lazily_archived_thread_state_(NULL), |
| 285 free_anchor_(NULL), | 288 free_anchor_(NULL), |
| 286 in_use_anchor_(NULL) { | 289 in_use_anchor_(NULL) { |
| 287 free_anchor_ = new ThreadState(this); | 290 free_anchor_ = new ThreadState(this); |
| 288 in_use_anchor_ = new ThreadState(this); | 291 in_use_anchor_ = new ThreadState(this); |
| 289 } | 292 } |
| 290 | 293 |
| 291 | 294 |
| 292 ThreadManager::~ThreadManager() { | 295 ThreadManager::~ThreadManager() { |
| 293 // TODO(isolates): Destroy TLS keys and mutexes. | 296 // TODO(isolates): Destroy mutexes. |
| 294 } | 297 } |
| 295 | 298 |
| 296 | 299 |
| 297 void ThreadManager::ArchiveThread() { | 300 void ThreadManager::ArchiveThread() { |
| 298 ASSERT(!lazily_archived_thread_.IsValid()); | 301 ASSERT(!lazily_archived_thread_.IsValid()); |
| 299 ASSERT(!IsArchived()); | 302 ASSERT(!IsArchived()); |
| 300 ThreadState* state = GetFreeThreadState(); | 303 ThreadState* state = GetFreeThreadState(); |
| 301 state->Unlink(); | 304 state->Unlink(); |
| 302 Isolate::CurrentPerIsolateThreadData()->set_thread_state(state); | 305 Isolate::CurrentPerIsolateThreadData()->set_thread_state(state); |
| 303 lazily_archived_thread_.Initialize(ThreadHandle::SELF); | 306 lazily_archived_thread_.Initialize(ThreadHandle::SELF); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 // Acknowledge the preemption by the receiving thread. | 444 // Acknowledge the preemption by the receiving thread. |
| 442 void ContextSwitcher::PreemptionReceived() { | 445 void ContextSwitcher::PreemptionReceived() { |
| 443 ASSERT(Locker::IsLocked()); | 446 ASSERT(Locker::IsLocked()); |
| 444 // There is currently no accounting being done for this. But could be in the | 447 // There is currently no accounting being done for this. But could be in the |
| 445 // future, which is why we leave this in. | 448 // future, which is why we leave this in. |
| 446 } | 449 } |
| 447 | 450 |
| 448 | 451 |
| 449 } // namespace internal | 452 } // namespace internal |
| 450 } // namespace v8 | 453 } // namespace v8 |
| OLD | NEW |