src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu May 29 11:13:58 2008
--- new/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Thu May 29 11:13:57 2008
*** 803,836 ****
--- 803,838 ----
NOT_PRODUCT(verify_objects_initialized());
assert(MemRegion(bottom(), end()).contains(p), "p not in space");
// This must be volatile, or else there is a danger that the compiler
// will compile the code below into a sometimes-infinite loop, by keeping
// the value read the first time in a register.
oop o = (oop)p;
volatile oop* second_word_addr = o->klass_addr();
while (true) {
klassOop k = (klassOop)(*second_word_addr);
// We must do this until we get a consistent view of the object.
! if (FreeChunk::secondWordIndicatesFreeChunk((intptr_t)k)) {
! FreeChunk* fc = (FreeChunk*)p;
! volatile size_t* sz_addr = (volatile size_t*)(fc->size_addr());
size_t res = (*sz_addr);
! klassOop k2 = (klassOop)(*second_word_addr); // Read to confirm.
! if (k == k2) {
! if (FreeChunk::indicatesFreeChunk(p)) {
! volatile FreeChunk* fc = (volatile FreeChunk*)p;
! size_t res = fc->size();
+ // If the object is still a free chunk, return the size, else it
! // has been allocated so try again.
! if (FreeChunk::indicatesFreeChunk(p)) {
assert(res != 0, "Block size should not be 0");
return res;
}
- } else if (k != NULL) {
+ // must read from what 'p' points to in each loop.
+ klassOop k = ((volatile oopDesc*)p)->klass_or_null();
+ if (k != NULL) {
assert(k->is_oop(true /* ignore mark word */), "Should really be klass oop.");
+ oop o = (oop)p;
assert(o->is_parsable(), "Should be parsable");
assert(o->is_oop(true /* ignore mark word */), "Should be an oop.");
size_t res = o->size_given_klass(k->klass_part());
res = adjustObjectSize(res);
assert(res != 0, "Block size should not be 0");
return res;
}
}
+ }
}
// A variant of the above that uses the Printezis bits for
// unparsable but allocated objects. This avoids any possible
// stalls waiting for mutators to initialize objects, and is
*** 843,878 ****
--- 845,880 ----
const {
assert(MemRegion(bottom(), end()).contains(p), "p not in space");
// This must be volatile, or else there is a danger that the compiler
// will compile the code below into a sometimes-infinite loop, by keeping
// the value read the first time in a register.
oop o = (oop)p;
volatile oop* second_word_addr = o->klass_addr();
DEBUG_ONLY(uint loops = 0;)
while (true) {
klassOop k = (klassOop)(*second_word_addr);
// We must do this until we get a consistent view of the object.
! if (FreeChunk::secondWordIndicatesFreeChunk((intptr_t)k)) {
! FreeChunk* fc = (FreeChunk*)p;
! volatile size_t* sz_addr = (volatile size_t*)(fc->size_addr());
size_t res = (*sz_addr);
klassOop k2 = (klassOop)(*second_word_addr); // Read to confirm.
if (k == k2) {
! if (FreeChunk::indicatesFreeChunk(p)) {
! volatile FreeChunk* fc = (volatile FreeChunk*)p;
! size_t res = fc->size();
+ if (FreeChunk::indicatesFreeChunk(p)) {
assert(res != 0, "Block size should not be 0");
assert(loops == 0, "Should be 0");
return res;
}
- } else if (k != NULL && o->is_parsable()) {
+ // must read from what 'p' points to in each loop.
+ klassOop k = ((volatile oopDesc*)p)->klass_or_null();
+ if (k != NULL && ((oopDesc*)p)->is_parsable()) {
assert(k->is_oop(), "Should really be klass oop.");
+ oop o = (oop)p;
assert(o->is_oop(), "Should be an oop");
size_t res = o->size_given_klass(k->klass_part());
res = adjustObjectSize(res);
assert(res != 0, "Block size should not be 0");
return res;
} else {
return c->block_size_if_printezis_bits(p);
}
+ }
assert(loops == 0, "Can loop at most once");
DEBUG_ONLY(loops++;)
}
}
*** 905,917 ****
--- 907,918 ----
// (i.e., that the block start calculation may look at objects
// at address below "p" in finding the object that contains "p"
// and those objects (if garbage) may have been modified to hold
// live range information.
// assert(ParallelGCThreads > 0 || _bt.block_start(p) == p, "Should be a block boundary");
! klassOop k = oop(p)->klass();
! intptr_t ki = (intptr_t)k;
if (FreeChunk::secondWordIndicatesFreeChunk(ki)) return false;
! if (FreeChunk::indicatesFreeChunk(p)) return false;
! klassOop k = oop(p)->klass_or_null();
if (k != NULL) {
// Ignore mark word because it may have been used to
// chain together promoted objects (the last one
// would have a null value).
assert(oop(p)->is_oop(true), "Should be an oop");
*** 1025,1035 ****
--- 1026,1036 ----
assert(is_aligned((void*)res), "alignment check");
FreeChunk* fc = (FreeChunk*)res;
fc->markNotFree();
assert(!fc->isFree(), "shouldn't be marked free");
! assert(oop(fc)->klass_or_null() == NULL, "should look uninitialized");
// Verify that the block offset table shows this to
// be a single block, but not one which is unallocated.
_bt.verify_single_block(res, size);
_bt.verify_not_unallocated(res, size);
// mangle a just allocated object with a distinct pattern.
*** 2591,2601 ****
--- 2592,2602 ----
res = fl->getChunkAtHead();
assert(res != NULL, "Why was count non-zero?");
}
res->markNotFree();
assert(!res->isFree(), "shouldn't be marked free");
! assert(oop(res)->klass_or_null() == NULL, "should look uninitialized");
// mangle a just allocated object with a distinct pattern.
debug_only(res->mangleAllocated(word_sz));
return (HeapWord*)res;
}
src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File