@@ -1038,8 +1038,10 @@ void PageSpace::CollectGarbage(bool compact, bool finalize) {
10381038 const int64_t pre_wait_for_sweepers = OS::GetCurrentMonotonicMicros ();
10391039
10401040 // Wait for pending tasks to complete and then account for the driver task.
1041+ Phase waited_for;
10411042 {
10421043 MonitorLocker locker (tasks_lock ());
1044+ waited_for = phase ();
10431045 if (!finalize &&
10441046 (phase () == kMarking || phase () == kAwaitingFinalization )) {
10451047 // Concurrent mark is already running.
@@ -1054,6 +1056,16 @@ void PageSpace::CollectGarbage(bool compact, bool finalize) {
10541056 }
10551057
10561058 const int64_t pre_safe_point = OS::GetCurrentMonotonicMicros ();
1059+ if (FLAG_verbose_gc) {
1060+ const int64_t wait = pre_safe_point - pre_wait_for_sweepers;
1061+ if (waited_for == kMarking ) {
1062+ THR_Print (" Waited %" Pd64 " us for concurrent marking to finish.\n " ,
1063+ wait);
1064+ } else if (waited_for == kSweepingRegular || waited_for == kSweepingLarge ) {
1065+ THR_Print (" Waited %" Pd64 " us for concurrent sweeping to finish.\n " ,
1066+ wait);
1067+ }
1068+ }
10571069
10581070 // Ensure that all threads for this isolate are at a safepoint (either
10591071 // stopped or in native code). We have guards around Newgen GC and oldgen GC
@@ -1483,9 +1495,8 @@ PageSpaceController::PageSpaceController(Heap* heap,
14831495 heap_growth_max_(heap_growth_max),
14841496 garbage_collection_time_ratio_(garbage_collection_time_ratio),
14851497 idle_gc_threshold_in_words_(0 ) {
1486- intptr_t grow_heap = heap_growth_max / 2 ;
1487- gc_threshold_in_words_ =
1488- last_usage_.capacity_in_words + (kPageSizeInWords * grow_heap);
1498+ const intptr_t growth_in_pages = heap_growth_max / 2 ;
1499+ RecordUpdate (last_usage_, last_usage_, growth_in_pages, " initial" );
14891500}
14901501
14911502PageSpaceController::~PageSpaceController () {}
@@ -1497,12 +1508,7 @@ bool PageSpaceController::NeedsGarbageCollection(SpaceUsage after) const {
14971508 if (heap_growth_ratio_ == 100 ) {
14981509 return false ;
14991510 }
1500- #if defined(TARGET_ARCH_IA32)
1501- intptr_t headroom = 0 ;
1502- #else
1503- intptr_t headroom = heap_->new_space ()->CapacityInWords ();
1504- #endif
1505- return after.CombinedUsedInWords () > (gc_threshold_in_words_ + headroom);
1511+ return after.CombinedUsedInWords () > hard_gc_threshold_in_words_;
15061512}
15071513
15081514bool PageSpaceController::AlmostNeedsGarbageCollection (SpaceUsage after) const {
@@ -1512,7 +1518,7 @@ bool PageSpaceController::AlmostNeedsGarbageCollection(SpaceUsage after) const {
15121518 if (heap_growth_ratio_ == 100 ) {
15131519 return false ;
15141520 }
1515- return after.CombinedUsedInWords () > gc_threshold_in_words_ ;
1521+ return after.CombinedUsedInWords () > soft_gc_threshold_in_words_ ;
15161522}
15171523
15181524bool PageSpaceController::NeedsIdleGarbageCollection (SpaceUsage current) const {
@@ -1613,15 +1619,7 @@ void PageSpaceController::EvaluateGarbageCollection(SpaceUsage before,
16131619 heap_->RecordData (PageSpace::kAllowedGrowth , grow_heap);
16141620 last_usage_ = after;
16151621
1616- // Save final threshold compared before growing.
1617- gc_threshold_in_words_ =
1618- after.CombinedUsedInWords () + (kPageSizeInWords * grow_heap);
1619-
1620- // Set a tight idle threshold.
1621- idle_gc_threshold_in_words_ =
1622- after.CombinedUsedInWords () + (2 * kPageSizeInWords );
1623-
1624- RecordUpdate (before, after, " gc" );
1622+ RecordUpdate (before, after, grow_heap, " gc" );
16251623}
16261624
16271625void PageSpaceController::EvaluateAfterLoading (SpaceUsage after) {
@@ -1637,38 +1635,57 @@ void PageSpaceController::EvaluateAfterLoading(SpaceUsage after) {
16371635 growth_in_pages =
16381636 Utils::Minimum (static_cast <intptr_t >(heap_growth_max_), growth_in_pages);
16391637
1638+ RecordUpdate (after, after, growth_in_pages, " loaded" );
1639+ }
1640+
1641+ void PageSpaceController::RecordUpdate (SpaceUsage before,
1642+ SpaceUsage after,
1643+ intptr_t growth_in_pages,
1644+ const char * reason) {
16401645 // Save final threshold compared before growing.
1641- gc_threshold_in_words_ =
1646+ hard_gc_threshold_in_words_ =
16421647 after.CombinedUsedInWords () + (kPageSizeInWords * growth_in_pages);
16431648
1649+ // Start concurrent marking when old-space has less than half of new-space
1650+ // available or less than 5% available.
1651+ #if defined(TARGET_ARCH_IA32)
1652+ const intptr_t headroom = 0 ; // No concurrent marking.
1653+ #else
1654+ // Note that heap_ can be null in some unit tests.
1655+ const intptr_t new_space =
1656+ heap_ == nullptr ? 0 : heap_->new_space ()->CapacityInWords ();
1657+ const intptr_t headroom =
1658+ Utils::Maximum (new_space / 2 , hard_gc_threshold_in_words_ / 20 );
1659+ #endif
1660+ soft_gc_threshold_in_words_ = hard_gc_threshold_in_words_ - headroom;
1661+
16441662 // Set a tight idle threshold.
16451663 idle_gc_threshold_in_words_ =
16461664 after.CombinedUsedInWords () + (2 * kPageSizeInWords );
16471665
1648- RecordUpdate (after, after, " loaded" );
1649- }
1650-
1651- void PageSpaceController::RecordUpdate (SpaceUsage before,
1652- SpaceUsage after,
1653- const char * reason) {
16541666#if defined(SUPPORT_TIMELINE)
1655- TIMELINE_FUNCTION_GC_DURATION (Thread::Current (), " UpdateGrowthLimit" );
1656- tbes.SetNumArguments (5 );
1657- tbes.CopyArgument (0 , " Reason" , reason);
1658- tbes.FormatArgument (1 , " Before.CombinedUsed (kB)" , " %" Pd " " ,
1659- RoundWordsToKB (before.CombinedUsedInWords ()));
1660- tbes.FormatArgument (2 , " After.CombinedUsed (kB)" , " %" Pd " " ,
1661- RoundWordsToKB (after.CombinedUsedInWords ()));
1662- tbes.FormatArgument (3 , " Threshold (kB)" , " %" Pd " " ,
1663- RoundWordsToKB (gc_threshold_in_words_));
1664- tbes.FormatArgument (4 , " Idle Threshold (kB)" , " %" Pd " " ,
1665- RoundWordsToKB (idle_gc_threshold_in_words_));
1667+ Thread* thread = Thread::Current ();
1668+ if (thread != nullptr ) {
1669+ TIMELINE_FUNCTION_GC_DURATION (thread, " UpdateGrowthLimit" );
1670+ tbes.SetNumArguments (6 );
1671+ tbes.CopyArgument (0 , " Reason" , reason);
1672+ tbes.FormatArgument (1 , " Before.CombinedUsed (kB)" , " %" Pd " " ,
1673+ RoundWordsToKB (before.CombinedUsedInWords ()));
1674+ tbes.FormatArgument (2 , " After.CombinedUsed (kB)" , " %" Pd " " ,
1675+ RoundWordsToKB (after.CombinedUsedInWords ()));
1676+ tbes.FormatArgument (3 , " Hard Threshold (kB)" , " %" Pd " " ,
1677+ RoundWordsToKB (hard_gc_threshold_in_words_));
1678+ tbes.FormatArgument (4 , " Soft Threshold (kB)" , " %" Pd " " ,
1679+ RoundWordsToKB (soft_gc_threshold_in_words_));
1680+ tbes.FormatArgument (5 , " Idle Threshold (kB)" , " %" Pd " " ,
1681+ RoundWordsToKB (idle_gc_threshold_in_words_));
1682+ }
16661683#endif
16671684
16681685 if (FLAG_log_growth) {
16691686 THR_Print (" %s: threshold=%" Pd " kB, idle_threshold=%" Pd " kB, reason=%s\n " ,
16701687 heap_->isolate_group ()->source ()->name ,
1671- gc_threshold_in_words_ / KBInWords,
1688+ hard_gc_threshold_in_words_ / KBInWords,
16721689 idle_gc_threshold_in_words_ / KBInWords, reason);
16731690 }
16741691}
0 commit comments