src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File cms-comp Cdiff src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp

src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp

Print this page

        

*** 803,836 **** 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) { assert(res != 0, "Block size should not be 0"); return res; } ! } else if (k != NULL) { assert(k->is_oop(true /* ignore mark word */), "Should really be klass oop."); 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 --- 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. while (true) { // We must do this until we get a consistent view of the object. ! 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 { ! // 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 **** 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) { assert(res != 0, "Block size should not be 0"); assert(loops == 0, "Should be 0"); return res; } ! } else if (k != NULL && o->is_parsable()) { assert(k->is_oop(), "Should really be klass oop."); 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++;) } } --- 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. DEBUG_ONLY(uint loops = 0;) while (true) { // We must do this until we get a consistent view of the object. ! 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 { ! // 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 **** // (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 (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"); --- 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"); ! 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 **** 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() == 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. --- 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 **** 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() == NULL, "should look uninitialized"); // mangle a just allocated object with a distinct pattern. debug_only(res->mangleAllocated(word_sz)); return (HeapWord*)res; } --- 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