United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 6786188 par compact - "SplitALot" stress mode should fill to_space
6786188 : par compact - "SplitALot" stress mode should fill to_space

Details
Type:
Enhancement
Submit Date:
2008-12-17
Status:
Resolved
Updated Date:
2010-04-02
Project Name:
JDK
Resolved Date:
2008-12-23
Component:
hotspot
OS:
generic
Sub-Component:
gc
CPU:
generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
hs14
Fixed Versions:
hs14

Related Reports
Backport:
Backport:
Relates:
Relates:

Sub Tasks

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
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
                                     
2008-12-18
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/b27c885f75f9
                                     
2008-12-18
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).
                                     
2008-12-17
EVALUATION

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



Hardware and Software, Engineered to Work Together