| OLD | NEW |
| 1 // Copyright 2006-2010 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2010 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 #include "serialize.h" | 47 #include "serialize.h" |
| 48 #include "simulator.h" | 48 #include "simulator.h" |
| 49 #include "spaces.h" | 49 #include "spaces.h" |
| 50 #include "stub-cache.h" | 50 #include "stub-cache.h" |
| 51 #include "version.h" | 51 #include "version.h" |
| 52 | 52 |
| 53 | 53 |
| 54 namespace v8 { | 54 namespace v8 { |
| 55 namespace internal { | 55 namespace internal { |
| 56 | 56 |
| 57 Atomic32 ThreadId::highest_thread_id_ = 0; |
| 58 |
| 59 int ThreadId::AllocateThreadId() { |
| 60 int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1); |
| 61 return new_id; |
| 62 } |
| 63 |
| 64 int ThreadId::GetCurrentThreadId() { |
| 65 int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_); |
| 66 if (thread_id == 0) { |
| 67 thread_id = AllocateThreadId(); |
| 68 Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id); |
| 69 } |
| 70 return thread_id; |
| 71 } |
| 57 | 72 |
| 58 // Create a dummy thread that will wait forever on a semaphore. The only | 73 // Create a dummy thread that will wait forever on a semaphore. The only |
| 59 // purpose for this thread is to have some stack area to save essential data | 74 // purpose for this thread is to have some stack area to save essential data |
| 60 // into for use by a stacks only core dump (aka minidump). | 75 // into for use by a stacks only core dump (aka minidump). |
| 61 class PreallocatedMemoryThread: public Thread { | 76 class PreallocatedMemoryThread: public Thread { |
| 62 public: | 77 public: |
| 63 char* data() { | 78 char* data() { |
| 64 if (data_ready_semaphore_ != NULL) { | 79 if (data_ready_semaphore_ != NULL) { |
| 65 // Initial access is guarded until the data has been published. | 80 // Initial access is guarded until the data has been published. |
| 66 data_ready_semaphore_->Wait(); | 81 data_ready_semaphore_->Wait(); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 storage->LinkTo(&free_list_); | 253 storage->LinkTo(&free_list_); |
| 239 } | 254 } |
| 240 | 255 |
| 241 | 256 |
| 242 Isolate* Isolate::default_isolate_ = NULL; | 257 Isolate* Isolate::default_isolate_ = NULL; |
| 243 Thread::LocalStorageKey Isolate::isolate_key_; | 258 Thread::LocalStorageKey Isolate::isolate_key_; |
| 244 Thread::LocalStorageKey Isolate::thread_id_key_; | 259 Thread::LocalStorageKey Isolate::thread_id_key_; |
| 245 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; | 260 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; |
| 246 Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex(); | 261 Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex(); |
| 247 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL; | 262 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL; |
| 248 Isolate::ThreadId Isolate::highest_thread_id_ = 0; | |
| 249 | 263 |
| 250 | 264 |
| 251 class IsolateInitializer { | 265 class IsolateInitializer { |
| 252 public: | 266 public: |
| 253 IsolateInitializer() { | 267 IsolateInitializer() { |
| 254 Isolate::EnsureDefaultIsolate(); | 268 Isolate::EnsureDefaultIsolate(); |
| 255 } | 269 } |
| 256 }; | 270 }; |
| 257 | 271 |
| 258 static IsolateInitializer* EnsureDefaultIsolateAllocated() { | 272 static IsolateInitializer* EnsureDefaultIsolateAllocated() { |
| 259 // TODO(isolates): Use the system threading API to do this once? | 273 // TODO(isolates): Use the system threading API to do this once? |
| 260 static IsolateInitializer static_initializer; | 274 static IsolateInitializer static_initializer; |
| 261 return &static_initializer; | 275 return &static_initializer; |
| 262 } | 276 } |
| 263 | 277 |
| 264 // This variable only needed to trigger static intialization. | 278 // This variable only needed to trigger static intialization. |
| 265 static IsolateInitializer* static_initializer = EnsureDefaultIsolateAllocated(); | 279 static IsolateInitializer* static_initializer = EnsureDefaultIsolateAllocated(); |
| 266 | 280 |
| 267 | 281 |
| 268 Isolate::ThreadId Isolate::AllocateThreadId() { | 282 |
| 269 ThreadId new_id; | |
| 270 { | |
| 271 ScopedLock lock(process_wide_mutex_); | |
| 272 new_id = ++highest_thread_id_; | |
| 273 } | |
| 274 return new_id; | |
| 275 } | |
| 276 | 283 |
| 277 | 284 |
| 278 Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData( | 285 Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData( |
| 279 ThreadId thread_id) { | 286 ThreadId thread_id) { |
| 280 ASSERT(thread_id != 0); | 287 ASSERT(!thread_id.Equals(ThreadId::Invalid())); |
| 281 ASSERT(Thread::GetThreadLocalInt(thread_id_key_) == thread_id); | |
| 282 PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id); | 288 PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id); |
| 283 { | 289 { |
| 284 ScopedLock lock(process_wide_mutex_); | 290 ScopedLock lock(process_wide_mutex_); |
| 285 ASSERT(thread_data_table_->Lookup(this, thread_id) == NULL); | 291 ASSERT(thread_data_table_->Lookup(this, thread_id) == NULL); |
| 286 thread_data_table_->Insert(per_thread); | 292 thread_data_table_->Insert(per_thread); |
| 287 ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread); | 293 ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread); |
| 288 } | 294 } |
| 289 return per_thread; | 295 return per_thread; |
| 290 } | 296 } |
| 291 | 297 |
| 292 | 298 |
| 293 Isolate::PerIsolateThreadData* | 299 Isolate::PerIsolateThreadData* |
| 294 Isolate::FindOrAllocatePerThreadDataForThisThread() { | 300 Isolate::FindOrAllocatePerThreadDataForThisThread() { |
| 295 ThreadId thread_id = Thread::GetThreadLocalInt(thread_id_key_); | 301 ThreadId thread_id = ThreadId::Current(); |
| 296 if (thread_id == 0) { | |
| 297 thread_id = AllocateThreadId(); | |
| 298 Thread::SetThreadLocalInt(thread_id_key_, thread_id); | |
| 299 } | |
| 300 PerIsolateThreadData* per_thread = NULL; | 302 PerIsolateThreadData* per_thread = NULL; |
| 301 { | 303 { |
| 302 ScopedLock lock(process_wide_mutex_); | 304 ScopedLock lock(process_wide_mutex_); |
| 303 per_thread = thread_data_table_->Lookup(this, thread_id); | 305 per_thread = thread_data_table_->Lookup(this, thread_id); |
| 304 if (per_thread == NULL) { | 306 if (per_thread == NULL) { |
| 305 per_thread = AllocatePerIsolateThreadData(thread_id); | 307 per_thread = AllocatePerIsolateThreadData(thread_id); |
| 306 } | 308 } |
| 307 } | 309 } |
| 308 return per_thread; | 310 return per_thread; |
| 309 } | 311 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 return default_isolate_; | 356 return default_isolate_; |
| 355 } | 357 } |
| 356 | 358 |
| 357 | 359 |
| 358 Isolate::ThreadDataTable::ThreadDataTable() | 360 Isolate::ThreadDataTable::ThreadDataTable() |
| 359 : list_(NULL) { | 361 : list_(NULL) { |
| 360 } | 362 } |
| 361 | 363 |
| 362 | 364 |
| 363 Isolate::PerIsolateThreadData* | 365 Isolate::PerIsolateThreadData* |
| 364 Isolate::ThreadDataTable::Lookup(Isolate* isolate, ThreadId thread_id) { | 366 Isolate::ThreadDataTable::Lookup(Isolate* isolate, |
| 367 ThreadId thread_id) { |
| 365 for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) { | 368 for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) { |
| 366 if (data->Matches(isolate, thread_id)) return data; | 369 if (data->Matches(isolate, thread_id)) return data; |
| 367 } | 370 } |
| 368 return NULL; | 371 return NULL; |
| 369 } | 372 } |
| 370 | 373 |
| 371 | 374 |
| 372 void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) { | 375 void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) { |
| 373 if (list_ != NULL) list_->prev_ = data; | 376 if (list_ != NULL) list_->prev_ = data; |
| 374 data->next_ = list_; | 377 data->next_ = list_; |
| 375 list_ = data; | 378 list_ = data; |
| 376 } | 379 } |
| 377 | 380 |
| 378 | 381 |
| 379 void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) { | 382 void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) { |
| 380 if (list_ == data) list_ = data->next_; | 383 if (list_ == data) list_ = data->next_; |
| 381 if (data->next_ != NULL) data->next_->prev_ = data->prev_; | 384 if (data->next_ != NULL) data->next_->prev_ = data->prev_; |
| 382 if (data->prev_ != NULL) data->prev_->next_ = data->next_; | 385 if (data->prev_ != NULL) data->prev_->next_ = data->next_; |
| 383 } | 386 } |
| 384 | 387 |
| 385 | 388 |
| 386 void Isolate::ThreadDataTable::Remove(Isolate* isolate, ThreadId thread_id) { | 389 void Isolate::ThreadDataTable::Remove(Isolate* isolate, |
| 390 ThreadId thread_id) { |
| 387 PerIsolateThreadData* data = Lookup(isolate, thread_id); | 391 PerIsolateThreadData* data = Lookup(isolate, thread_id); |
| 388 if (data != NULL) { | 392 if (data != NULL) { |
| 389 Remove(data); | 393 Remove(data); |
| 390 } | 394 } |
| 391 } | 395 } |
| 392 | 396 |
| 393 | 397 |
| 394 #ifdef DEBUG | 398 #ifdef DEBUG |
| 395 #define TRACE_ISOLATE(tag) \ | 399 #define TRACE_ISOLATE(tag) \ |
| 396 do { \ | 400 do { \ |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 void Isolate::Enter() { | 830 void Isolate::Enter() { |
| 827 Isolate* current_isolate = NULL; | 831 Isolate* current_isolate = NULL; |
| 828 PerIsolateThreadData* current_data = CurrentPerIsolateThreadData(); | 832 PerIsolateThreadData* current_data = CurrentPerIsolateThreadData(); |
| 829 if (current_data != NULL) { | 833 if (current_data != NULL) { |
| 830 current_isolate = current_data->isolate_; | 834 current_isolate = current_data->isolate_; |
| 831 ASSERT(current_isolate != NULL); | 835 ASSERT(current_isolate != NULL); |
| 832 if (current_isolate == this) { | 836 if (current_isolate == this) { |
| 833 ASSERT(Current() == this); | 837 ASSERT(Current() == this); |
| 834 ASSERT(entry_stack_ != NULL); | 838 ASSERT(entry_stack_ != NULL); |
| 835 ASSERT(entry_stack_->previous_thread_data == NULL || | 839 ASSERT(entry_stack_->previous_thread_data == NULL || |
| 836 entry_stack_->previous_thread_data->thread_id() == | 840 entry_stack_->previous_thread_data->thread_id().Equals( |
| 837 Thread::GetThreadLocalInt(thread_id_key_)); | 841 ThreadId::Current())); |
| 838 // Same thread re-enters the isolate, no need to re-init anything. | 842 // Same thread re-enters the isolate, no need to re-init anything. |
| 839 entry_stack_->entry_count++; | 843 entry_stack_->entry_count++; |
| 840 return; | 844 return; |
| 841 } | 845 } |
| 842 } | 846 } |
| 843 | 847 |
| 844 // Threads can have default isolate set into TLS as Current but not yet have | 848 // Threads can have default isolate set into TLS as Current but not yet have |
| 845 // PerIsolateThreadData for it, as it requires more advanced phase of the | 849 // PerIsolateThreadData for it, as it requires more advanced phase of the |
| 846 // initialization. For example, a thread might be the one that system used for | 850 // initialization. For example, a thread might be the one that system used for |
| 847 // static initializers - in this case the default isolate is set in TLS but | 851 // static initializers - in this case the default isolate is set in TLS but |
| (...skipping 17 matching lines...) Expand all Loading... |
| 865 CHECK(PreInit()); | 869 CHECK(PreInit()); |
| 866 | 870 |
| 867 // In case it's the first time some thread enters the isolate. | 871 // In case it's the first time some thread enters the isolate. |
| 868 set_thread_id(data->thread_id()); | 872 set_thread_id(data->thread_id()); |
| 869 } | 873 } |
| 870 | 874 |
| 871 | 875 |
| 872 void Isolate::Exit() { | 876 void Isolate::Exit() { |
| 873 ASSERT(entry_stack_ != NULL); | 877 ASSERT(entry_stack_ != NULL); |
| 874 ASSERT(entry_stack_->previous_thread_data == NULL || | 878 ASSERT(entry_stack_->previous_thread_data == NULL || |
| 875 entry_stack_->previous_thread_data->thread_id() == | 879 entry_stack_->previous_thread_data->thread_id().Equals( |
| 876 Thread::GetThreadLocalInt(thread_id_key_)); | 880 ThreadId::Current())); |
| 877 | 881 |
| 878 if (--entry_stack_->entry_count > 0) return; | 882 if (--entry_stack_->entry_count > 0) return; |
| 879 | 883 |
| 880 ASSERT(CurrentPerIsolateThreadData() != NULL); | 884 ASSERT(CurrentPerIsolateThreadData() != NULL); |
| 881 ASSERT(CurrentPerIsolateThreadData()->isolate_ == this); | 885 ASSERT(CurrentPerIsolateThreadData()->isolate_ == this); |
| 882 | 886 |
| 883 // Pop the stack. | 887 // Pop the stack. |
| 884 EntryStackItem* item = entry_stack_; | 888 EntryStackItem* item = entry_stack_; |
| 885 entry_stack_ = item->previous_item; | 889 entry_stack_ = item->previous_item; |
| 886 | 890 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 901 | 905 |
| 902 #ifdef DEBUG | 906 #ifdef DEBUG |
| 903 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ | 907 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ |
| 904 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); | 908 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); |
| 905 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) | 909 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) |
| 906 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) | 910 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) |
| 907 #undef ISOLATE_FIELD_OFFSET | 911 #undef ISOLATE_FIELD_OFFSET |
| 908 #endif | 912 #endif |
| 909 | 913 |
| 910 } } // namespace v8::internal | 914 } } // namespace v8::internal |
| OLD | NEW |