SUGGESTED FIX
This fixes one aspect of the assert to do with the interference
between concurrent direct allocation in the old gen and
the precleaning code that encounters an uparsable object
but beats the allocator into acquiring the bit map lock to
try and read the Printezis-bit, thus locking out the
writer of those bits (i.e. the allocating thread):-
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration
.cpp Wed Aug 20 23:05:04 2008 -0700
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration
.cpp Mon Aug 25 16:01:17 2008 -0700
@@ -4560,11 +4560,11 @@ size_t CMSCollector::preclean_mod_union_
if (!dirtyRegion.is_empty()) {
assert(numDirtyCards > 0, "consistency check");
HeapWord* stop_point = NULL;
+ stopTimer();
+ CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
+ bitMapLock());
+ startTimer();
{
- stopTimer();
- CMSTokenSyncWithLocks ts(true, gen->freelistLock(),
- bitMapLock());
- startTimer();
verify_work_stacks_empty();
verify_overflow_empty();
sample_eden();
@@ -4581,10 +4581,6 @@ size_t CMSCollector::preclean_mod_union_
assert((CMSPermGenPrecleaningEnabled && (gen == _permGen)) ||
(_collectorState == AbortablePreclean && should_abort_preclean()),
"Unparsable objects should only be in perm gen.");
-
- stopTimer();
- CMSTokenSyncWithLocks ts(true, bitMapLock());
- startTimer();
_modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end()));
if (should_abort_preclean()) {
break; // out of preclean loop
The following diff might be useful during further debugging of this
bug but, obviously should be removed before checking in the changes:-
@@ -6130,8 +6124,15 @@ void CMSCollector::verify_ok_to_terminat
#endif
size_t CMSCollector::block_size_using_printezis_bits(HeapWord* addr) const {
- assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
- "missing Printezis mark?");
+// assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1),
+// "missing Printezis mark?");
+ if (!(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1))) {
+ tty->print_cr("Missing Printezis bits for " PTR_FORMAT, addr);
+ tty->print_cr("_markBitMap.isMarked(addr)=%d, _markBitMap.isMarked(addr+1)=%d",
+ _markBitMap.isMarked(addr), _markBitMap.isMarked(addr+1));
+ oop(addr)->print();
+ assert(false, "Missing Printezis mark!!!");
+ }
HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2);
size_t size = pointer_delta(nextOneAddr + 1, addr);
assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
|
EVALUATION
With the above mods we still have a few issues that appear
directly related to the class redefinition being done in these
tests. If the class redefinition is switched off, the tests
run fine. I have a suspicion that class redifinition is being
done in such a way as to interfere with concurrent CMS activities.
Will need to understand class redefinition steps thoroughly to
understand the extent of this interference.
Meanwhile, as a workaround to this problem, CMS activity should
be locked out during class redefinition. A simple workaround along
those lines will be attempted as a temporary workaround.
|