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 // mutex lock. It also ensures that the lock is not held while waiting for a GC | |
608 // to complete in the leaveSafePoint method, by releasing the lock if the | |
609 // leaveSafePoint method cannot complete without blocking, see | |
610 // SafePointBarrier::checkAndPark. | |
zerny-chromium
2014/06/17 11:12:56
Nits:
The SafePointAwareMutexLocker is -> SafePoin
wibling-chromium
2014/06/17 12:06:40
Done.
haraken
2014/06/17 12:25:41
... It also ensures that the lock is not held whil
| |
611 class SafePointAwareMutexLocker { | |
612 WTF_MAKE_NONCOPYABLE(SafePointAwareMutexLocker); | |
613 public: | |
614 SafePointAwareMutexLocker(Mutex& mutex) : m_mutex(mutex), m_locked(false) | |
zerny-chromium
2014/06/17 11:12:56
nit: explicit
wibling-chromium
2014/06/17 12:06:40
Done.
| |
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) { | |
haraken
2014/06/17 12:25:41
Do we need |leaveSafePoint|? Probably we can use '
wibling-chromium
2014/06/17 12:38:21
No, unfortunately not since we only want to leave
| |
626 state->leaveSafePoint(this); | |
zerny-chromium
2014/06/17 11:12:56
Maybe add a comment here about "leaveSafePoint" po
wibling-chromium
2014/06/17 12:06:40
Done.
| |
627 } | |
628 } while (!m_locked); | |
629 } | |
630 | |
631 ~SafePointAwareMutexLocker() | |
632 { | |
633 ASSERT(m_locked); | |
634 m_mutex.unlock(); | |
635 } | |
636 | |
637 private: | |
638 friend class SafePointBarrier; | |
639 | |
640 void reset() | |
641 { | |
642 ASSERT(m_locked); | |
643 m_mutex.unlock(); | |
644 m_locked = false; | |
645 } | |
646 | |
647 Mutex& m_mutex; | |
648 bool m_locked; | |
649 }; | |
650 | |
604 } | 651 } |
605 | 652 |
606 #endif // ThreadState_h | 653 #endif // ThreadState_h |
OLD | NEW |