JDK-6786188 : par compact - "SplitALot" stress mode should fill to_space
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: hs14
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2008-12-17
  • Updated: 2010-04-02
  • Resolved: 2008-12-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u14Fixed 7Fixed hs14Fixed
Related Reports
Relates :  
Relates :  
Description
It's very rare that both survivor spaces contain objects at the start of a full gc.  The par compact stress mode for splitting young gen spaces (ParallelOldGCSplitALot) should periodically add objects to to_space to allow better testing of compaction with objects in both survivor spaces.

Comments
EVALUATION http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/b27c885f75f9
18-12-2008

SUGGESTED FIX diff --git a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -1473,8 +1473,52 @@ } void +PSParallelCompact::provoke_split_fill_survivor(SpaceId id) +{ + if (total_invocations() % (ParallelOldGCSplitInterval * 3) != 0) { + return; + } + + MutableSpace* const space = _space_info[id].space(); + if (space->is_empty()) { + HeapWord* b = space->bottom(); + HeapWord* t = b + space->capacity_in_words() / 2; + space->set_top(t); + if (ZapUnusedHeapArea) { + space->set_top_for_allocations(); + } + + size_t obj_len = 8; + while (b + obj_len <= t) { + CollectedHeap::fill_with_object(b, obj_len); + mark_bitmap()->mark_obj(b, obj_len); + summary_data().add_obj(b, obj_len); + b += obj_len; + obj_len = (obj_len & 0x18) + 8; // 8 16 24 32 8 16 24 32 ... + } + if (b < t) { + // The loop didn't completely fill to t (top); adjust top downward. + space->set_top(b); + if (ZapUnusedHeapArea) { + space->set_top_for_allocations(); + } + } + + HeapWord** nta = _space_info[id].new_top_addr(); + bool result = summary_data().summarize(_space_info[id].split_info(), + space->bottom(), space->top(), NULL, + space->bottom(), space->end(), nta); + assert(result, "space must fit into itself"); + } +} + +void PSParallelCompact::provoke_split(bool & max_compaction) { + if (total_invocations() % ParallelOldGCSplitInterval != 0) { + return; + } + const size_t region_size = ParallelCompactData::RegionSize; ParallelCompactData& sd = summary_data(); @@ -1587,6 +1631,12 @@ assert(result, "space must fit into itself"); _space_info[i].set_dense_prefix(space->bottom()); } + +#ifndef PRODUCT + if (ParallelOldGCSplitALot) { + provoke_split_fill_survivor(to_space_id); + } +#endif // #ifndef PRODUCT } void PSParallelCompact::fill_dense_prefix_end(SpaceId id) @@ -1794,9 +1844,7 @@ } #ifndef PRODUCT if (ParallelOldGCSplitALot && old_space_total_live < old_capacity) { - if (total_invocations() % ParallelOldGCSplitInterval == 0) { - provoke_split(maximum_compaction); - } + provoke_split(maximum_compaction); } #endif // #ifndef PRODUCT diff --git a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp @@ -978,6 +978,10 @@ // Include the new objects in the summary data. static void summarize_new_objects(SpaceId id, HeapWord* start); + // Add live objects to a survivor space since it's rare that both survivors + // are non-empty. + static void provoke_split_fill_survivor(SpaceId id); + // Add live objects and/or choose the dense prefix to provoke splitting. static void provoke_split(bool & maximum_compaction); #endif
18-12-2008

SUGGESTED FIX When ParallelOldGCSplitALot is enabled and to_space is empty, the summary phase should occasionally add live objects so to_space becomes about 50% full. Best to do this only some fraction of the time that young gen splits are provoked (e.g., 1/3 of the time).
17-12-2008

EVALUATION The description pretty much covers it. This feature would have prevented bug 6784849 (and was useful in diagnosing it).
17-12-2008