OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 20 matching lines...) Expand all Loading... | |
31 | 31 |
32 #include "ast.h" | 32 #include "ast.h" |
33 #include "bootstrapper.h" | 33 #include "bootstrapper.h" |
34 #include "codegen.h" | 34 #include "codegen.h" |
35 #include "compilation-cache.h" | 35 #include "compilation-cache.h" |
36 #include "debug.h" | 36 #include "debug.h" |
37 #include "deoptimizer.h" | 37 #include "deoptimizer.h" |
38 #include "heap-profiler.h" | 38 #include "heap-profiler.h" |
39 #include "hydrogen.h" | 39 #include "hydrogen.h" |
40 #include "isolate.h" | 40 #include "isolate.h" |
41 #include "lazy-instance.h" | |
42 #include "lithium-allocator.h" | 41 #include "lithium-allocator.h" |
43 #include "log.h" | 42 #include "log.h" |
44 #include "messages.h" | 43 #include "messages.h" |
45 #include "platform.h" | 44 #include "platform.h" |
46 #include "regexp-stack.h" | 45 #include "regexp-stack.h" |
47 #include "runtime-profiler.h" | 46 #include "runtime-profiler.h" |
48 #include "scopeinfo.h" | 47 #include "scopeinfo.h" |
49 #include "serialize.h" | 48 #include "serialize.h" |
50 #include "simulator.h" | 49 #include "simulator.h" |
51 #include "spaces.h" | 50 #include "spaces.h" |
52 #include "stub-cache.h" | 51 #include "stub-cache.h" |
53 #include "version.h" | 52 #include "version.h" |
54 #include "vm-state-inl.h" | 53 #include "vm-state-inl.h" |
55 | 54 |
56 | 55 |
57 namespace v8 { | 56 namespace v8 { |
58 namespace internal { | 57 namespace internal { |
59 | 58 |
60 struct GlobalState { | |
61 Thread::LocalStorageKey per_isolate_thread_data_key; | |
62 Thread::LocalStorageKey isolate_key; | |
63 Thread::LocalStorageKey thread_id_key; | |
64 Isolate* default_isolate; | |
65 Isolate::ThreadDataTable* thread_data_table; | |
66 Mutex* mutex; | |
67 }; | |
68 | |
69 struct InitializeGlobalState { | |
70 static void Construct(GlobalState* state) { | |
71 state->isolate_key = Thread::CreateThreadLocalKey(); | |
72 state->thread_id_key = Thread::CreateThreadLocalKey(); | |
73 state->per_isolate_thread_data_key = Thread::CreateThreadLocalKey(); | |
74 state->thread_data_table = new Isolate::ThreadDataTable(); | |
75 state->default_isolate = new Isolate(); | |
76 state->mutex = OS::CreateMutex(); | |
77 // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here | |
78 // because a non-null thread data may be already set. | |
79 Thread::SetThreadLocal(state->isolate_key, state->default_isolate); | |
80 } | |
81 }; | |
82 | |
83 static LazyInstance<GlobalState, InitializeGlobalState>::type global_state; | |
84 | |
85 Atomic32 ThreadId::highest_thread_id_ = 0; | 59 Atomic32 ThreadId::highest_thread_id_ = 0; |
86 | 60 |
87 int ThreadId::AllocateThreadId() { | 61 int ThreadId::AllocateThreadId() { |
88 int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1); | 62 int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1); |
89 return new_id; | 63 return new_id; |
90 } | 64 } |
91 | 65 |
92 | 66 |
93 int ThreadId::GetCurrentThreadId() { | 67 int ThreadId::GetCurrentThreadId() { |
94 const GlobalState& global = global_state.Get(); | 68 int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_); |
95 int thread_id = Thread::GetThreadLocalInt(global.thread_id_key); | |
96 if (thread_id == 0) { | 69 if (thread_id == 0) { |
97 thread_id = AllocateThreadId(); | 70 thread_id = AllocateThreadId(); |
98 Thread::SetThreadLocalInt(global.thread_id_key, thread_id); | 71 Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id); |
99 } | 72 } |
100 return thread_id; | 73 return thread_id; |
101 } | 74 } |
102 | 75 |
103 | 76 |
104 ThreadLocalTop::ThreadLocalTop() { | 77 ThreadLocalTop::ThreadLocalTop() { |
105 InitializeInternal(); | 78 InitializeInternal(); |
106 // This flag may be set using v8::V8::IgnoreOutOfMemoryException() | 79 // This flag may be set using v8::V8::IgnoreOutOfMemoryException() |
107 // before an isolate is initialized. The initialize methods below do | 80 // before an isolate is initialized. The initialize methods below do |
108 // not touch it to preserve its value. | 81 // not touch it to preserve its value. |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
332 FreeStoreAllocationPolicy::Delete(p); | 305 FreeStoreAllocationPolicy::Delete(p); |
333 return; | 306 return; |
334 } | 307 } |
335 PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1; | 308 PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1; |
336 ASSERT(storage->next_->previous_ == storage); | 309 ASSERT(storage->next_->previous_ == storage); |
337 ASSERT(storage->previous_->next_ == storage); | 310 ASSERT(storage->previous_->next_ == storage); |
338 storage->Unlink(); | 311 storage->Unlink(); |
339 storage->LinkTo(&free_list_); | 312 storage->LinkTo(&free_list_); |
340 } | 313 } |
341 | 314 |
315 Isolate* Isolate::default_isolate_ = NULL; | |
316 Thread::LocalStorageKey Isolate::isolate_key_; | |
317 Thread::LocalStorageKey Isolate::thread_id_key_; | |
318 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; | |
319 Mutex* Isolate::process_wide_mutex_ = NULL; | |
320 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL; | |
321 | |
322 | |
342 Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData( | 323 Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData( |
343 ThreadId thread_id) { | 324 ThreadId thread_id) { |
344 ASSERT(!thread_id.Equals(ThreadId::Invalid())); | 325 ASSERT(!thread_id.Equals(ThreadId::Invalid())); |
345 PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id); | 326 PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id); |
346 { | 327 { |
347 GlobalState* const global = global_state.Pointer(); | 328 ScopedLock lock(process_wide_mutex_); |
348 ScopedLock lock(global->mutex); | 329 ASSERT(thread_data_table_->Lookup(this, thread_id) == NULL); |
349 ASSERT(global->thread_data_table->Lookup(this, thread_id) == NULL); | 330 thread_data_table_->Insert(per_thread); |
350 global->thread_data_table->Insert(per_thread); | 331 ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread); |
351 ASSERT(global->thread_data_table->Lookup(this, thread_id) == per_thread); | |
352 } | 332 } |
353 return per_thread; | 333 return per_thread; |
354 } | 334 } |
355 | 335 |
356 | 336 |
357 Isolate::PerIsolateThreadData* | 337 Isolate::PerIsolateThreadData* |
358 Isolate::FindOrAllocatePerThreadDataForThisThread() { | 338 Isolate::FindOrAllocatePerThreadDataForThisThread() { |
359 ThreadId thread_id = ThreadId::Current(); | 339 ThreadId thread_id = ThreadId::Current(); |
360 PerIsolateThreadData* per_thread = NULL; | 340 PerIsolateThreadData* per_thread = NULL; |
361 { | 341 { |
362 GlobalState* const global = global_state.Pointer(); | 342 ScopedLock lock(process_wide_mutex_); |
363 ScopedLock lock(global->mutex); | 343 per_thread = thread_data_table_->Lookup(this, thread_id); |
364 per_thread = global->thread_data_table->Lookup(this, thread_id); | |
365 if (per_thread == NULL) { | 344 if (per_thread == NULL) { |
366 per_thread = AllocatePerIsolateThreadData(thread_id); | 345 per_thread = AllocatePerIsolateThreadData(thread_id); |
367 } | 346 } |
368 } | 347 } |
369 return per_thread; | 348 return per_thread; |
370 } | 349 } |
371 | 350 |
372 | 351 |
373 Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() { | 352 Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() { |
374 ThreadId thread_id = ThreadId::Current(); | 353 ThreadId thread_id = ThreadId::Current(); |
375 PerIsolateThreadData* per_thread = NULL; | 354 PerIsolateThreadData* per_thread = NULL; |
376 { | 355 { |
377 GlobalState* const global = global_state.Pointer(); | 356 ScopedLock lock(process_wide_mutex_); |
378 ScopedLock lock(global->mutex); | 357 per_thread = thread_data_table_->Lookup(this, thread_id); |
379 per_thread = global->thread_data_table->Lookup(this, thread_id); | |
380 } | 358 } |
381 return per_thread; | 359 return per_thread; |
382 } | 360 } |
383 | 361 |
384 | 362 |
385 bool Isolate::IsDefaultIsolate() const { | |
386 return this == global_state.Get().default_isolate; | |
387 } | |
388 | |
389 | |
390 void Isolate::EnsureDefaultIsolate() { | 363 void Isolate::EnsureDefaultIsolate() { |
391 GlobalState* const global = global_state.Pointer(); | 364 ScopedLock lock(process_wide_mutex_); |
365 if (default_isolate_ == NULL) { | |
366 isolate_key_ = Thread::CreateThreadLocalKey(); | |
367 thread_id_key_ = Thread::CreateThreadLocalKey(); | |
368 per_isolate_thread_data_key_ = Thread::CreateThreadLocalKey(); | |
369 thread_data_table_ = new Isolate::ThreadDataTable(); | |
370 default_isolate_ = new Isolate(); | |
371 } | |
392 // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here | 372 // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here |
393 // because a non-null thread data may be already set. | 373 // becase a non-null thread data may be already set. |
danno
2012/03/29 12:32:42
nit: because
Philippe
2012/03/29 13:06:53
Done.
| |
394 if (Thread::GetThreadLocal(global->isolate_key) == NULL) { | 374 if (Thread::GetThreadLocal(isolate_key_) == NULL) { |
395 Thread::SetThreadLocal(global->isolate_key, global->default_isolate); | 375 Thread::SetThreadLocal(isolate_key_, default_isolate_); |
396 } | 376 } |
397 } | 377 } |
398 | 378 |
399 | 379 |
400 #ifdef ENABLE_DEBUGGER_SUPPORT | 380 #ifdef ENABLE_DEBUGGER_SUPPORT |
401 Debugger* Isolate::GetDefaultIsolateDebugger() { | 381 Debugger* Isolate::GetDefaultIsolateDebugger() { |
402 EnsureDefaultIsolate(); | 382 EnsureDefaultIsolate(); |
403 return global_state.Pointer()->default_isolate->debugger(); | 383 return default_isolate_->debugger(); |
404 } | 384 } |
405 #endif | 385 #endif |
406 | 386 |
407 | 387 |
408 StackGuard* Isolate::GetDefaultIsolateStackGuard() { | 388 StackGuard* Isolate::GetDefaultIsolateStackGuard() { |
409 EnsureDefaultIsolate(); | 389 EnsureDefaultIsolate(); |
410 return global_state.Pointer()->default_isolate->stack_guard(); | 390 return default_isolate_->stack_guard(); |
411 } | |
412 | |
413 | |
414 Thread::LocalStorageKey Isolate::isolate_key() { | |
415 return global_state.Get().isolate_key; | |
416 } | |
417 | |
418 | |
419 Thread::LocalStorageKey Isolate::thread_id_key() { | |
420 return global_state.Get().thread_id_key; | |
421 } | |
422 | |
423 | |
424 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key() { | |
425 return global_state.Get().per_isolate_thread_data_key; | |
426 } | 391 } |
427 | 392 |
428 | 393 |
429 void Isolate::EnterDefaultIsolate() { | 394 void Isolate::EnterDefaultIsolate() { |
430 EnsureDefaultIsolate(); | 395 EnsureDefaultIsolate(); |
431 Isolate* const default_isolate = global_state.Pointer()->default_isolate; | 396 ASSERT(default_isolate_ != NULL); |
432 ASSERT(default_isolate != NULL); | |
433 | 397 |
434 PerIsolateThreadData* data = CurrentPerIsolateThreadData(); | 398 PerIsolateThreadData* data = CurrentPerIsolateThreadData(); |
435 // If not yet in default isolate - enter it. | 399 // If not yet in default isolate - enter it. |
436 if (data == NULL || data->isolate() != default_isolate) { | 400 if (data == NULL || data->isolate() != default_isolate_) { |
437 default_isolate->Enter(); | 401 default_isolate_->Enter(); |
438 } | 402 } |
439 } | 403 } |
440 | 404 |
441 | 405 |
442 Isolate* Isolate::GetDefaultIsolateForLocking() { | 406 Isolate* Isolate::GetDefaultIsolateForLocking() { |
443 EnsureDefaultIsolate(); | 407 EnsureDefaultIsolate(); |
444 return global_state.Pointer()->default_isolate; | 408 return default_isolate_; |
445 } | 409 } |
446 | 410 |
447 | 411 |
448 Address Isolate::get_address_from_id(Isolate::AddressId id) { | 412 Address Isolate::get_address_from_id(Isolate::AddressId id) { |
449 return isolate_addresses_[id]; | 413 return isolate_addresses_[id]; |
450 } | 414 } |
451 | 415 |
452 | 416 |
453 char* Isolate::Iterate(ObjectVisitor* v, char* thread_storage) { | 417 char* Isolate::Iterate(ObjectVisitor* v, char* thread_storage) { |
454 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage); | 418 ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage); |
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1557 // Temporarily set this isolate as current so that various parts of | 1521 // Temporarily set this isolate as current so that various parts of |
1558 // the isolate can access it in their destructors without having a | 1522 // the isolate can access it in their destructors without having a |
1559 // direct pointer. We don't use Enter/Exit here to avoid | 1523 // direct pointer. We don't use Enter/Exit here to avoid |
1560 // initializing the thread data. | 1524 // initializing the thread data. |
1561 PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData(); | 1525 PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData(); |
1562 Isolate* saved_isolate = UncheckedCurrent(); | 1526 Isolate* saved_isolate = UncheckedCurrent(); |
1563 SetIsolateThreadLocals(this, NULL); | 1527 SetIsolateThreadLocals(this, NULL); |
1564 | 1528 |
1565 Deinit(); | 1529 Deinit(); |
1566 | 1530 |
1567 { ScopedLock lock(global_state.Pointer()->mutex); | 1531 { ScopedLock lock(process_wide_mutex_); |
1568 global_state.Pointer()->thread_data_table->RemoveAllThreads(this); | 1532 thread_data_table_->RemoveAllThreads(this); |
1569 } | 1533 } |
1570 | 1534 |
1571 if (!IsDefaultIsolate()) { | 1535 if (!IsDefaultIsolate()) { |
1572 delete this; | 1536 delete this; |
1573 } | 1537 } |
1574 | 1538 |
1575 // Restore the previous current isolate. | 1539 // Restore the previous current isolate. |
1576 SetIsolateThreadLocals(saved_isolate, saved_data); | 1540 SetIsolateThreadLocals(saved_isolate, saved_data); |
1577 } | 1541 } |
1578 | 1542 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1611 logger_->TearDown(); | 1575 logger_->TearDown(); |
1612 | 1576 |
1613 // The default isolate is re-initializable due to legacy API. | 1577 // The default isolate is re-initializable due to legacy API. |
1614 state_ = UNINITIALIZED; | 1578 state_ = UNINITIALIZED; |
1615 } | 1579 } |
1616 } | 1580 } |
1617 | 1581 |
1618 | 1582 |
1619 void Isolate::SetIsolateThreadLocals(Isolate* isolate, | 1583 void Isolate::SetIsolateThreadLocals(Isolate* isolate, |
1620 PerIsolateThreadData* data) { | 1584 PerIsolateThreadData* data) { |
1621 const GlobalState& global = global_state.Get(); | 1585 Thread::SetThreadLocal(isolate_key_, isolate); |
1622 Thread::SetThreadLocal(global.isolate_key, isolate); | 1586 Thread::SetThreadLocal(per_isolate_thread_data_key_, data); |
1623 Thread::SetThreadLocal(global.per_isolate_thread_data_key, data); | |
1624 } | 1587 } |
1625 | 1588 |
1626 | 1589 |
1627 Isolate::~Isolate() { | 1590 Isolate::~Isolate() { |
1628 TRACE_ISOLATE(destructor); | 1591 TRACE_ISOLATE(destructor); |
1629 | 1592 |
1630 // Has to be called while counters_ are still alive. | 1593 // Has to be called while counters_ are still alive. |
1631 zone_.DeleteKeptSegment(); | 1594 zone_.DeleteKeptSegment(); |
1632 | 1595 |
1633 delete[] assembler_spare_buffer_; | 1596 delete[] assembler_spare_buffer_; |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1698 | 1661 |
1699 #ifdef ENABLE_DEBUGGER_SUPPORT | 1662 #ifdef ENABLE_DEBUGGER_SUPPORT |
1700 delete debugger_; | 1663 delete debugger_; |
1701 debugger_ = NULL; | 1664 debugger_ = NULL; |
1702 delete debug_; | 1665 delete debug_; |
1703 debug_ = NULL; | 1666 debug_ = NULL; |
1704 #endif | 1667 #endif |
1705 } | 1668 } |
1706 | 1669 |
1707 | 1670 |
1671 void Isolate::GlobalSetup() { | |
1672 if (!process_wide_mutex_) { | |
1673 Isolate::process_wide_mutex_ = OS::CreateMutex(); | |
1674 } | |
1675 EnsureDefaultIsolate(); | |
1676 } | |
1677 | |
1678 | |
1708 void Isolate::InitializeThreadLocal() { | 1679 void Isolate::InitializeThreadLocal() { |
1709 thread_local_top_.isolate_ = this; | 1680 thread_local_top_.isolate_ = this; |
1710 thread_local_top_.Initialize(); | 1681 thread_local_top_.Initialize(); |
1711 } | 1682 } |
1712 | 1683 |
1713 | 1684 |
1714 void Isolate::PropagatePendingExceptionToExternalTryCatch() { | 1685 void Isolate::PropagatePendingExceptionToExternalTryCatch() { |
1715 ASSERT(has_pending_exception()); | 1686 ASSERT(has_pending_exception()); |
1716 | 1687 |
1717 bool external_caught = IsExternallyCaught(); | 1688 bool external_caught = IsExternallyCaught(); |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1973 | 1944 |
1974 #ifdef DEBUG | 1945 #ifdef DEBUG |
1975 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ | 1946 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ |
1976 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); | 1947 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); |
1977 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) | 1948 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) |
1978 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) | 1949 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) |
1979 #undef ISOLATE_FIELD_OFFSET | 1950 #undef ISOLATE_FIELD_OFFSET |
1980 #endif | 1951 #endif |
1981 | 1952 |
1982 } } // namespace v8::internal | 1953 } } // namespace v8::internal |
OLD | NEW |