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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 // that may be collected in the same GC cycle. If you cannot avoid touching | 72 // that may be collected in the same GC cycle. If you cannot avoid touching |
73 // on-heap objects in a destructor (which is not allowed), you can consider | 73 // on-heap objects in a destructor (which is not allowed), you can consider |
74 // using the pre-finalizer. The only restriction is that the pre-finalizer | 74 // using the pre-finalizer. The only restriction is that the pre-finalizer |
75 // must not resurrect dead objects (e.g., store unmarked objects into | 75 // must not resurrect dead objects (e.g., store unmarked objects into |
76 // Members etc). The pre-finalizer is called on the thread that registered | 76 // Members etc). The pre-finalizer is called on the thread that registered |
77 // the pre-finalizer. | 77 // the pre-finalizer. |
78 // | 78 // |
79 // Since a pre-finalizer adds pressure on GC performance, you should use it | 79 // Since a pre-finalizer adds pressure on GC performance, you should use it |
80 // only if necessary. | 80 // only if necessary. |
81 // | 81 // |
82 // A pre-finalizer is similar to the HeapHashMap<WeakMember<Foo>, std::unique_pt
r<Disposer>> | 82 // A pre-finalizer is similar to the |
83 // idiom. The difference between this and the idiom is that pre-finalizer | 83 // HeapHashMap<WeakMember<Foo>, std::unique_ptr<Disposer>> idiom. The |
84 // function is called whenever an object is destructed with this feature. The | 84 // difference between this and the idiom is that pre-finalizer function is |
85 // HeapHashMap<WeakMember<Foo>, std::unique_ptr<Disposer>> idiom requires an ass
umption | 85 // called whenever an object is destructed with this feature. The |
86 // that the HeapHashMap outlives objects pointed by WeakMembers. | 86 // HeapHashMap<WeakMember<Foo>, std::unique_ptr<Disposer>> idiom requires an |
87 // FIXME: Replace all of the HeapHashMap<WeakMember<Foo>, std::unique_ptr<Dispos
er>> | 87 // assumption that the HeapHashMap outlives objects pointed by WeakMembers. |
88 // idiom usages with the pre-finalizer if the replacement won't cause | 88 // FIXME: Replace all of the |
89 // performance regressions. | 89 // HeapHashMap<WeakMember<Foo>, std::unique_ptr<Disposer>> idiom usages with the |
| 90 // pre-finalizer if the replacement won't cause performance regressions. |
90 // | 91 // |
91 // Usage: | 92 // Usage: |
92 // | 93 // |
93 // class Foo : GarbageCollected<Foo> { | 94 // class Foo : GarbageCollected<Foo> { |
94 // USING_PRE_FINALIZER(Foo, dispose); | 95 // USING_PRE_FINALIZER(Foo, dispose); |
95 // public: | 96 // public: |
96 // Foo() | 97 // Foo() |
97 // { | 98 // { |
98 // ThreadState::current()->registerPreFinalizer(this); | 99 // ThreadState::current()->registerPreFinalizer(this); |
99 // } | 100 // } |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 // We say that a thread is at a safepoint if this thread is guaranteed to | 312 // We say that a thread is at a safepoint if this thread is guaranteed to |
312 // not touch any heap allocated object or any heap related functionality until | 313 // not touch any heap allocated object or any heap related functionality until |
313 // it leaves the safepoint. | 314 // it leaves the safepoint. |
314 // | 315 // |
315 // Notice that a thread does not have to be paused if it is at safepoint it | 316 // Notice that a thread does not have to be paused if it is at safepoint it |
316 // can continue to run and perform tasks that do not require interaction | 317 // can continue to run and perform tasks that do not require interaction |
317 // with the heap. It will be paused if it attempts to leave the safepoint and | 318 // with the heap. It will be paused if it attempts to leave the safepoint and |
318 // there is a GC in progress. | 319 // there is a GC in progress. |
319 // | 320 // |
320 // Each thread that has ThreadState attached must: | 321 // Each thread that has ThreadState attached must: |
321 // - periodically check if GC is requested from another thread by calling a
safePoint() method; | 322 // - periodically check if GC is requested from another thread by calling a |
322 // - use SafePointScope around long running loops that have no safePoint() i
nvocation inside, | 323 // safePoint() method; |
323 // such loops must not touch any heap object; | 324 // - use SafePointScope around long running loops that have no safePoint() |
324 // - register an BlinkGCInterruptor that can interrupt long running loops th
at have no calls to safePoint and | 325 // invocation inside, such loops must not touch any heap object; |
325 // are not wrapped in a SafePointScope (e.g. BlinkGCInterruptor for JavaSc
ript code) | 326 // - register an BlinkGCInterruptor that can interrupt long running loops |
| 327 // that have no calls to safePoint and are not wrapped in a SafePointScope |
| 328 // (e.g. BlinkGCInterruptor for JavaScript code) |
326 // | 329 // |
327 | 330 |
328 // Check if GC is requested by another thread and pause this thread if this is
the case. | 331 // Check if GC is requested by another thread and pause this thread if this is |
329 // Can only be called when current thread is in a consistent state. | 332 // the case. Can only be called when current thread is in a consistent state. |
330 void safePoint(BlinkGC::StackState); | 333 void safePoint(BlinkGC::StackState); |
331 | 334 |
332 // Mark current thread as running inside safepoint. | 335 // Mark current thread as running inside safepoint. |
333 void enterSafePoint(BlinkGC::StackState, void*); | 336 void enterSafePoint(BlinkGC::StackState, void*); |
334 void leaveSafePoint(SafePointAwareMutexLocker* = nullptr); | 337 void leaveSafePoint(SafePointAwareMutexLocker* = nullptr); |
335 bool isAtSafePoint() const { return m_atSafePoint; } | 338 bool isAtSafePoint() const { return m_atSafePoint; } |
336 | 339 |
337 void addInterruptor(std::unique_ptr<BlinkGCInterruptor>); | 340 void addInterruptor(std::unique_ptr<BlinkGCInterruptor>); |
338 | 341 |
339 void recordStackEnd(intptr_t* endOfStack) { m_endOfStack = endOfStack; } | 342 void recordStackEnd(intptr_t* endOfStack) { m_endOfStack = endOfStack; } |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 } | 454 } |
452 void leaveGCForbiddenScopeIfNeeded( | 455 void leaveGCForbiddenScopeIfNeeded( |
453 GarbageCollectedMixinConstructorMarker* gcMixinMarker) { | 456 GarbageCollectedMixinConstructorMarker* gcMixinMarker) { |
454 ASSERT(checkThread()); | 457 ASSERT(checkThread()); |
455 if (m_gcMixinMarker == gcMixinMarker) { | 458 if (m_gcMixinMarker == gcMixinMarker) { |
456 leaveGCForbiddenScope(); | 459 leaveGCForbiddenScope(); |
457 m_gcMixinMarker = nullptr; | 460 m_gcMixinMarker = nullptr; |
458 } | 461 } |
459 } | 462 } |
460 | 463 |
461 // vectorBackingArena() returns an arena that the vector allocation should use
. | 464 // vectorBackingArena() returns an arena that the vector allocation should |
462 // We have four vector arenas and want to choose the best arena here. | 465 // use. We have four vector arenas and want to choose the best arena here. |
463 // | 466 // |
464 // The goal is to improve the succession rate where expand and | 467 // The goal is to improve the succession rate where expand and |
465 // promptlyFree happen at an allocation point. This is a key for reusing | 468 // promptlyFree happen at an allocation point. This is a key for reusing |
466 // the same memory as much as possible and thus improves performance. | 469 // the same memory as much as possible and thus improves performance. |
467 // To achieve the goal, we use the following heuristics: | 470 // To achieve the goal, we use the following heuristics: |
468 // | 471 // |
469 // - A vector that has been expanded recently is likely to be expanded | 472 // - A vector that has been expanded recently is likely to be expanded |
470 // again soon. | 473 // again soon. |
471 // - A vector is likely to be promptly freed if the same type of vector | 474 // - A vector is likely to be promptly freed if the same type of vector |
472 // has been frequently promptly freed in the past. | 475 // has been frequently promptly freed in the past. |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
547 explicit ThreadState(BlinkGC::ThreadHeapMode); | 550 explicit ThreadState(BlinkGC::ThreadHeapMode); |
548 ~ThreadState(); | 551 ~ThreadState(); |
549 | 552 |
550 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope(); | 553 NO_SANITIZE_ADDRESS void copyStackUntilSafePointScope(); |
551 void clearSafePointScopeMarker() { | 554 void clearSafePointScopeMarker() { |
552 m_safePointStackCopy.clear(); | 555 m_safePointStackCopy.clear(); |
553 m_safePointScopeMarker = nullptr; | 556 m_safePointScopeMarker = nullptr; |
554 } | 557 } |
555 | 558 |
556 // shouldSchedule{Precise,Idle}GC and shouldForceConservativeGC | 559 // shouldSchedule{Precise,Idle}GC and shouldForceConservativeGC |
557 // implement the heuristics that are used to determine when to collect garbage
. | 560 // implement the heuristics that are used to determine when to collect |
| 561 // garbage. |
558 // If shouldForceConservativeGC returns true, we force the garbage | 562 // If shouldForceConservativeGC returns true, we force the garbage |
559 // collection immediately. Otherwise, if should*GC returns true, we | 563 // collection immediately. Otherwise, if should*GC returns true, we |
560 // record that we should garbage collect the next time we return | 564 // record that we should garbage collect the next time we return |
561 // to the event loop. If both return false, we don't need to | 565 // to the event loop. If both return false, we don't need to |
562 // collect garbage at this point. | 566 // collect garbage at this point. |
563 bool shouldScheduleIdleGC(); | 567 bool shouldScheduleIdleGC(); |
564 bool shouldSchedulePreciseGC(); | 568 bool shouldSchedulePreciseGC(); |
565 bool shouldForceConservativeGC(); | 569 bool shouldForceConservativeGC(); |
566 // V8 minor or major GC is likely to drop a lot of references to objects | 570 // V8 minor or major GC is likely to drop a lot of references to objects |
567 // on Oilpan's heap. We give a chance to schedule a GC. | 571 // on Oilpan's heap. We give a chance to schedule a GC. |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 class ThreadStateFor<AnyThread> { | 730 class ThreadStateFor<AnyThread> { |
727 STATIC_ONLY(ThreadStateFor); | 731 STATIC_ONLY(ThreadStateFor); |
728 | 732 |
729 public: | 733 public: |
730 static ThreadState* state() { return ThreadState::current(); } | 734 static ThreadState* state() { return ThreadState::current(); } |
731 }; | 735 }; |
732 | 736 |
733 } // namespace blink | 737 } // namespace blink |
734 | 738 |
735 #endif // ThreadState_h | 739 #endif // ThreadState_h |
OLD | NEW |