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