| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 | 51 |
| 52 namespace blink { | 52 namespace blink { |
| 53 | 53 |
| 54 class BasePage; | 54 class BasePage; |
| 55 class CallbackStack; | 55 class CallbackStack; |
| 56 struct GCInfo; | 56 struct GCInfo; |
| 57 class GarbageCollectedMixinConstructorMarker; | 57 class GarbageCollectedMixinConstructorMarker; |
| 58 class HeapObjectHeader; | 58 class HeapObjectHeader; |
| 59 class PersistentNode; | 59 class PersistentNode; |
| 60 class PersistentRegion; | 60 class PersistentRegion; |
| 61 class BaseHeap; | 61 class BaseArena; |
| 62 class SafePointAwareMutexLocker; | 62 class SafePointAwareMutexLocker; |
| 63 class SafePointBarrier; | 63 class SafePointBarrier; |
| 64 class ThreadState; | 64 class ThreadState; |
| 65 class Visitor; | 65 class Visitor; |
| 66 | 66 |
| 67 // Declare that a class has a pre-finalizer. The pre-finalizer is called | 67 // Declare that a class has a pre-finalizer. The pre-finalizer is called |
| 68 // before any object gets swept, so it is safe to touch on-heap objects | 68 // before any object gets swept, so it is safe to touch on-heap objects |
| 69 // that may be collected in the same GC cycle. If you cannot avoid touching | 69 // that may be collected in the same GC cycle. If you cannot avoid touching |
| 70 // on-heap objects in a destructor (which is not allowed), you can consider | 70 // on-heap objects in a destructor (which is not allowed), you can consider |
| 71 // using the pre-finalizer. The only restriction is that the pre-finalizer | 71 // using the pre-finalizer. The only restriction is that the pre-finalizer |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 void removeInterruptor(BlinkGCInterruptor*); | 346 void removeInterruptor(BlinkGCInterruptor*); |
| 347 | 347 |
| 348 void recordStackEnd(intptr_t* endOfStack) | 348 void recordStackEnd(intptr_t* endOfStack) |
| 349 { | 349 { |
| 350 m_endOfStack = endOfStack; | 350 m_endOfStack = endOfStack; |
| 351 } | 351 } |
| 352 | 352 |
| 353 // Get one of the heap structures for this thread. | 353 // Get one of the heap structures for this thread. |
| 354 // The thread heap is split into multiple heap parts based on object types | 354 // The thread heap is split into multiple heap parts based on object types |
| 355 // and object sizes. | 355 // and object sizes. |
| 356 BaseHeap* heap(int heapIndex) const | 356 BaseArena* arena(int arenaIndex) const |
| 357 { | 357 { |
| 358 ASSERT(0 <= heapIndex); | 358 ASSERT(0 <= arenaIndex); |
| 359 ASSERT(heapIndex < BlinkGC::NumberOfHeaps); | 359 ASSERT(arenaIndex < BlinkGC::NumberOfArenas); |
| 360 return m_heaps[heapIndex]; | 360 return m_arenas[arenaIndex]; |
| 361 } | 361 } |
| 362 | 362 |
| 363 #if ENABLE(ASSERT) | 363 #if ENABLE(ASSERT) |
| 364 // Infrastructure to determine if an address is within one of the | 364 // Infrastructure to determine if an address is within one of the |
| 365 // address ranges for the Blink heap. If the address is in the Blink | 365 // address ranges for the Blink heap. If the address is in the Blink |
| 366 // heap the containing heap page is returned. | 366 // heap the containing heap page is returned. |
| 367 BasePage* findPageFromAddress(Address); | 367 BasePage* findPageFromAddress(Address); |
| 368 BasePage* findPageFromAddress(const void* pointer) { return findPageFromAddr
ess(reinterpret_cast<Address>(const_cast<void*>(pointer))); } | 368 BasePage* findPageFromAddress(const void* pointer) { return findPageFromAddr
ess(reinterpret_cast<Address>(const_cast<void*>(pointer))); } |
| 369 #endif | 369 #endif |
| 370 | 370 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 } | 449 } |
| 450 void leaveGCForbiddenScopeIfNeeded(GarbageCollectedMixinConstructorMarker* g
cMixinMarker) | 450 void leaveGCForbiddenScopeIfNeeded(GarbageCollectedMixinConstructorMarker* g
cMixinMarker) |
| 451 { | 451 { |
| 452 ASSERT(checkThread()); | 452 ASSERT(checkThread()); |
| 453 if (m_gcMixinMarker == gcMixinMarker) { | 453 if (m_gcMixinMarker == gcMixinMarker) { |
| 454 leaveGCForbiddenScope(); | 454 leaveGCForbiddenScope(); |
| 455 m_gcMixinMarker = nullptr; | 455 m_gcMixinMarker = nullptr; |
| 456 } | 456 } |
| 457 } | 457 } |
| 458 | 458 |
| 459 // vectorBackingHeap() returns a heap that the vector allocation should use. | 459 // vectorBackingArena() returns a heap that the vector allocation should use
. |
| 460 // We have four vector heaps and want to choose the best heap here. | 460 // We have four vector arenas and want to choose the best heap here. |
| 461 // | 461 // |
| 462 // The goal is to improve the succession rate where expand and | 462 // The goal is to improve the succession rate where expand and |
| 463 // promptlyFree happen at an allocation point. This is a key for reusing | 463 // promptlyFree happen at an allocation point. This is a key for reusing |
| 464 // the same memory as much as possible and thus improves performance. | 464 // the same memory as much as possible and thus improves performance. |
| 465 // To achieve the goal, we use the following heuristics: | 465 // To achieve the goal, we use the following heuristics: |
| 466 // | 466 // |
| 467 // - A vector that has been expanded recently is likely to be expanded | 467 // - A vector that has been expanded recently is likely to be expanded |
| 468 // again soon. | 468 // again soon. |
| 469 // - A vector is likely to be promptly freed if the same type of vector | 469 // - A vector is likely to be promptly freed if the same type of vector |
| 470 // has been frequently promptly freed in the past. | 470 // has been frequently promptly freed in the past. |
| 471 // - Given the above, when allocating a new vector, look at the four vectors | 471 // - Given the above, when allocating a new vector, look at the four vectors |
| 472 // that are placed immediately prior to the allocation point of each heap. | 472 // that are placed immediately prior to the allocation point of each heap. |
| 473 // Choose the heap where the vector is least likely to be expanded | 473 // Choose the heap where the vector is least likely to be expanded |
| 474 // nor promptly freed. | 474 // nor promptly freed. |
| 475 // | 475 // |
| 476 // To implement the heuristics, we add a heapAge to each heap. The heapAge | 476 // To implement the heuristics, we add a arenaAge to each heap. The arenaAge |
| 477 // is updated if: | 477 // is updated if: |
| 478 // | 478 // |
| 479 // - a vector on the heap is expanded; or | 479 // - a vector on the heap is expanded; or |
| 480 // - a vector that meets the condition (*) is allocated on the heap | 480 // - a vector that meets the condition (*) is allocated on the heap |
| 481 // | 481 // |
| 482 // (*) More than 33% of the same type of vectors have been promptly | 482 // (*) More than 33% of the same type of vectors have been promptly |
| 483 // freed since the last GC. | 483 // freed since the last GC. |
| 484 // | 484 // |
| 485 BaseHeap* vectorBackingHeap(size_t gcInfoIndex) | 485 BaseArena* vectorBackingArena(size_t gcInfoIndex) |
| 486 { | 486 { |
| 487 ASSERT(checkThread()); | 487 ASSERT(checkThread()); |
| 488 size_t entryIndex = gcInfoIndex & likelyToBePromptlyFreedArrayMask; | 488 size_t entryIndex = gcInfoIndex & likelyToBePromptlyFreedArrayMask; |
| 489 --m_likelyToBePromptlyFreed[entryIndex]; | 489 --m_likelyToBePromptlyFreed[entryIndex]; |
| 490 int heapIndex = m_vectorBackingHeapIndex; | 490 int arenaIndex = m_vectorBackingArenaIndex; |
| 491 // If m_likelyToBePromptlyFreed[entryIndex] > 0, that means that | 491 // If m_likelyToBePromptlyFreed[entryIndex] > 0, that means that |
| 492 // more than 33% of vectors of the type have been promptly freed | 492 // more than 33% of vectors of the type have been promptly freed |
| 493 // since the last GC. | 493 // since the last GC. |
| 494 if (m_likelyToBePromptlyFreed[entryIndex] > 0) { | 494 if (m_likelyToBePromptlyFreed[entryIndex] > 0) { |
| 495 m_heapAges[heapIndex] = ++m_currentHeapAges; | 495 m_arenaAges[arenaIndex] = ++m_currentArenaAges; |
| 496 m_vectorBackingHeapIndex = heapIndexOfVectorHeapLeastRecentlyExpande
d(BlinkGC::Vector1HeapIndex, BlinkGC::Vector4HeapIndex); | 496 m_vectorBackingArenaIndex = arenaIndexOfVectorArenaLeastRecentlyExpa
nded(BlinkGC::Vector1ArenaIndex, BlinkGC::Vector4ArenaIndex); |
| 497 } | 497 } |
| 498 ASSERT(isVectorHeapIndex(heapIndex)); | 498 ASSERT(isVectorArenaIndex(arenaIndex)); |
| 499 return m_heaps[heapIndex]; | 499 return m_arenas[arenaIndex]; |
| 500 } | 500 } |
| 501 BaseHeap* expandedVectorBackingHeap(size_t gcInfoIndex); | 501 BaseArena* expandedVectorBackingHeap(size_t gcInfoIndex); |
| 502 static bool isVectorHeapIndex(int heapIndex) | 502 static bool isVectorArenaIndex(int arenaIndex) |
| 503 { | 503 { |
| 504 return BlinkGC::Vector1HeapIndex <= heapIndex && heapIndex <= BlinkGC::V
ector4HeapIndex; | 504 return BlinkGC::Vector1ArenaIndex <= arenaIndex && arenaIndex <= BlinkGC
::Vector4ArenaIndex; |
| 505 } | 505 } |
| 506 void allocationPointAdjusted(int heapIndex); | 506 void allocationPointAdjusted(int arenaIndex); |
| 507 void promptlyFreed(size_t gcInfoIndex); | 507 void promptlyFreed(size_t gcInfoIndex); |
| 508 | 508 |
| 509 void accumulateSweepingTime(double time) { m_accumulatedSweepingTime += time
; } | 509 void accumulateSweepingTime(double time) { m_accumulatedSweepingTime += time
; } |
| 510 | 510 |
| 511 #if OS(WIN) && COMPILER(MSVC) | 511 #if OS(WIN) && COMPILER(MSVC) |
| 512 size_t threadStackSize(); | 512 size_t threadStackSize(); |
| 513 #endif | 513 #endif |
| 514 | 514 |
| 515 #if defined(LEAK_SANITIZER) | 515 #if defined(LEAK_SANITIZER) |
| 516 void registerStaticPersistentNode(PersistentNode*); | 516 void registerStaticPersistentNode(PersistentNode*); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 size_t totalMemorySize(); | 574 size_t totalMemorySize(); |
| 575 double heapGrowingRate(); | 575 double heapGrowingRate(); |
| 576 double partitionAllocGrowingRate(); | 576 double partitionAllocGrowingRate(); |
| 577 bool judgeGCThreshold(size_t allocatedObjectSizeThreshold, double heapGrowin
gRateThreshold); | 577 bool judgeGCThreshold(size_t allocatedObjectSizeThreshold, double heapGrowin
gRateThreshold); |
| 578 | 578 |
| 579 void runScheduledGC(BlinkGC::StackState); | 579 void runScheduledGC(BlinkGC::StackState); |
| 580 | 580 |
| 581 void eagerSweep(); | 581 void eagerSweep(); |
| 582 | 582 |
| 583 #if defined(ADDRESS_SANITIZER) | 583 #if defined(ADDRESS_SANITIZER) |
| 584 void poisonEagerHeap(BlinkGC::Poisoning); | 584 void poisonEagerArena(BlinkGC::Poisoning); |
| 585 void poisonAllHeaps(); | 585 void poisonAllHeaps(); |
| 586 #endif | 586 #endif |
| 587 | 587 |
| 588 // When ThreadState is detaching from non-main thread its | 588 // When ThreadState is detaching from non-main thread its |
| 589 // heap is expected to be empty (because it is going away). | 589 // heap is expected to be empty (because it is going away). |
| 590 // Perform registered cleanup tasks and garbage collection | 590 // Perform registered cleanup tasks and garbage collection |
| 591 // to sweep away any objects that are left on this heap. | 591 // to sweep away any objects that are left on this heap. |
| 592 // We assert that nothing must remain after this cleanup. | 592 // We assert that nothing must remain after this cleanup. |
| 593 // If assertion does not hold we crash as we are potentially | 593 // If assertion does not hold we crash as we are potentially |
| 594 // in the dangling pointer situation. | 594 // in the dangling pointer situation. |
| 595 void cleanup(); | 595 void cleanup(); |
| 596 void cleanupPages(); | 596 void cleanupPages(); |
| 597 | 597 |
| 598 void prepareForThreadStateTermination(); | 598 void prepareForThreadStateTermination(); |
| 599 | 599 |
| 600 void invokePreFinalizers(); | 600 void invokePreFinalizers(); |
| 601 | 601 |
| 602 void takeSnapshot(SnapshotType); | 602 void takeSnapshot(SnapshotType); |
| 603 void clearHeapAges(); | 603 void clearArenaAges(); |
| 604 int heapIndexOfVectorHeapLeastRecentlyExpanded(int beginHeapIndex, int endHe
apIndex); | 604 int arenaIndexOfVectorArenaLeastRecentlyExpanded(int beginArenaIndex, int en
dArenaIndex); |
| 605 | 605 |
| 606 void reportMemoryToV8(); | 606 void reportMemoryToV8(); |
| 607 | 607 |
| 608 // Should only be called under protection of threadAttachMutex(). | 608 // Should only be called under protection of threadAttachMutex(). |
| 609 const Vector<OwnPtr<BlinkGCInterruptor>>& interruptors() const { return m_in
terruptors; } | 609 const Vector<OwnPtr<BlinkGCInterruptor>>& interruptors() const { return m_in
terruptors; } |
| 610 | 610 |
| 611 friend class SafePointAwareMutexLocker; | 611 friend class SafePointAwareMutexLocker; |
| 612 friend class SafePointBarrier; | 612 friend class SafePointBarrier; |
| 613 friend class SafePointScope; | 613 friend class SafePointScope; |
| 614 | 614 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 637 | 637 |
| 638 void* m_safePointScopeMarker; | 638 void* m_safePointScopeMarker; |
| 639 Vector<Address> m_safePointStackCopy; | 639 Vector<Address> m_safePointStackCopy; |
| 640 bool m_atSafePoint; | 640 bool m_atSafePoint; |
| 641 Vector<OwnPtr<BlinkGCInterruptor>> m_interruptors; | 641 Vector<OwnPtr<BlinkGCInterruptor>> m_interruptors; |
| 642 bool m_sweepForbidden; | 642 bool m_sweepForbidden; |
| 643 size_t m_noAllocationCount; | 643 size_t m_noAllocationCount; |
| 644 size_t m_gcForbiddenCount; | 644 size_t m_gcForbiddenCount; |
| 645 double m_accumulatedSweepingTime; | 645 double m_accumulatedSweepingTime; |
| 646 | 646 |
| 647 BaseHeap* m_heaps[BlinkGC::NumberOfHeaps]; | 647 BaseArena* m_arenas[BlinkGC::NumberOfArenas]; |
| 648 int m_vectorBackingHeapIndex; | 648 int m_vectorBackingArenaIndex; |
| 649 size_t m_heapAges[BlinkGC::NumberOfHeaps]; | 649 size_t m_arenaAges[BlinkGC::NumberOfArenas]; |
| 650 size_t m_currentHeapAges; | 650 size_t m_currentArenaAges; |
| 651 | 651 |
| 652 bool m_isTerminating; | 652 bool m_isTerminating; |
| 653 GarbageCollectedMixinConstructorMarker* m_gcMixinMarker; | 653 GarbageCollectedMixinConstructorMarker* m_gcMixinMarker; |
| 654 | 654 |
| 655 bool m_shouldFlushHeapDoesNotContainCache; | 655 bool m_shouldFlushHeapDoesNotContainCache; |
| 656 GCState m_gcState; | 656 GCState m_gcState; |
| 657 | 657 |
| 658 CallbackStack* m_threadLocalWeakCallbackStack; | 658 CallbackStack* m_threadLocalWeakCallbackStack; |
| 659 | 659 |
| 660 // Pre-finalizers are called in the reverse order in which they are | 660 // Pre-finalizers are called in the reverse order in which they are |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 707 | 707 |
| 708 template<> class ThreadStateFor<AnyThread> { | 708 template<> class ThreadStateFor<AnyThread> { |
| 709 STATIC_ONLY(ThreadStateFor); | 709 STATIC_ONLY(ThreadStateFor); |
| 710 public: | 710 public: |
| 711 static ThreadState* state() { return ThreadState::current(); } | 711 static ThreadState* state() { return ThreadState::current(); } |
| 712 }; | 712 }; |
| 713 | 713 |
| 714 } // namespace blink | 714 } // namespace blink |
| 715 | 715 |
| 716 #endif // ThreadState_h | 716 #endif // ThreadState_h |
| OLD | NEW |