OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 | 45 |
46 class BaseHeap; | 46 class BaseHeap; |
47 class BaseHeapPage; | 47 class BaseHeapPage; |
48 class FinalizedHeapObjectHeader; | 48 class FinalizedHeapObjectHeader; |
49 struct GCInfo; | 49 struct GCInfo; |
50 class HeapContainsCache; | 50 class HeapContainsCache; |
51 class HeapObjectHeader; | 51 class HeapObjectHeader; |
52 class PersistentNode; | 52 class PersistentNode; |
53 class Visitor; | 53 class Visitor; |
54 class SafePointBarrier; | 54 class SafePointBarrier; |
| 55 class SafePointAwareMutexLocker; |
55 template<typename Header> class ThreadHeap; | 56 template<typename Header> class ThreadHeap; |
56 class CallbackStack; | 57 class CallbackStack; |
57 | 58 |
58 typedef uint8_t* Address; | 59 typedef uint8_t* Address; |
59 | 60 |
60 typedef void (*FinalizationCallback)(void*); | 61 typedef void (*FinalizationCallback)(void*); |
61 typedef void (*VisitorCallback)(Visitor*, void* self); | 62 typedef void (*VisitorCallback)(Visitor*, void* self); |
62 typedef VisitorCallback TraceCallback; | 63 typedef VisitorCallback TraceCallback; |
63 typedef VisitorCallback WeakPointerCallback; | 64 typedef VisitorCallback WeakPointerCallback; |
64 | 65 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 static bool stopThreads(); | 363 static bool stopThreads(); |
363 static void resumeThreads(); | 364 static void resumeThreads(); |
364 | 365 |
365 // Check if GC is requested by another thread and pause this thread if this
is the case. | 366 // Check if GC is requested by another thread and pause this thread if this
is the case. |
366 // Can only be called when current thread is in a consistent state. | 367 // Can only be called when current thread is in a consistent state. |
367 void safePoint(StackState); | 368 void safePoint(StackState); |
368 | 369 |
369 // Mark current thread as running inside safepoint. | 370 // Mark current thread as running inside safepoint. |
370 void enterSafePointWithoutPointers() { enterSafePoint(NoHeapPointersOnStack,
0); } | 371 void enterSafePointWithoutPointers() { enterSafePoint(NoHeapPointersOnStack,
0); } |
371 void enterSafePointWithPointers(void* scopeMarker) { enterSafePoint(HeapPoin
tersOnStack, scopeMarker); } | 372 void enterSafePointWithPointers(void* scopeMarker) { enterSafePoint(HeapPoin
tersOnStack, scopeMarker); } |
372 void leaveSafePoint(); | 373 void leaveSafePoint(SafePointAwareMutexLocker* = 0); |
373 bool isAtSafePoint() const { return m_atSafePoint; } | 374 bool isAtSafePoint() const { return m_atSafePoint; } |
374 | 375 |
375 class SafePointScope { | 376 class SafePointScope { |
376 public: | 377 public: |
377 enum ScopeNesting { | 378 enum ScopeNesting { |
378 NoNesting, | 379 NoNesting, |
379 AllowNesting | 380 AllowNesting |
380 }; | 381 }; |
381 | 382 |
382 explicit SafePointScope(StackState stackState, ScopeNesting nesting = No
Nesting) | 383 explicit SafePointScope(StackState stackState, ScopeNesting nesting = No
Nesting) |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
503 | 504 |
504 void getStats(HeapStats&); | 505 void getStats(HeapStats&); |
505 HeapStats& stats() { return m_stats; } | 506 HeapStats& stats() { return m_stats; } |
506 HeapStats& statsAfterLastGC() { return m_statsAfterLastGC; } | 507 HeapStats& statsAfterLastGC() { return m_statsAfterLastGC; } |
507 | 508 |
508 private: | 509 private: |
509 explicit ThreadState(); | 510 explicit ThreadState(); |
510 ~ThreadState(); | 511 ~ThreadState(); |
511 | 512 |
512 friend class SafePointBarrier; | 513 friend class SafePointBarrier; |
| 514 friend class SafePointAwareMutexLocker; |
513 | 515 |
514 void enterSafePoint(StackState, void*); | 516 void enterSafePoint(StackState, void*); |
515 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope(); | 517 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope(); |
516 void clearSafePointScopeMarker() | 518 void clearSafePointScopeMarker() |
517 { | 519 { |
518 m_safePointStackCopy.clear(); | 520 m_safePointStackCopy.clear(); |
519 m_safePointScopeMarker = 0; | 521 m_safePointScopeMarker = 0; |
520 } | 522 } |
521 | 523 |
522 void performPendingGC(StackState); | 524 void performPendingGC(StackState); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
594 ASSERT(ThreadState::current()->isMainThread()); | 596 ASSERT(ThreadState::current()->isMainThread()); |
595 return ThreadState::mainThreadState(); | 597 return ThreadState::mainThreadState(); |
596 } | 598 } |
597 }; | 599 }; |
598 | 600 |
599 template<> class ThreadStateFor<AnyThread> { | 601 template<> class ThreadStateFor<AnyThread> { |
600 public: | 602 public: |
601 static ThreadState* state() { return ThreadState::current(); } | 603 static ThreadState* state() { return ThreadState::current(); } |
602 }; | 604 }; |
603 | 605 |
| 606 // The SafePointAwareMutexLocker is used to enter a safepoint while waiting for |
| 607 // a mutex lock. It also ensures that the lock is not held while waiting for a G
C |
| 608 // to complete in the leaveSafePoint method, by releasing the lock if the |
| 609 // leaveSafePoint method cannot complete without blocking, see |
| 610 // SafePointBarrier::checkAndPark. |
| 611 class SafePointAwareMutexLocker { |
| 612 WTF_MAKE_NONCOPYABLE(SafePointAwareMutexLocker); |
| 613 public: |
| 614 explicit SafePointAwareMutexLocker(Mutex& mutex) : m_mutex(mutex), m_locked(
false) |
| 615 { |
| 616 ThreadState* state = ThreadState::current(); |
| 617 do { |
| 618 bool leaveSafePoint = false; |
| 619 if (!state->isAtSafePoint()) { |
| 620 state->enterSafePoint(ThreadState::HeapPointersOnStack, this); |
| 621 leaveSafePoint = true; |
| 622 } |
| 623 m_mutex.lock(); |
| 624 m_locked = true; |
| 625 if (leaveSafePoint) { |
| 626 // When leaving the safepoint we might end up release the mutex |
| 627 // if another thread is requesting a GC, see |
| 628 // SafePointBarrier::checkAndPark. This is the case where we |
| 629 // loop around to reacquire the lock. |
| 630 state->leaveSafePoint(this); |
| 631 } |
| 632 } while (!m_locked); |
| 633 } |
| 634 |
| 635 ~SafePointAwareMutexLocker() |
| 636 { |
| 637 ASSERT(m_locked); |
| 638 m_mutex.unlock(); |
| 639 } |
| 640 |
| 641 private: |
| 642 friend class SafePointBarrier; |
| 643 |
| 644 void reset() |
| 645 { |
| 646 ASSERT(m_locked); |
| 647 m_mutex.unlock(); |
| 648 m_locked = false; |
| 649 } |
| 650 |
| 651 Mutex& m_mutex; |
| 652 bool m_locked; |
| 653 }; |
| 654 |
604 } | 655 } |
605 | 656 |
606 #endif // ThreadState_h | 657 #endif // ThreadState_h |
OLD | NEW |