123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631 |
- # HG changeset patch
- # Parent dc85548673e78358fc7a3dcbe2f51cad5a91201f
- Change MarkAndSweep garbage collector to allow changing instances during redefinition.
-
- diff -r dc85548673e7 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
- --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Wed Apr 01 11:22:01 2015 -0700
- @@ -163,6 +163,12 @@
- }
- }
-
- +HeapWord* CompactibleFreeListSpace::forward_compact_top(size_t size,
- + CompactPoint* cp, HeapWord* compact_top) {
- + ShouldNotReachHere();
- + return NULL;
- +}
- +
- // Like CompactibleSpace forward() but always calls cross_threshold() to
- // update the block offset table. Removed initialize_threshold call because
- // CFLS does not use a block offset array for contiguous spaces.
- @@ -2097,7 +2103,7 @@
- // Support for compaction
-
- void CompactibleFreeListSpace::prepare_for_compaction(CompactPoint* cp) {
- - SCAN_AND_FORWARD(cp,end,block_is_obj,block_size);
- + SCAN_AND_FORWARD(cp,end,block_is_obj,block_size,false);
- // prepare_for_compaction() uses the space between live objects
- // so that later phase can skip dead space quickly. So verification
- // of the free lists doesn't work after.
- @@ -2118,7 +2124,7 @@
- }
-
- void CompactibleFreeListSpace::compact() {
- - SCAN_AND_COMPACT(obj_size);
- + SCAN_AND_COMPACT(obj_size, false);
- }
-
- // fragmentation_metric = 1 - [sum of (fbs**2) / (sum of fbs)**2]
- diff -r dc85548673e7 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
- --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Wed Apr 01 11:22:01 2015 -0700
- @@ -150,6 +150,7 @@
-
- // Support for compacting cms
- HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
- + HeapWord* forward_compact_top(size_t size, CompactPoint* cp, HeapWord* compact_top);
- HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top);
-
- // Initialization helpers.
- diff -r dc85548673e7 src/share/vm/gc_implementation/g1/heapRegion.cpp
- --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp Wed Apr 01 11:22:01 2015 -0700
- @@ -1063,7 +1063,7 @@
-
- #define block_is_always_obj(q) true
- void G1OffsetTableContigSpace::prepare_for_compaction(CompactPoint* cp) {
- - SCAN_AND_FORWARD(cp, top, block_is_always_obj, block_size);
- + SCAN_AND_FORWARD(cp, top, block_is_always_obj, block_size, false);
- }
- #undef block_is_always_obj
-
- diff -r dc85548673e7 src/share/vm/gc_implementation/shared/markSweep.cpp
- --- a/src/share/vm/gc_implementation/shared/markSweep.cpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Wed Apr 01 11:22:01 2015 -0700
- @@ -48,6 +48,8 @@
- STWGCTimer* MarkSweep::_gc_timer = NULL;
- SerialOldTracer* MarkSweep::_gc_tracer = NULL;
-
- +GrowableArray<HeapWord*>* MarkSweep::_rescued_oops = NULL;
- +
- MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
-
- void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); }
- @@ -165,3 +167,100 @@
- }
-
- #endif
- +
- +// (DCEVM) Copy the rescued objects to their destination address after compaction.
- +void MarkSweep::copy_rescued_objects_back() {
- +
- + if (_rescued_oops != NULL) {
- +
- + for (int i=0; i<_rescued_oops->length(); i++) {
- + HeapWord* rescued_ptr = _rescued_oops->at(i);
- + oop rescued_obj = (oop) rescued_ptr;
- +
- + int size = rescued_obj->size();
- + oop new_obj = rescued_obj->forwardee();
- +
- + assert(rescued_obj->klass()->new_version() != NULL, "just checking");
- +
- + if (rescued_obj->klass()->new_version()->update_information() != NULL) {
- + MarkSweep::update_fields(rescued_obj, new_obj);
- + } else {
- + rescued_obj->set_klass(rescued_obj->klass()->new_version());
- + Copy::aligned_disjoint_words((HeapWord*)rescued_obj, (HeapWord*)new_obj, size);
- + }
- +
- + FREE_RESOURCE_ARRAY(HeapWord, rescued_ptr, size);
- +
- + new_obj->init_mark();
- + assert(new_obj->is_oop(), "must be a valid oop");
- + }
- + _rescued_oops->clear();
- + _rescued_oops = NULL;
- + }
- +}
- +
- +// (DCEVM) Update instances of a class whose fields changed.
- +void MarkSweep::update_fields(oop q, oop new_location) {
- +
- + assert(q->klass()->new_version() != NULL, "class of old object must have new version");
- +
- + Klass* old_klass_oop = q->klass();
- + Klass* new_klass_oop = q->klass()->new_version();
- +
- + InstanceKlass *old_klass = InstanceKlass::cast(old_klass_oop);
- + InstanceKlass *new_klass = InstanceKlass::cast(new_klass_oop);
- +
- + int size = q->size_given_klass(old_klass);
- + int new_size = q->size_given_klass(new_klass);
- +
- + HeapWord* tmp = NULL;
- + oop tmp_obj = q;
- +
- + // Save object somewhere, there is an overlap in fields
- + if (new_klass_oop->is_copying_backwards()) {
- + if (((HeapWord *)q >= (HeapWord *)new_location && (HeapWord *)q < (HeapWord *)new_location + new_size) ||
- + ((HeapWord *)new_location >= (HeapWord *)q && (HeapWord *)new_location < (HeapWord *)q + size)) {
- + tmp = NEW_RESOURCE_ARRAY(HeapWord, size);
- + q = (oop) tmp;
- + Copy::aligned_disjoint_words((HeapWord*)q, (HeapWord*)tmp_obj, size);
- + }
- + }
- +
- + q->set_klass(new_klass_oop);
- + int *cur = new_klass_oop->update_information();
- + assert(cur != NULL, "just checking");
- + MarkSweep::update_fields(new_location, q, cur);
- +
- + if (tmp != NULL) {
- + FREE_RESOURCE_ARRAY(HeapWord, tmp, size);
- + }
- +}
- +
- +void MarkSweep::update_fields(oop new_location, oop tmp_obj, int *cur) {
- + assert(cur != NULL, "just checking");
- + char* to = (char*)(HeapWord*)new_location;
- + while (*cur != 0) {
- + int size = *cur;
- + if (size > 0) {
- + cur++;
- + int offset = *cur;
- + HeapWord* from = (HeapWord*)(((char *)(HeapWord*)tmp_obj) + offset);
- + if (size == HeapWordSize) {
- + *((HeapWord*)to) = *from;
- + } else if (size == HeapWordSize * 2) {
- + *((HeapWord*)to) = *from;
- + *(((HeapWord*)to) + 1) = *(from + 1);
- + } else {
- + Copy::conjoint_jbytes(from, to, size);
- + }
- + to += size;
- + cur++;
- + } else {
- + assert(size < 0, "");
- + int skip = -*cur;
- + Copy::fill_to_bytes(to, skip, 0);
- + to += skip;
- + cur++;
- + }
- + }
- +}
- diff -r dc85548673e7 src/share/vm/gc_implementation/shared/markSweep.hpp
- --- a/src/share/vm/gc_implementation/shared/markSweep.hpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/gc_implementation/shared/markSweep.hpp Wed Apr 01 11:22:01 2015 -0700
- @@ -96,8 +96,12 @@
- friend class AdjustPointerClosure;
- friend class KeepAliveClosure;
- friend class VM_MarkSweep;
- + friend class GenMarkSweep;
- friend void marksweep_init();
-
- +public:
- + static GrowableArray<HeapWord*>* _rescued_oops;
- +
- //
- // Vars
- //
- @@ -157,6 +161,9 @@
-
- static inline void push_objarray(oop obj, size_t index);
-
- + static void copy_rescued_objects_back();
- + static void update_fields(oop q, oop new_location);
- + static void update_fields(oop new_location, oop tmp_obj, int *cur);
- static void follow_stack(); // Empty marking stack.
-
- static void follow_klass(Klass* klass);
- diff -r dc85548673e7 src/share/vm/memory/genMarkSweep.cpp
- --- a/src/share/vm/memory/genMarkSweep.cpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/memory/genMarkSweep.cpp Wed Apr 01 11:22:01 2015 -0700
- @@ -327,11 +327,16 @@
- // in the same order in phase2, phase3 and phase4. We don't quite do that
- // here (perm_gen first rather than last), so we tell the validate code
- // to use a higher index (saved from phase2) when verifying perm_gen.
- + assert(_rescued_oops == NULL, "must be empty before processing");
- GenCollectedHeap* gch = GenCollectedHeap::heap();
-
- GCTraceTime tm("phase 4", PrintGC && Verbose, true, _gc_timer, _gc_tracer->gc_id());
- trace("4");
-
- + MarkSweep::copy_rescued_objects_back();
- +
- GenCompactClosure blk;
- gch->generation_iterate(&blk, true);
- +
- + MarkSweep::copy_rescued_objects_back();
- }
- diff -r dc85548673e7 src/share/vm/memory/space.cpp
- --- a/src/share/vm/memory/space.cpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/memory/space.cpp Wed Apr 01 11:22:01 2015 -0700
- @@ -377,9 +377,8 @@
- _compaction_top = bottom();
- }
-
- -HeapWord* CompactibleSpace::forward(oop q, size_t size,
- - CompactPoint* cp, HeapWord* compact_top) {
- - // q is alive
- +// (DCEVM) Calculates the compact_top that will be used for placing the next object with the giving size on the heap.
- +HeapWord* CompactibleSpace::forward_compact_top(size_t size, CompactPoint* cp, HeapWord* compact_top) {
- // First check if we should switch compaction space
- assert(this == cp->space, "'this' should be current compaction space.");
- size_t compaction_max_size = pointer_delta(end(), compact_top);
- @@ -399,8 +398,15 @@
- compaction_max_size = pointer_delta(cp->space->end(), compact_top);
- }
-
- + return compact_top;
- +}
- +
- +HeapWord* CompactibleSpace::forward(oop q, size_t size,
- + CompactPoint* cp, HeapWord* compact_top) {
- + compact_top = forward_compact_top(size, cp, compact_top);
- +
- // store the forwarding pointer into the mark word
- - if ((HeapWord*)q != compact_top) {
- + if ((HeapWord*)q != compact_top || (size_t)q->size() != size) {
- q->forward_to(oop(compact_top));
- assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
- } else {
- @@ -421,6 +427,58 @@
- return compact_top;
- }
-
- +// Compute the forward sizes and leave out objects whose position could
- +// possibly overlap other objects.
- +HeapWord* CompactibleSpace::forward_with_rescue(HeapWord* q, size_t size,
- + CompactPoint* cp, HeapWord* compact_top) {
- + size_t forward_size = size;
- +
- + // (DCEVM) There is a new version of the class of q => different size
- + if (oop(q)->klass()->new_version() != NULL && oop(q)->klass()->new_version()->update_information() != NULL) {
- +
- + size_t new_size = oop(q)->size_given_klass(oop(q)->klass()->new_version());
- + assert(size != new_size, "instances without changed size have to be updated prior to GC run");
- + forward_size = new_size;
- + }
- +
- + compact_top = forward_compact_top(forward_size, cp, compact_top);
- +
- + if (must_rescue(oop(q), oop(compact_top))) {
- + if (MarkSweep::_rescued_oops == NULL) {
- + MarkSweep::_rescued_oops = new GrowableArray<HeapWord*>(128);
- + }
- + MarkSweep::_rescued_oops->append(q);
- + return compact_top;
- + }
- +
- + return forward(oop(q), forward_size, cp, compact_top);
- +}
- +
- +// Compute the forwarding addresses for the objects that need to be rescued.
- +HeapWord* CompactibleSpace::forward_rescued(CompactPoint* cp, HeapWord* compact_top) {
- + // TODO: empty the _rescued_oops after ALL spaces are compacted!
- + if (MarkSweep::_rescued_oops != NULL) {
- + for (int i=0; i<MarkSweep::_rescued_oops->length(); i++) {
- + HeapWord* q = MarkSweep::_rescued_oops->at(i);
- +
- + /* size_t size = oop(q)->size(); changing this for cms for perm gen */
- + size_t size = block_size(q);
- +
- + // (DCEVM) There is a new version of the class of q => different size
- + if (oop(q)->klass()->new_version() != NULL) {
- + size_t new_size = oop(q)->size_given_klass(oop(q)->klass()->new_version());
- + assert(size != new_size, "instances without changed size have to be updated prior to GC run");
- + size = new_size;
- + }
- +
- + compact_top = cp->space->forward(oop(q), size, cp, compact_top);
- + assert(compact_top <= end(), "must not write over end of space!");
- + }
- + MarkSweep::_rescued_oops->clear();
- + MarkSweep::_rescued_oops = NULL;
- + }
- + return compact_top;
- +}
-
- bool CompactibleSpace::insert_deadspace(size_t& allowed_deadspace_words,
- HeapWord* q, size_t deadlength) {
- @@ -442,12 +500,17 @@
- #define adjust_obj_size(s) s
-
- void CompactibleSpace::prepare_for_compaction(CompactPoint* cp) {
- - SCAN_AND_FORWARD(cp, end, block_is_obj, block_size);
- + SCAN_AND_FORWARD(cp, end, block_is_obj, block_size, false);
- }
-
- // Faster object search.
- void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) {
- - SCAN_AND_FORWARD(cp, top, block_is_always_obj, obj_size);
- + if (!Universe::is_redefining_gc_run()) {
- + SCAN_AND_FORWARD(cp, top, block_is_always_obj, obj_size, false);
- + } else {
- + // Redefinition run
- + SCAN_AND_FORWARD(cp, top, block_is_always_obj, obj_size, true);
- + }
- }
-
- void Space::adjust_pointers() {
- @@ -485,6 +548,111 @@
- assert(q == t, "just checking");
- }
-
- +
- +#ifdef ASSERT
- +
- +int CompactibleSpace::space_index(oop obj) {
- + GenCollectedHeap* heap = GenCollectedHeap::heap();
- +
- + //if (heap->is_in_permanent(obj)) {
- + // return -1;
- + //}
- +
- + int index = 0;
- + for (int i = heap->n_gens() - 1; i >= 0; i--) {
- + Generation* gen = heap->get_gen(i);
- + CompactibleSpace* space = gen->first_compaction_space();
- + while (space != NULL) {
- + if (space->is_in_reserved(obj)) {
- + return index;
- + }
- + space = space->next_compaction_space();
- + index++;
- + }
- + }
- +
- + tty->print_cr("could not compute space_index for %08xh", (HeapWord*)obj);
- + index = 0;
- + for (int i = heap->n_gens() - 1; i >= 0; i--) {
- + Generation* gen = heap->get_gen(i);
- + tty->print_cr(" generation %s: %08xh - %08xh", gen->name(), gen->reserved().start(), gen->reserved().end());
- +
- + CompactibleSpace* space = gen->first_compaction_space();
- + while (space != NULL) {
- + tty->print_cr(" %2d space %08xh - %08xh", index, space->bottom(), space->end());
- + space = space->next_compaction_space();
- + index++;
- + }
- + }
- +
- + ShouldNotReachHere();
- + return 0;
- +}
- +#endif
- +
- +bool CompactibleSpace::must_rescue(oop old_obj, oop new_obj) {
- + // Only redefined objects can have the need to be rescued.
- + if (oop(old_obj)->klass()->new_version() == NULL) return false;
- +
- + //if (old_obj->is_perm()) {
- + // // This object is in perm gen: Always rescue to satisfy invariant obj->klass() <= obj.
- + // return true;
- + //}
- +
- + int new_size = old_obj->size_given_klass(oop(old_obj)->klass()->new_version());
- + int original_size = old_obj->size();
- +
- + Generation* tenured_gen = GenCollectedHeap::heap()->get_gen(1);
- + bool old_in_tenured = tenured_gen->is_in_reserved(old_obj);
- + bool new_in_tenured = tenured_gen->is_in_reserved(new_obj);
- + if (old_in_tenured == new_in_tenured) {
- + // Rescue if object may overlap with a higher memory address.
- + bool overlap = ((HeapWord*)old_obj + original_size < (HeapWord*)new_obj + new_size);
- + if (old_in_tenured) {
- + // Old and new address are in same space, so just compare the address.
- + // Must rescue if object moves towards the top of the space.
- + assert(space_index(old_obj) == space_index(new_obj), "old_obj and new_obj must be in same space");
- + } else {
- + // In the new generation, eden is located before the from space, so a
- + // simple pointer comparison is sufficient.
- + assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(old_obj), "old_obj must be in DefNewGeneration");
- + assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(new_obj), "new_obj must be in DefNewGeneration");
- + assert(overlap == (space_index(old_obj) < space_index(new_obj)), "slow and fast computation must yield same result");
- + }
- + return overlap;
- +
- + } else {
- + assert(space_index(old_obj) != space_index(new_obj), "old_obj and new_obj must be in different spaces");
- + if (tenured_gen->is_in_reserved(new_obj)) {
- + // Must never rescue when moving from the new into the old generation.
- + assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(old_obj), "old_obj must be in DefNewGeneration");
- + assert(space_index(old_obj) > space_index(new_obj), "must be");
- + return false;
- +
- + } else /* if (tenured_gen->is_in_reserved(old_obj)) */ {
- + // Must always rescue when moving from the old into the new generation.
- + assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(new_obj), "new_obj must be in DefNewGeneration");
- + assert(space_index(old_obj) < space_index(new_obj), "must be");
- + return true;
- + }
- + }
- +}
- +
- +HeapWord* CompactibleSpace::rescue(HeapWord* old_obj) {
- + assert(must_rescue(oop(old_obj), oop(old_obj)->forwardee()), "do not call otherwise");
- +
- + int size = oop(old_obj)->size();
- + HeapWord* rescued_obj = NEW_RESOURCE_ARRAY(HeapWord, size);
- + Copy::aligned_disjoint_words(old_obj, rescued_obj, size);
- +
- + if (MarkSweep::_rescued_oops == NULL) {
- + MarkSweep::_rescued_oops = new GrowableArray<HeapWord*>(128);
- + }
- +
- + MarkSweep::_rescued_oops->append(rescued_obj);
- + return rescued_obj;
- +}
- +
- void CompactibleSpace::adjust_pointers() {
- // Check first is there is any work to do.
- if (used() == 0) {
- @@ -495,7 +663,12 @@
- }
-
- void CompactibleSpace::compact() {
- - SCAN_AND_COMPACT(obj_size);
- + if(!Universe::is_redefining_gc_run()) {
- + SCAN_AND_COMPACT(obj_size, false);
- + } else {
- + // Redefinition run
- + SCAN_AND_COMPACT(obj_size, true)
- + }
- }
-
- void Space::print_short() const { print_short_on(tty); }
- diff -r dc85548673e7 src/share/vm/memory/space.hpp
- --- a/src/share/vm/memory/space.hpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/memory/space.hpp Wed Apr 01 11:22:01 2015 -0700
- @@ -392,6 +392,9 @@
- // indicates when the next such action should be taken.
- virtual void prepare_for_compaction(CompactPoint* cp);
- // MarkSweep support phase3
- + DEBUG_ONLY(int space_index(oop obj));
- + bool must_rescue(oop old_obj, oop new_obj);
- + HeapWord* rescue(HeapWord* old_obj);
- virtual void adjust_pointers();
- // MarkSweep support phase4
- virtual void compact();
- @@ -421,6 +424,15 @@
- // accordingly".
- virtual HeapWord* forward(oop q, size_t size, CompactPoint* cp,
- HeapWord* compact_top);
- + // (DCEVM) same as forwad, but can rescue objects. Invoked only during
- + // redefinition runs
- + HeapWord* forward_with_rescue(HeapWord* q, size_t size, CompactPoint* cp,
- + HeapWord* compact_top);
- +
- + HeapWord* forward_rescued(CompactPoint* cp, HeapWord* compact_top);
- +
- + // (tw) Compute new compact top without actually forwarding the object.
- + virtual HeapWord* forward_compact_top(size_t size, CompactPoint* cp, HeapWord* compact_top);
-
- // Return a size with adjusments as required of the space.
- virtual size_t adjust_object_size_v(size_t size) const { return size; }
- diff -r dc85548673e7 src/share/vm/memory/space.inline.hpp
- --- a/src/share/vm/memory/space.inline.hpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/memory/space.inline.hpp Wed Apr 01 11:22:01 2015 -0700
- @@ -35,7 +35,7 @@
- return block_start_const(p);
- }
-
- -#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size) { \
- +#define SCAN_AND_FORWARD(cp,scan_limit,block_is_obj,block_size,redefinition_run) { \
- /* Compute the new addresses for the live objects and store it in the mark \
- * Used by universe::mark_sweep_phase2() \
- */ \
- @@ -93,7 +93,17 @@
- /* prefetch beyond q */ \
- Prefetch::write(q, interval); \
- size_t size = block_size(q); \
- + if (redefinition_run) { \
- + compact_top = cp->space->forward_with_rescue(q, size, \
- + cp, compact_top); \
- + if (q < first_dead && oop(q)->is_gc_marked()) { \
- + /* Was moved (otherwise, forward would reset mark), \
- + set first_dead to here */ \
- + first_dead = q; \
- + } \
- + } else { \
- compact_top = cp->space->forward(oop(q), size, cp, compact_top); \
- + } \
- q += size; \
- end_of_live = q; \
- } else { \
- @@ -142,6 +152,8 @@
- } \
- } \
- \
- + if (redefinition_run) { compact_top = forward_rescued(cp, compact_top); } \
- + \
- assert(q == t, "just checking"); \
- if (liveRange != NULL) { \
- liveRange->set_end(q); \
- @@ -188,13 +200,8 @@
- q += size; \
- } \
- \
- - if (_first_dead == t) { \
- - q = t; \
- - } else { \
- - /* $$$ This is funky. Using this to read the previously written \
- - * LiveRange. See also use below. */ \
- - q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer(); \
- - } \
- + /* (DCEVM) first_dead can be live object if we move/rescue resized objects */ \
- + q = _first_dead; \
- } \
- \
- const intx interval = PrefetchScanIntervalInBytes; \
- @@ -222,7 +229,7 @@
- assert(q == t, "just checking"); \
- }
-
- -#define SCAN_AND_COMPACT(obj_size) { \
- +#define SCAN_AND_COMPACT(obj_size, redefinition_run) { \
- /* Copy all live objects to their new location \
- * Used by MarkSweep::mark_sweep_phase4() */ \
- \
- @@ -247,13 +254,9 @@
- } \
- ) /* debug_only */ \
- \
- - if (_first_dead == t) { \
- - q = t; \
- - } else { \
- - /* $$$ Funky */ \
- - q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer(); \
- + /* (DCEVM) first_dead can be live object if we move/rescue resized objects */ \
- + q = _first_dead; \
- } \
- - } \
- \
- const intx scan_interval = PrefetchScanIntervalInBytes; \
- const intx copy_interval = PrefetchCopyIntervalInBytes; \
- @@ -271,11 +274,34 @@
- size_t size = obj_size(q); \
- HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee(); \
- \
- + if (redefinition_run && must_rescue(oop(q), oop(q)->forwardee())) { \
- + rescue(q); \
- + debug_only(Copy::fill_to_words(q, size, 0)); \
- + q += size; \
- + continue; \
- + } \
- + \
- /* prefetch beyond compaction_top */ \
- Prefetch::write(compaction_top, copy_interval); \
- \
- /* copy object and reinit its mark */ \
- - assert(q != compaction_top, "everything in this pass should be moving"); \
- + assert(q != compaction_top || oop(q)->klass()->new_version() != NULL, \
- + "everything in this pass should be moving"); \
- + if (redefinition_run && oop(q)->klass()->new_version() != NULL) { \
- + Klass* new_version = oop(q)->klass()->new_version(); \
- + if (new_version->update_information() == NULL) { \
- + Copy::aligned_conjoint_words(q, compaction_top, size); \
- + oop(compaction_top)->set_klass(new_version); \
- + } else { \
- + MarkSweep::update_fields(oop(q), oop(compaction_top)); \
- + } \
- + oop(compaction_top)->init_mark(); \
- + assert(oop(compaction_top)->klass() != NULL, "should have a class"); \
- + \
- + debug_only(prev_q = q); \
- + q += size; \
- + continue; \
- + } \
- Copy::aligned_conjoint_words(q, compaction_top, size); \
- oop(compaction_top)->init_mark(); \
- assert(oop(compaction_top)->klass() != NULL, "should have a class"); \
- diff -r dc85548673e7 src/share/vm/memory/universe.cpp
- --- a/src/share/vm/memory/universe.cpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/memory/universe.cpp Wed Apr 01 11:22:01 2015 -0700
- @@ -84,6 +84,8 @@
-
- PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
-
- +bool Universe::_is_redefining_gc_run = false;
- +
- // Known objects
- Klass* Universe::_boolArrayKlassObj = NULL;
- Klass* Universe::_byteArrayKlassObj = NULL;
- diff -r dc85548673e7 src/share/vm/memory/universe.hpp
- --- a/src/share/vm/memory/universe.hpp Tue Mar 31 18:13:48 2015 -0700
- +++ b/src/share/vm/memory/universe.hpp Wed Apr 01 11:22:01 2015 -0700
- @@ -251,7 +251,13 @@
-
- static void compute_verify_oop_data();
-
- + static bool _is_redefining_gc_run;
- +
- public:
- +
- + static bool is_redefining_gc_run() { return _is_redefining_gc_run; }
- + static void set_redefining_gc_run(bool b) { _is_redefining_gc_run = b; }
- +
- // Known classes in the VM
- static Klass* boolArrayKlassObj() { return _boolArrayKlassObj; }
- static Klass* byteArrayKlassObj() { return _byteArrayKlassObj; }
|