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 23 matching lines...) Expand all Loading... |
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 "lithium-allocator.h" | 41 #include "lithium-allocator.h" |
42 #include "log.h" | 42 #include "log.h" |
43 #include "messages.h" | 43 #include "messages.h" |
| 44 #include "platform.h" |
44 #include "regexp-stack.h" | 45 #include "regexp-stack.h" |
45 #include "runtime-profiler.h" | 46 #include "runtime-profiler.h" |
46 #include "scopeinfo.h" | 47 #include "scopeinfo.h" |
47 #include "serialize.h" | 48 #include "serialize.h" |
48 #include "simulator.h" | 49 #include "simulator.h" |
49 #include "spaces.h" | 50 #include "spaces.h" |
50 #include "stub-cache.h" | 51 #include "stub-cache.h" |
51 #include "version.h" | 52 #include "version.h" |
52 #include "vm-state-inl.h" | 53 #include "vm-state-inl.h" |
53 | 54 |
54 | 55 |
55 namespace v8 { | 56 namespace v8 { |
56 namespace internal { | 57 namespace internal { |
57 | 58 |
58 Atomic32 ThreadId::highest_thread_id_ = 0; | 59 Atomic32 ThreadId::highest_thread_id_ = 0; |
59 | 60 |
60 int ThreadId::AllocateThreadId() { | 61 int ThreadId::AllocateThreadId() { |
61 int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1); | 62 int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1); |
62 return new_id; | 63 return new_id; |
63 } | 64 } |
64 | 65 |
65 | 66 |
66 int ThreadId::GetCurrentThreadId() { | 67 int ThreadId::GetCurrentThreadId() { |
67 int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_); | 68 int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key()); |
68 if (thread_id == 0) { | 69 if (thread_id == 0) { |
69 thread_id = AllocateThreadId(); | 70 thread_id = AllocateThreadId(); |
70 Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id); | 71 Thread::SetThreadLocalInt(Isolate::thread_id_key(), thread_id); |
71 } | 72 } |
72 return thread_id; | 73 return thread_id; |
73 } | 74 } |
74 | 75 |
75 | 76 |
76 ThreadLocalTop::ThreadLocalTop() { | 77 ThreadLocalTop::ThreadLocalTop() { |
77 InitializeInternal(); | 78 InitializeInternal(); |
78 // This flag may be set using v8::V8::IgnoreOutOfMemoryException() | 79 // This flag may be set using v8::V8::IgnoreOutOfMemoryException() |
79 // before an isolate is initialized. The initialize methods below do | 80 // before an isolate is initialized. The initialize methods below do |
80 // not touch it to preserve its value. | 81 // not touch it to preserve its value. |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 return; | 306 return; |
306 } | 307 } |
307 PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1; | 308 PreallocatedStorage* storage = reinterpret_cast<PreallocatedStorage*>(p) - 1; |
308 ASSERT(storage->next_->previous_ == storage); | 309 ASSERT(storage->next_->previous_ == storage); |
309 ASSERT(storage->previous_->next_ == storage); | 310 ASSERT(storage->previous_->next_ == storage); |
310 storage->Unlink(); | 311 storage->Unlink(); |
311 storage->LinkTo(&free_list_); | 312 storage->LinkTo(&free_list_); |
312 } | 313 } |
313 | 314 |
314 | 315 |
| 316 // This mutex protects highest_thread_id_, thread_data_table_ and |
| 317 // g_default_mutex_. |
| 318 static LazyMutex process_wide_mutex = LAZY_MUTEX_INITIALIZER; |
| 319 |
315 Isolate* Isolate::default_isolate_ = NULL; | 320 Isolate* Isolate::default_isolate_ = NULL; |
316 Thread::LocalStorageKey Isolate::isolate_key_; | 321 Thread::LocalStorageKey Isolate::isolate_key_; |
317 Thread::LocalStorageKey Isolate::thread_id_key_; | 322 Thread::LocalStorageKey Isolate::thread_id_key_; |
318 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; | 323 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; |
319 Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex(); | |
320 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL; | 324 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL; |
321 | 325 |
322 | 326 |
323 class IsolateInitializer { | |
324 public: | |
325 IsolateInitializer() { | |
326 Isolate::EnsureDefaultIsolate(); | |
327 } | |
328 }; | |
329 | |
330 static IsolateInitializer* EnsureDefaultIsolateAllocated() { | |
331 // TODO(isolates): Use the system threading API to do this once? | |
332 static IsolateInitializer static_initializer; | |
333 return &static_initializer; | |
334 } | |
335 | |
336 // This variable only needed to trigger static intialization. | |
337 static IsolateInitializer* static_initializer = EnsureDefaultIsolateAllocated(); | |
338 | |
339 | |
340 | |
341 | |
342 | |
343 Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData( | 327 Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData( |
344 ThreadId thread_id) { | 328 ThreadId thread_id) { |
345 ASSERT(!thread_id.Equals(ThreadId::Invalid())); | 329 ASSERT(!thread_id.Equals(ThreadId::Invalid())); |
346 PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id); | 330 PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id); |
347 { | 331 { |
348 ScopedLock lock(process_wide_mutex_); | 332 ScopedLock lock(process_wide_mutex.Pointer()); |
349 ASSERT(thread_data_table_->Lookup(this, thread_id) == NULL); | 333 ASSERT(thread_data_table()->Lookup(this, thread_id) == NULL); |
350 thread_data_table_->Insert(per_thread); | 334 thread_data_table()->Insert(per_thread); |
351 ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread); | 335 ASSERT(thread_data_table()->Lookup(this, thread_id) == per_thread); |
352 } | 336 } |
353 return per_thread; | 337 return per_thread; |
354 } | 338 } |
355 | 339 |
356 | 340 |
357 Isolate::PerIsolateThreadData* | 341 Isolate::PerIsolateThreadData* |
358 Isolate::FindOrAllocatePerThreadDataForThisThread() { | 342 Isolate::FindOrAllocatePerThreadDataForThisThread() { |
359 ThreadId thread_id = ThreadId::Current(); | 343 ThreadId thread_id = ThreadId::Current(); |
360 PerIsolateThreadData* per_thread = NULL; | 344 PerIsolateThreadData* per_thread = NULL; |
361 { | 345 { |
362 ScopedLock lock(process_wide_mutex_); | 346 ScopedLock lock(process_wide_mutex.Pointer()); |
363 per_thread = thread_data_table_->Lookup(this, thread_id); | 347 per_thread = thread_data_table()->Lookup(this, thread_id); |
364 if (per_thread == NULL) { | 348 if (per_thread == NULL) { |
365 per_thread = AllocatePerIsolateThreadData(thread_id); | 349 per_thread = AllocatePerIsolateThreadData(thread_id); |
366 } | 350 } |
367 } | 351 } |
368 return per_thread; | 352 return per_thread; |
369 } | 353 } |
370 | 354 |
371 | 355 |
372 Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() { | 356 Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() { |
373 ThreadId thread_id = ThreadId::Current(); | 357 ThreadId thread_id = ThreadId::Current(); |
374 PerIsolateThreadData* per_thread = NULL; | 358 PerIsolateThreadData* per_thread = NULL; |
375 { | 359 { |
376 ScopedLock lock(process_wide_mutex_); | 360 ScopedLock lock(process_wide_mutex.Pointer()); |
377 per_thread = thread_data_table_->Lookup(this, thread_id); | 361 per_thread = thread_data_table()->Lookup(this, thread_id); |
378 } | 362 } |
379 return per_thread; | 363 return per_thread; |
380 } | 364 } |
381 | 365 |
382 | 366 |
383 void Isolate::EnsureDefaultIsolate() { | 367 void Isolate::EnsureDefaultIsolate() { |
384 ScopedLock lock(process_wide_mutex_); | 368 ScopedLock lock(process_wide_mutex.Pointer()); |
385 if (default_isolate_ == NULL) { | 369 if (default_isolate_ == NULL) { |
386 isolate_key_ = Thread::CreateThreadLocalKey(); | 370 isolate_key_ = Thread::CreateThreadLocalKey(); |
387 thread_id_key_ = Thread::CreateThreadLocalKey(); | 371 thread_id_key_ = Thread::CreateThreadLocalKey(); |
388 per_isolate_thread_data_key_ = Thread::CreateThreadLocalKey(); | 372 per_isolate_thread_data_key_ = Thread::CreateThreadLocalKey(); |
389 thread_data_table_ = new Isolate::ThreadDataTable(); | 373 thread_data_table_ = new Isolate::ThreadDataTable(); |
390 default_isolate_ = new Isolate(); | 374 default_isolate_ = new Isolate(); |
391 } | 375 } |
392 // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here | 376 // Can't use SetIsolateThreadLocals(default_isolate_, NULL) here |
393 // becase a non-null thread data may be already set. | 377 // becase a non-null thread data may be already set. |
394 if (Thread::GetThreadLocal(isolate_key_) == NULL) { | 378 if (Thread::GetThreadLocal(Isolate::isolate_key_) == NULL) { |
395 Thread::SetThreadLocal(isolate_key_, default_isolate_); | 379 Thread::SetThreadLocal(Isolate::isolate_key_, default_isolate_); |
396 } | 380 } |
397 } | 381 } |
398 | 382 |
399 | 383 |
400 #ifdef ENABLE_DEBUGGER_SUPPORT | 384 #ifdef ENABLE_DEBUGGER_SUPPORT |
401 Debugger* Isolate::GetDefaultIsolateDebugger() { | 385 Debugger* Isolate::GetDefaultIsolateDebugger() { |
402 EnsureDefaultIsolate(); | 386 EnsureDefaultIsolate(); |
403 return default_isolate_->debugger(); | 387 return default_isolate_->debugger(); |
404 } | 388 } |
405 #endif | 389 #endif |
406 | 390 |
407 | 391 |
408 StackGuard* Isolate::GetDefaultIsolateStackGuard() { | 392 StackGuard* Isolate::GetDefaultIsolateStackGuard() { |
409 EnsureDefaultIsolate(); | 393 EnsureDefaultIsolate(); |
410 return default_isolate_->stack_guard(); | 394 return default_isolate_->stack_guard(); |
411 } | 395 } |
412 | 396 |
413 | 397 |
414 void Isolate::EnterDefaultIsolate() { | 398 void Isolate::EnterDefaultIsolate() { |
415 EnsureDefaultIsolate(); | 399 EnsureDefaultIsolate(); |
416 ASSERT(default_isolate_ != NULL); | 400 Isolate* const default_isolate = default_isolate_; |
| 401 ASSERT(default_isolate != NULL); |
417 | 402 |
418 PerIsolateThreadData* data = CurrentPerIsolateThreadData(); | 403 PerIsolateThreadData* data = CurrentPerIsolateThreadData(); |
419 // If not yet in default isolate - enter it. | 404 // If not yet in default isolate - enter it. |
420 if (data == NULL || data->isolate() != default_isolate_) { | 405 if (data == NULL || data->isolate() != default_isolate) { |
421 default_isolate_->Enter(); | 406 default_isolate->Enter(); |
422 } | 407 } |
423 } | 408 } |
424 | 409 |
425 | 410 |
426 Isolate* Isolate::GetDefaultIsolateForLocking() { | 411 Isolate* Isolate::GetDefaultIsolateForLocking() { |
427 EnsureDefaultIsolate(); | 412 EnsureDefaultIsolate(); |
428 return default_isolate_; | 413 return default_isolate_; |
429 } | 414 } |
430 | 415 |
431 | 416 |
(...skipping 1108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1540 // Temporarily set this isolate as current so that various parts of | 1525 // Temporarily set this isolate as current so that various parts of |
1541 // the isolate can access it in their destructors without having a | 1526 // the isolate can access it in their destructors without having a |
1542 // direct pointer. We don't use Enter/Exit here to avoid | 1527 // direct pointer. We don't use Enter/Exit here to avoid |
1543 // initializing the thread data. | 1528 // initializing the thread data. |
1544 PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData(); | 1529 PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData(); |
1545 Isolate* saved_isolate = UncheckedCurrent(); | 1530 Isolate* saved_isolate = UncheckedCurrent(); |
1546 SetIsolateThreadLocals(this, NULL); | 1531 SetIsolateThreadLocals(this, NULL); |
1547 | 1532 |
1548 Deinit(); | 1533 Deinit(); |
1549 | 1534 |
1550 { ScopedLock lock(process_wide_mutex_); | 1535 { ScopedLock lock(process_wide_mutex.Pointer()); |
1551 thread_data_table_->RemoveAllThreads(this); | 1536 thread_data_table()->RemoveAllThreads(this); |
1552 } | 1537 } |
1553 | 1538 |
1554 if (!IsDefaultIsolate()) { | 1539 if (!IsDefaultIsolate()) { |
1555 delete this; | 1540 delete this; |
1556 } | 1541 } |
1557 | 1542 |
1558 // Restore the previous current isolate. | 1543 // Restore the previous current isolate. |
1559 SetIsolateThreadLocals(saved_isolate, saved_data); | 1544 SetIsolateThreadLocals(saved_isolate, saved_data); |
1560 } | 1545 } |
1561 | 1546 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1594 logger_->TearDown(); | 1579 logger_->TearDown(); |
1595 | 1580 |
1596 // The default isolate is re-initializable due to legacy API. | 1581 // The default isolate is re-initializable due to legacy API. |
1597 state_ = UNINITIALIZED; | 1582 state_ = UNINITIALIZED; |
1598 } | 1583 } |
1599 } | 1584 } |
1600 | 1585 |
1601 | 1586 |
1602 void Isolate::SetIsolateThreadLocals(Isolate* isolate, | 1587 void Isolate::SetIsolateThreadLocals(Isolate* isolate, |
1603 PerIsolateThreadData* data) { | 1588 PerIsolateThreadData* data) { |
1604 Thread::SetThreadLocal(isolate_key_, isolate); | 1589 Thread::SetThreadLocal(isolate_key(), isolate); |
1605 Thread::SetThreadLocal(per_isolate_thread_data_key_, data); | 1590 Thread::SetThreadLocal(per_isolate_thread_data_key(), data); |
1606 } | 1591 } |
1607 | 1592 |
1608 | 1593 |
1609 Isolate::~Isolate() { | 1594 Isolate::~Isolate() { |
1610 TRACE_ISOLATE(destructor); | 1595 TRACE_ISOLATE(destructor); |
1611 | 1596 |
1612 // Has to be called while counters_ are still alive. | 1597 // Has to be called while counters_ are still alive. |
1613 zone_.DeleteKeptSegment(); | 1598 zone_.DeleteKeptSegment(); |
1614 | 1599 |
1615 delete[] assembler_spare_buffer_; | 1600 delete[] assembler_spare_buffer_; |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 | 1937 |
1953 #ifdef DEBUG | 1938 #ifdef DEBUG |
1954 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ | 1939 #define ISOLATE_FIELD_OFFSET(type, name, ignored) \ |
1955 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); | 1940 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_); |
1956 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) | 1941 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET) |
1957 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) | 1942 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET) |
1958 #undef ISOLATE_FIELD_OFFSET | 1943 #undef ISOLATE_FIELD_OFFSET |
1959 #endif | 1944 #endif |
1960 | 1945 |
1961 } } // namespace v8::internal | 1946 } } // namespace v8::internal |
OLD | NEW |