| 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 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 } | 140 } |
| 141 | 141 |
| 142 | 142 |
| 143 namespace internal { | 143 namespace internal { |
| 144 | 144 |
| 145 | 145 |
| 146 bool ThreadManager::RestoreThread() { | 146 bool ThreadManager::RestoreThread() { |
| 147 // First check whether the current thread has been 'lazily archived', ie | 147 // First check whether the current thread has been 'lazily archived', ie |
| 148 // not archived at all. If that is the case we put the state storage we | 148 // not archived at all. If that is the case we put the state storage we |
| 149 // had prepared back in the free list, since we didn't need it after all. | 149 // had prepared back in the free list, since we didn't need it after all. |
| 150 if (lazily_archived_thread_.IsSelf()) { | 150 if (lazily_archived_thread_.Equals(ThreadId::Current())) { |
| 151 lazily_archived_thread_.Initialize(ThreadHandle::INVALID); | 151 lazily_archived_thread_ = ThreadId::Invalid(); |
| 152 ASSERT(Isolate::CurrentPerIsolateThreadData()->thread_state() == | 152 ASSERT(Isolate::CurrentPerIsolateThreadData()->thread_state() == |
| 153 lazily_archived_thread_state_); | 153 lazily_archived_thread_state_); |
| 154 lazily_archived_thread_state_->set_id(kInvalidId); | 154 lazily_archived_thread_state_->set_id(ThreadId::Invalid()); |
| 155 lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST); | 155 lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST); |
| 156 lazily_archived_thread_state_ = NULL; | 156 lazily_archived_thread_state_ = NULL; |
| 157 Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL); | 157 Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL); |
| 158 return true; | 158 return true; |
| 159 } | 159 } |
| 160 | 160 |
| 161 // 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 |
| 162 // it is being archived or restored. | 162 // it is being archived or restored. |
| 163 ExecutionAccess access(isolate_); | 163 ExecutionAccess access(isolate_); |
| 164 | 164 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 183 from = isolate_->debug()->RestoreDebug(from); | 183 from = isolate_->debug()->RestoreDebug(from); |
| 184 #endif | 184 #endif |
| 185 from = isolate_->stack_guard()->RestoreStackGuard(from); | 185 from = isolate_->stack_guard()->RestoreStackGuard(from); |
| 186 from = isolate_->regexp_stack()->RestoreStack(from); | 186 from = isolate_->regexp_stack()->RestoreStack(from); |
| 187 from = isolate_->bootstrapper()->RestoreState(from); | 187 from = isolate_->bootstrapper()->RestoreState(from); |
| 188 per_thread->set_thread_state(NULL); | 188 per_thread->set_thread_state(NULL); |
| 189 if (state->terminate_on_restore()) { | 189 if (state->terminate_on_restore()) { |
| 190 isolate_->stack_guard()->TerminateExecution(); | 190 isolate_->stack_guard()->TerminateExecution(); |
| 191 state->set_terminate_on_restore(false); | 191 state->set_terminate_on_restore(false); |
| 192 } | 192 } |
| 193 state->set_id(kInvalidId); | 193 state->set_id(ThreadId::Invalid()); |
| 194 state->Unlink(); | 194 state->Unlink(); |
| 195 state->LinkInto(ThreadState::FREE_LIST); | 195 state->LinkInto(ThreadState::FREE_LIST); |
| 196 return true; | 196 return true; |
| 197 } | 197 } |
| 198 | 198 |
| 199 | 199 |
| 200 void ThreadManager::Lock() { | 200 void ThreadManager::Lock() { |
| 201 mutex_->Lock(); | 201 mutex_->Lock(); |
| 202 mutex_owner_.Initialize(ThreadHandle::SELF); | 202 mutex_owner_ = ThreadId::Current(); |
| 203 ASSERT(IsLockedByCurrentThread()); | 203 ASSERT(IsLockedByCurrentThread()); |
| 204 } | 204 } |
| 205 | 205 |
| 206 | 206 |
| 207 void ThreadManager::Unlock() { | 207 void ThreadManager::Unlock() { |
| 208 mutex_owner_.Initialize(ThreadHandle::INVALID); | 208 mutex_owner_ = ThreadId::Invalid(); |
| 209 mutex_->Unlock(); | 209 mutex_->Unlock(); |
| 210 } | 210 } |
| 211 | 211 |
| 212 | 212 |
| 213 static int ArchiveSpacePerThread() { | 213 static int ArchiveSpacePerThread() { |
| 214 return HandleScopeImplementer::ArchiveSpacePerThread() + | 214 return HandleScopeImplementer::ArchiveSpacePerThread() + |
| 215 Isolate::ArchiveSpacePerThread() + | 215 Isolate::ArchiveSpacePerThread() + |
| 216 #ifdef ENABLE_DEBUGGER_SUPPORT | 216 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 217 Debug::ArchiveSpacePerThread() + | 217 Debug::ArchiveSpacePerThread() + |
| 218 #endif | 218 #endif |
| 219 StackGuard::ArchiveSpacePerThread() + | 219 StackGuard::ArchiveSpacePerThread() + |
| 220 RegExpStack::ArchiveSpacePerThread() + | 220 RegExpStack::ArchiveSpacePerThread() + |
| 221 Bootstrapper::ArchiveSpacePerThread() + | 221 Bootstrapper::ArchiveSpacePerThread() + |
| 222 Relocatable::ArchiveSpacePerThread(); | 222 Relocatable::ArchiveSpacePerThread(); |
| 223 } | 223 } |
| 224 | 224 |
| 225 | 225 |
| 226 ThreadState::ThreadState(ThreadManager* thread_manager) | 226 ThreadState::ThreadState(ThreadManager* thread_manager) |
| 227 : id_(ThreadManager::kInvalidId), | 227 : id_(ThreadId::Invalid()), |
| 228 terminate_on_restore_(false), | 228 terminate_on_restore_(false), |
| 229 next_(this), | 229 next_(this), |
| 230 previous_(this), | 230 previous_(this), |
| 231 thread_manager_(thread_manager) { | 231 thread_manager_(thread_manager) { |
| 232 } | 232 } |
| 233 | 233 |
| 234 | 234 |
| 235 void ThreadState::AllocateSpace() { | 235 void ThreadState::AllocateSpace() { |
| 236 data_ = NewArray<char>(ArchiveSpacePerThread()); | 236 data_ = NewArray<char>(ArchiveSpacePerThread()); |
| 237 } | 237 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 if (next_ == thread_manager_->in_use_anchor_) return NULL; | 275 if (next_ == thread_manager_->in_use_anchor_) return NULL; |
| 276 return next_; | 276 return next_; |
| 277 } | 277 } |
| 278 | 278 |
| 279 | 279 |
| 280 // Thread ids must start with 1, because in TLS having thread id 0 can't | 280 // Thread ids must start with 1, because in TLS having thread id 0 can't |
| 281 // be distinguished from not having a thread id at all (since NULL is | 281 // be distinguished from not having a thread id at all (since NULL is |
| 282 // defined as 0.) | 282 // defined as 0.) |
| 283 ThreadManager::ThreadManager() | 283 ThreadManager::ThreadManager() |
| 284 : mutex_(OS::CreateMutex()), | 284 : mutex_(OS::CreateMutex()), |
| 285 mutex_owner_(ThreadHandle::INVALID), | 285 mutex_owner_(ThreadId::Invalid()), |
| 286 lazily_archived_thread_(ThreadHandle::INVALID), | 286 lazily_archived_thread_(ThreadId::Invalid()), |
| 287 lazily_archived_thread_state_(NULL), | 287 lazily_archived_thread_state_(NULL), |
| 288 free_anchor_(NULL), | 288 free_anchor_(NULL), |
| 289 in_use_anchor_(NULL) { | 289 in_use_anchor_(NULL) { |
| 290 free_anchor_ = new ThreadState(this); | 290 free_anchor_ = new ThreadState(this); |
| 291 in_use_anchor_ = new ThreadState(this); | 291 in_use_anchor_ = new ThreadState(this); |
| 292 } | 292 } |
| 293 | 293 |
| 294 | 294 |
| 295 ThreadManager::~ThreadManager() { | 295 ThreadManager::~ThreadManager() { |
| 296 // TODO(isolates): Destroy mutexes. | 296 // TODO(isolates): Destroy mutexes. |
| 297 } | 297 } |
| 298 | 298 |
| 299 | 299 |
| 300 void ThreadManager::ArchiveThread() { | 300 void ThreadManager::ArchiveThread() { |
| 301 ASSERT(!lazily_archived_thread_.IsValid()); | 301 ASSERT(lazily_archived_thread_.Equals(ThreadId::Invalid())); |
| 302 ASSERT(!IsArchived()); | 302 ASSERT(!IsArchived()); |
| 303 ThreadState* state = GetFreeThreadState(); | 303 ThreadState* state = GetFreeThreadState(); |
| 304 state->Unlink(); | 304 state->Unlink(); |
| 305 Isolate::CurrentPerIsolateThreadData()->set_thread_state(state); | 305 Isolate::CurrentPerIsolateThreadData()->set_thread_state(state); |
| 306 lazily_archived_thread_.Initialize(ThreadHandle::SELF); | 306 lazily_archived_thread_ = ThreadId::Current(); |
| 307 lazily_archived_thread_state_ = state; | 307 lazily_archived_thread_state_ = state; |
| 308 ASSERT(state->id() == kInvalidId); | 308 ASSERT(state->id().Equals(ThreadId::Invalid())); |
| 309 state->set_id(CurrentId()); | 309 state->set_id(CurrentId()); |
| 310 ASSERT(state->id() != kInvalidId); | 310 ASSERT(!state->id().Equals(ThreadId::Invalid())); |
| 311 } | 311 } |
| 312 | 312 |
| 313 | 313 |
| 314 void ThreadManager::EagerlyArchiveThread() { | 314 void ThreadManager::EagerlyArchiveThread() { |
| 315 ThreadState* state = lazily_archived_thread_state_; | 315 ThreadState* state = lazily_archived_thread_state_; |
| 316 state->LinkInto(ThreadState::IN_USE_LIST); | 316 state->LinkInto(ThreadState::IN_USE_LIST); |
| 317 char* to = state->data(); | 317 char* to = state->data(); |
| 318 // Ensure that data containing GC roots are archived first, and handle them | 318 // Ensure that data containing GC roots are archived first, and handle them |
| 319 // in ThreadManager::Iterate(ObjectVisitor*). | 319 // in ThreadManager::Iterate(ObjectVisitor*). |
| 320 to = isolate_->handle_scope_implementer()->ArchiveThread(to); | 320 to = isolate_->handle_scope_implementer()->ArchiveThread(to); |
| 321 to = isolate_->ArchiveThread(to); | 321 to = isolate_->ArchiveThread(to); |
| 322 to = Relocatable::ArchiveState(to); | 322 to = Relocatable::ArchiveState(to); |
| 323 #ifdef ENABLE_DEBUGGER_SUPPORT | 323 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 324 to = isolate_->debug()->ArchiveDebug(to); | 324 to = isolate_->debug()->ArchiveDebug(to); |
| 325 #endif | 325 #endif |
| 326 to = isolate_->stack_guard()->ArchiveStackGuard(to); | 326 to = isolate_->stack_guard()->ArchiveStackGuard(to); |
| 327 to = isolate_->regexp_stack()->ArchiveStack(to); | 327 to = isolate_->regexp_stack()->ArchiveStack(to); |
| 328 to = isolate_->bootstrapper()->ArchiveState(to); | 328 to = isolate_->bootstrapper()->ArchiveState(to); |
| 329 lazily_archived_thread_.Initialize(ThreadHandle::INVALID); | 329 lazily_archived_thread_ = ThreadId::Invalid(); |
| 330 lazily_archived_thread_state_ = NULL; | 330 lazily_archived_thread_state_ = NULL; |
| 331 } | 331 } |
| 332 | 332 |
| 333 | 333 |
| 334 void ThreadManager::FreeThreadResources() { | 334 void ThreadManager::FreeThreadResources() { |
| 335 isolate_->handle_scope_implementer()->FreeThreadResources(); | 335 isolate_->handle_scope_implementer()->FreeThreadResources(); |
| 336 isolate_->FreeThreadResources(); | 336 isolate_->FreeThreadResources(); |
| 337 #ifdef ENABLE_DEBUGGER_SUPPORT | 337 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 338 isolate_->debug()->FreeThreadResources(); | 338 isolate_->debug()->FreeThreadResources(); |
| 339 #endif | 339 #endif |
| (...skipping 26 matching lines...) Expand all Loading... |
| 366 for (ThreadState* state = FirstThreadStateInUse(); | 366 for (ThreadState* state = FirstThreadStateInUse(); |
| 367 state != NULL; | 367 state != NULL; |
| 368 state = state->Next()) { | 368 state = state->Next()) { |
| 369 char* data = state->data(); | 369 char* data = state->data(); |
| 370 data += HandleScopeImplementer::ArchiveSpacePerThread(); | 370 data += HandleScopeImplementer::ArchiveSpacePerThread(); |
| 371 isolate_->IterateThread(v, data); | 371 isolate_->IterateThread(v, data); |
| 372 } | 372 } |
| 373 } | 373 } |
| 374 | 374 |
| 375 | 375 |
| 376 int ThreadManager::CurrentId() { | 376 ThreadId ThreadManager::CurrentId() { |
| 377 return Thread::GetThreadLocalInt(Isolate::thread_id_key()); | 377 return ThreadId::Current(); |
| 378 } | 378 } |
| 379 | 379 |
| 380 | 380 |
| 381 void ThreadManager::TerminateExecution(int thread_id) { | 381 void ThreadManager::TerminateExecution(ThreadId thread_id) { |
| 382 for (ThreadState* state = FirstThreadStateInUse(); | 382 for (ThreadState* state = FirstThreadStateInUse(); |
| 383 state != NULL; | 383 state != NULL; |
| 384 state = state->Next()) { | 384 state = state->Next()) { |
| 385 if (thread_id == state->id()) { | 385 if (thread_id.Equals(state->id())) { |
| 386 state->set_terminate_on_restore(true); | 386 state->set_terminate_on_restore(true); |
| 387 } | 387 } |
| 388 } | 388 } |
| 389 } | 389 } |
| 390 | 390 |
| 391 | 391 |
| 392 ContextSwitcher::ContextSwitcher(Isolate* isolate, int every_n_ms) | 392 ContextSwitcher::ContextSwitcher(Isolate* isolate, int every_n_ms) |
| 393 : Thread(isolate, "v8:CtxtSwitcher"), | 393 : Thread(isolate, "v8:CtxtSwitcher"), |
| 394 keep_going_(true), | 394 keep_going_(true), |
| 395 sleep_ms_(every_n_ms) { | 395 sleep_ms_(every_n_ms) { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 // Acknowledge the preemption by the receiving thread. | 444 // Acknowledge the preemption by the receiving thread. |
| 445 void ContextSwitcher::PreemptionReceived() { | 445 void ContextSwitcher::PreemptionReceived() { |
| 446 ASSERT(Locker::IsLocked()); | 446 ASSERT(Locker::IsLocked()); |
| 447 // 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 |
| 448 // future, which is why we leave this in. | 448 // future, which is why we leave this in. |
| 449 } | 449 } |
| 450 | 450 |
| 451 | 451 |
| 452 } // namespace internal | 452 } // namespace internal |
| 453 } // namespace v8 | 453 } // namespace v8 |
| OLD | NEW |