--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Fri Jun 06 11:47:26 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Mon Jun 09 11:51:19 2008 -0400
@@ -190,7 +190,8 @@
// depends on this property.
debug_only(
FreeChunk* junk = NULL;
- assert(junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
+ assert(UseCompressedOops ||
+ junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
"Offset of FreeChunk::_prev within FreeChunk must match"
" that of OopDesc::_klass within OopDesc");
)
@@ -1039,7 +1040,7 @@
// mark end of object
}
// check that oop looks uninitialized
- assert(oop(start)->klass() == NULL, "_klass should be NULL");
+ assert(oop(start)->klass_or_null() == NULL, "_klass should be NULL");
}
void CMSCollector::promoted(bool par, HeapWord* start,
@@ -1309,17 +1310,25 @@
}
}
oop obj = oop(obj_ptr);
- assert(obj->klass() == NULL, "Object should be uninitialized here.");
+ assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
// Otherwise, copy the object. Here we must be careful to insert the
// klass pointer last, since this marks the block as an allocated object.
+ // Except with compressed oops it's the mark word.
HeapWord* old_ptr = (HeapWord*)old;
if (word_sz > (size_t)oopDesc::header_size()) {
Copy::aligned_disjoint_words(old_ptr + oopDesc::header_size(),
obj_ptr + oopDesc::header_size(),
word_sz - oopDesc::header_size());
}
+
+ if (UseCompressedOops) {
+ // Copy gap missed by (aligned) header size calculation above
+ obj->set_klass_gap(old->klass_gap());
+ }
+
// Restore the mark word copied above.
obj->set_mark(m);
+
// Now we can track the promoted object, if necessary. We take care
// To delay the transition from uninitialized to full object
// (i.e., insertion of klass pointer) until after, so that it
@@ -1327,7 +1336,8 @@
if (promoInfo->tracking()) {
promoInfo->track((PromotedObject*)obj, old->klass());
}
- // Finally, install the klass pointer.
+
+ // Finally, install the klass pointer (this should be volatile).
obj->set_klass(old->klass());
assert(old->is_oop(), "Will dereference klass ptr below");
@@ -6165,7 +6175,7 @@
HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
size_t sz = 0;
oop p = (oop)addr;
- if (p->klass() != NULL && p->is_parsable()) {
+ if (p->klass_or_null() != NULL && p->is_parsable()) {
sz = CompactibleFreeListSpace::adjustObjectSize(p->size());
} else {
sz = block_size_using_printezis_bits(addr);
@@ -6602,7 +6612,7 @@
}
if (_bitMap->isMarked(addr)) {
// it's marked; is it potentially uninitialized?
- if (p->klass() != NULL) {
+ if (p->klass_or_null() != NULL) {
if (CMSPermGenPrecleaningEnabled && !p->is_parsable()) {
// Signal precleaning to redirty the card since
// the klass pointer is already installed.
@@ -6615,11 +6625,8 @@
if (p->is_objArray()) {
// objArrays are precisely marked; restrict scanning
// to dirty cards only.
- size = p->oop_iterate(_scanningClosure, mr);
- assert(size == CompactibleFreeListSpace::adjustObjectSize(size),
- "adjustObjectSize should be the identity for array sizes, "
- "which are necessarily larger than minimum object size of "
- "two heap words");
+ size = CompactibleFreeListSpace::adjustObjectSize(
+ p->oop_iterate(_scanningClosure, mr));
} else {
// A non-array may have been imprecisely marked; we need
// to scan object in its entirety.
@@ -6653,7 +6660,7 @@
}
} else {
// Either a not yet marked object or an uninitialized object
- if (p->klass() == NULL || !p->is_parsable()) {
+ if (p->klass_or_null() == NULL || !p->is_parsable()) {
// An uninitialized object, skip to the next card, since
// we may not be able to read its P-bits yet.
assert(size == 0, "Initial value");
@@ -6710,7 +6717,7 @@
HeapWord* addr = (HeapWord*)p;
DEBUG_ONLY(_collector->verify_work_stacks_empty();)
assert(!_span.contains(addr), "we are scanning the survivor spaces");
- assert(p->klass() != NULL, "object should be initializd");
+ assert(p->klass_or_null() != NULL, "object should be initializd");
assert(p->is_parsable(), "must be parsable.");
// an initialized object; ignore mark word in verification below
// since we are running concurrent with mutators
@@ -6868,7 +6875,7 @@
assert(_skipBits == 0, "tautology");
_skipBits = 2; // skip next two marked bits ("Printezis-marks")
oop p = oop(addr);
- if (p->klass() == NULL || !p->is_parsable()) {
+ if (p->klass_or_null() == NULL || !p->is_parsable()) {
DEBUG_ONLY(if (!_verifying) {)
// We re-dirty the cards on which this object lies and increase
// the _threshold so that we'll come back to scan this object
@@ -6890,7 +6897,7 @@
if (_threshold < end_card_addr) {
_threshold = end_card_addr;
}
- if (p->klass() != NULL) {
+ if (p->klass_or_null() != NULL) {
// Redirty the range of cards...
_mut->mark_range(redirty_range);
} // ...else the setting of klass will dirty the card anyway.
@@ -7048,7 +7055,7 @@
assert(_skip_bits == 0, "tautology");
_skip_bits = 2; // skip next two marked bits ("Printezis-marks")
oop p = oop(addr);
- if (p->klass() == NULL || !p->is_parsable()) {
+ if (p->klass_or_null() == NULL || !p->is_parsable()) {
// in the case of Clean-on-Enter optimization, redirty card
// and avoid clearing card by increasing the threshold.
return;
@@ -8023,7 +8030,7 @@
"alignment problem");
#ifdef DEBUG
- if (oop(addr)->klass() != NULL &&
+ if (oop(addr)->klass_or_null() != NULL &&
( !_collector->should_unload_classes()
|| oop(addr)->is_parsable())) {
// Ignore mark word because we are running concurrent with mutators
@@ -8036,7 +8043,7 @@
} else {
// This should be an initialized object that's alive.
- assert(oop(addr)->klass() != NULL &&
+ assert(oop(addr)->klass_or_null() != NULL &&
(!_collector->should_unload_classes()
|| oop(addr)->is_parsable()),
"Should be an initialized object");