提交 08159558 编写于 作者: J johnc

8004132: SerialGC: ValidateMarkSweep broken when running GCOld

Summary: Remove bit-rotten ValidateMarkSweep functionality and flag.
Reviewed-by: johnc, jmasa
Contributed-by: Ntamao <tao.mao@oracle.com>
上级 8f14f3b0
...@@ -214,7 +214,6 @@ HeapWord* CompactibleFreeListSpace::forward(oop q, size_t size, ...@@ -214,7 +214,6 @@ HeapWord* CompactibleFreeListSpace::forward(oop q, size_t size,
assert(q->forwardee() == NULL, "should be forwarded to NULL"); assert(q->forwardee() == NULL, "should be forwarded to NULL");
} }
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(q, adjusted_size));
compact_top += adjusted_size; compact_top += adjusted_size;
// we need to update the offset table so that the beginnings of objects can be // we need to update the offset table so that the beginnings of objects can be
......
...@@ -282,10 +282,8 @@ class G1AdjustPointersClosure: public HeapRegionClosure { ...@@ -282,10 +282,8 @@ class G1AdjustPointersClosure: public HeapRegionClosure {
if (r->startsHumongous()) { if (r->startsHumongous()) {
// We must adjust the pointers on the single H object. // We must adjust the pointers on the single H object.
oop obj = oop(r->bottom()); oop obj = oop(r->bottom());
debug_only(GenMarkSweep::track_interior_pointers(obj));
// point all the oops to the new location // point all the oops to the new location
obj->adjust_pointers(); obj->adjust_pointers();
debug_only(GenMarkSweep::check_interior_pointers());
} }
} else { } else {
// This really ought to be "as_CompactibleSpace"... // This really ought to be "as_CompactibleSpace"...
......
...@@ -164,7 +164,6 @@ void PSMarkSweepDecorator::precompact() { ...@@ -164,7 +164,6 @@ void PSMarkSweepDecorator::precompact() {
start_array->allocate_block(compact_top); start_array->allocate_block(compact_top);
} }
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), size));
compact_top += size; compact_top += size;
assert(compact_top <= dest->space()->end(), assert(compact_top <= dest->space()->end(),
"Exceeding space in destination"); "Exceeding space in destination");
...@@ -225,7 +224,6 @@ void PSMarkSweepDecorator::precompact() { ...@@ -225,7 +224,6 @@ void PSMarkSweepDecorator::precompact() {
start_array->allocate_block(compact_top); start_array->allocate_block(compact_top);
} }
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(oop(q), sz));
compact_top += sz; compact_top += sz;
assert(compact_top <= dest->space()->end(), assert(compact_top <= dest->space()->end(),
"Exceeding space in destination"); "Exceeding space in destination");
...@@ -304,11 +302,8 @@ void PSMarkSweepDecorator::adjust_pointers() { ...@@ -304,11 +302,8 @@ void PSMarkSweepDecorator::adjust_pointers() {
HeapWord* end = _first_dead; HeapWord* end = _first_dead;
while (q < end) { while (q < end) {
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));
// point all the oops to the new location // point all the oops to the new location
size_t size = oop(q)->adjust_pointers(); size_t size = oop(q)->adjust_pointers();
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));
q += size; q += size;
} }
...@@ -328,11 +323,8 @@ void PSMarkSweepDecorator::adjust_pointers() { ...@@ -328,11 +323,8 @@ void PSMarkSweepDecorator::adjust_pointers() {
Prefetch::write(q, interval); Prefetch::write(q, interval);
if (oop(q)->is_gc_marked()) { if (oop(q)->is_gc_marked()) {
// q is alive // q is alive
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));
// point all the oops to the new location // point all the oops to the new location
size_t size = oop(q)->adjust_pointers(); size_t size = oop(q)->adjust_pointers();
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));
debug_only(prev_q = q); debug_only(prev_q = q);
q += size; q += size;
} else { } else {
...@@ -366,7 +358,6 @@ void PSMarkSweepDecorator::compact(bool mangle_free_space ) { ...@@ -366,7 +358,6 @@ void PSMarkSweepDecorator::compact(bool mangle_free_space ) {
while (q < end) { while (q < end) {
size_t size = oop(q)->size(); size_t size = oop(q)->size();
assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)"); assert(!oop(q)->is_gc_marked(), "should be unmarked (special dense prefix handling)");
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q));
debug_only(prev_q = q); debug_only(prev_q = q);
q += size; q += size;
} }
...@@ -401,7 +392,6 @@ void PSMarkSweepDecorator::compact(bool mangle_free_space ) { ...@@ -401,7 +392,6 @@ void PSMarkSweepDecorator::compact(bool mangle_free_space ) {
Prefetch::write(compaction_top, copy_interval); Prefetch::write(compaction_top, copy_interval);
// copy object and reinit its mark // copy object and reinit its mark
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, compaction_top));
assert(q != compaction_top, "everything in this pass should be moving"); assert(q != compaction_top, "everything in this pass should be moving");
Copy::aligned_conjoint_words(q, compaction_top, size); Copy::aligned_conjoint_words(q, compaction_top, size);
oop(compaction_top)->init_mark(); oop(compaction_top)->init_mark();
......
...@@ -99,25 +99,6 @@ double PSParallelCompact::_dwl_adjustment; ...@@ -99,25 +99,6 @@ double PSParallelCompact::_dwl_adjustment;
bool PSParallelCompact::_dwl_initialized = false; bool PSParallelCompact::_dwl_initialized = false;
#endif // #ifdef ASSERT #endif // #ifdef ASSERT
#ifdef VALIDATE_MARK_SWEEP
GrowableArray<void*>* PSParallelCompact::_root_refs_stack = NULL;
GrowableArray<oop> * PSParallelCompact::_live_oops = NULL;
GrowableArray<oop> * PSParallelCompact::_live_oops_moved_to = NULL;
GrowableArray<size_t>* PSParallelCompact::_live_oops_size = NULL;
size_t PSParallelCompact::_live_oops_index = 0;
GrowableArray<void*>* PSParallelCompact::_other_refs_stack = NULL;
GrowableArray<void*>* PSParallelCompact::_adjusted_pointers = NULL;
bool PSParallelCompact::_pointer_tracking = false;
bool PSParallelCompact::_root_tracking = true;
GrowableArray<HeapWord*>* PSParallelCompact::_cur_gc_live_oops = NULL;
GrowableArray<HeapWord*>* PSParallelCompact::_cur_gc_live_oops_moved_to = NULL;
GrowableArray<size_t> * PSParallelCompact::_cur_gc_live_oops_size = NULL;
GrowableArray<HeapWord*>* PSParallelCompact::_last_gc_live_oops = NULL;
GrowableArray<HeapWord*>* PSParallelCompact::_last_gc_live_oops_moved_to = NULL;
GrowableArray<size_t> * PSParallelCompact::_last_gc_live_oops_size = NULL;
#endif
void SplitInfo::record(size_t src_region_idx, size_t partial_obj_size, void SplitInfo::record(size_t src_region_idx, size_t partial_obj_size,
HeapWord* destination) HeapWord* destination)
{ {
...@@ -2715,151 +2696,6 @@ void PSParallelCompact::verify_complete(SpaceId space_id) { ...@@ -2715,151 +2696,6 @@ void PSParallelCompact::verify_complete(SpaceId space_id) {
} }
#endif // #ifdef ASSERT #endif // #ifdef ASSERT
#ifdef VALIDATE_MARK_SWEEP
void PSParallelCompact::track_adjusted_pointer(void* p, bool isroot) {
if (!ValidateMarkSweep)
return;
if (!isroot) {
if (_pointer_tracking) {
guarantee(_adjusted_pointers->contains(p), "should have seen this pointer");
_adjusted_pointers->remove(p);
}
} else {
ptrdiff_t index = _root_refs_stack->find(p);
if (index != -1) {
int l = _root_refs_stack->length();
if (l > 0 && l - 1 != index) {
void* last = _root_refs_stack->pop();
assert(last != p, "should be different");
_root_refs_stack->at_put(index, last);
} else {
_root_refs_stack->remove(p);
}
}
}
}
void PSParallelCompact::check_adjust_pointer(void* p) {
_adjusted_pointers->push(p);
}
class AdjusterTracker: public OopClosure {
public:
AdjusterTracker() {};
void do_oop(oop* o) { PSParallelCompact::check_adjust_pointer(o); }
void do_oop(narrowOop* o) { PSParallelCompact::check_adjust_pointer(o); }
};
void PSParallelCompact::track_interior_pointers(oop obj) {
if (ValidateMarkSweep) {
_adjusted_pointers->clear();
_pointer_tracking = true;
AdjusterTracker checker;
obj->oop_iterate_no_header(&checker);
}
}
void PSParallelCompact::check_interior_pointers() {
if (ValidateMarkSweep) {
_pointer_tracking = false;
guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers");
}
}
void PSParallelCompact::reset_live_oop_tracking() {
if (ValidateMarkSweep) {
guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops");
_live_oops_index = 0;
}
}
void PSParallelCompact::register_live_oop(oop p, size_t size) {
if (ValidateMarkSweep) {
_live_oops->push(p);
_live_oops_size->push(size);
_live_oops_index++;
}
}
void PSParallelCompact::validate_live_oop(oop p, size_t size) {
if (ValidateMarkSweep) {
oop obj = _live_oops->at((int)_live_oops_index);
guarantee(obj == p, "should be the same object");
guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size");
_live_oops_index++;
}
}
void PSParallelCompact::live_oop_moved_to(HeapWord* q, size_t size,
HeapWord* compaction_top) {
assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top),
"should be moved to forwarded location");
if (ValidateMarkSweep) {
PSParallelCompact::validate_live_oop(oop(q), size);
_live_oops_moved_to->push(oop(compaction_top));
}
if (RecordMarkSweepCompaction) {
_cur_gc_live_oops->push(q);
_cur_gc_live_oops_moved_to->push(compaction_top);
_cur_gc_live_oops_size->push(size);
}
}
void PSParallelCompact::compaction_complete() {
if (RecordMarkSweepCompaction) {
GrowableArray<HeapWord*>* _tmp_live_oops = _cur_gc_live_oops;
GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to;
GrowableArray<size_t> * _tmp_live_oops_size = _cur_gc_live_oops_size;
_cur_gc_live_oops = _last_gc_live_oops;
_cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to;
_cur_gc_live_oops_size = _last_gc_live_oops_size;
_last_gc_live_oops = _tmp_live_oops;
_last_gc_live_oops_moved_to = _tmp_live_oops_moved_to;
_last_gc_live_oops_size = _tmp_live_oops_size;
}
}
void PSParallelCompact::print_new_location_of_heap_address(HeapWord* q) {
if (!RecordMarkSweepCompaction) {
tty->print_cr("Requires RecordMarkSweepCompaction to be enabled");
return;
}
if (_last_gc_live_oops == NULL) {
tty->print_cr("No compaction information gathered yet");
return;
}
for (int i = 0; i < _last_gc_live_oops->length(); i++) {
HeapWord* old_oop = _last_gc_live_oops->at(i);
size_t sz = _last_gc_live_oops_size->at(i);
if (old_oop <= q && q < (old_oop + sz)) {
HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i);
size_t offset = (q - old_oop);
tty->print_cr("Address " PTR_FORMAT, q);
tty->print_cr(" Was in oop " PTR_FORMAT ", size %d, at offset %d", old_oop, sz, offset);
tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset);
return;
}
}
tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q);
}
#endif //VALIDATE_MARK_SWEEP
// Update interior oops in the ranges of regions [beg_region, end_region). // Update interior oops in the ranges of regions [beg_region, end_region).
void void
PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm, PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm,
......
...@@ -1006,34 +1006,6 @@ class PSParallelCompact : AllStatic { ...@@ -1006,34 +1006,6 @@ class PSParallelCompact : AllStatic {
// Reset time since last full gc // Reset time since last full gc
static void reset_millis_since_last_gc(); static void reset_millis_since_last_gc();
protected:
#ifdef VALIDATE_MARK_SWEEP
static GrowableArray<void*>* _root_refs_stack;
static GrowableArray<oop> * _live_oops;
static GrowableArray<oop> * _live_oops_moved_to;
static GrowableArray<size_t>* _live_oops_size;
static size_t _live_oops_index;
static size_t _live_oops_index_at_perm;
static GrowableArray<void*>* _other_refs_stack;
static GrowableArray<void*>* _adjusted_pointers;
static bool _pointer_tracking;
static bool _root_tracking;
// The following arrays are saved since the time of the last GC and
// assist in tracking down problems where someone has done an errant
// store into the heap, usually to an oop that wasn't properly
// handleized across a GC. If we crash or otherwise fail before the
// next GC, we can query these arrays to find out the object we had
// intended to do the store to (assuming it is still alive) and the
// offset within that object. Covered under RecordMarkSweepCompaction.
static GrowableArray<HeapWord*> * _cur_gc_live_oops;
static GrowableArray<HeapWord*> * _cur_gc_live_oops_moved_to;
static GrowableArray<size_t>* _cur_gc_live_oops_size;
static GrowableArray<HeapWord*> * _last_gc_live_oops;
static GrowableArray<HeapWord*> * _last_gc_live_oops_moved_to;
static GrowableArray<size_t>* _last_gc_live_oops_size;
#endif
public: public:
class MarkAndPushClosure: public OopClosure { class MarkAndPushClosure: public OopClosure {
private: private:
...@@ -1191,25 +1163,6 @@ class PSParallelCompact : AllStatic { ...@@ -1191,25 +1163,6 @@ class PSParallelCompact : AllStatic {
// Time since last full gc (in milliseconds). // Time since last full gc (in milliseconds).
static jlong millis_since_last_gc(); static jlong millis_since_last_gc();
#ifdef VALIDATE_MARK_SWEEP
static void track_adjusted_pointer(void* p, bool isroot);
static void check_adjust_pointer(void* p);
static void track_interior_pointers(oop obj);
static void check_interior_pointers();
static void reset_live_oop_tracking();
static void register_live_oop(oop p, size_t size);
static void validate_live_oop(oop p, size_t size);
static void live_oop_moved_to(HeapWord* q, size_t size, HeapWord* compaction_top);
static void compaction_complete();
// Querying operation of RecordMarkSweepCompaction results.
// Finds and prints the current base oop and offset for a word
// within an oop that was live during the last GC. Helpful for
// tracking down heap stomps.
static void print_new_location_of_heap_address(HeapWord* q);
#endif // #ifdef VALIDATE_MARK_SWEEP
#ifndef PRODUCT #ifndef PRODUCT
// Debugging support. // Debugging support.
static const char* space_names[last_space_id]; static const char* space_names[last_space_id];
...@@ -1250,12 +1203,7 @@ template <class T> ...@@ -1250,12 +1203,7 @@ template <class T>
inline void PSParallelCompact::follow_root(ParCompactionManager* cm, T* p) { inline void PSParallelCompact::follow_root(ParCompactionManager* cm, T* p) {
assert(!Universe::heap()->is_in_reserved(p), assert(!Universe::heap()->is_in_reserved(p),
"roots shouldn't be things within the heap"); "roots shouldn't be things within the heap");
#ifdef VALIDATE_MARK_SWEEP
if (ValidateMarkSweep) {
guarantee(!_root_refs_stack->contains(p), "should only be in here once");
_root_refs_stack->push(p);
}
#endif
T heap_oop = oopDesc::load_heap_oop(p); T heap_oop = oopDesc::load_heap_oop(p);
if (!oopDesc::is_null(heap_oop)) { if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
...@@ -1294,20 +1242,10 @@ inline void PSParallelCompact::adjust_pointer(T* p, bool isroot) { ...@@ -1294,20 +1242,10 @@ inline void PSParallelCompact::adjust_pointer(T* p, bool isroot) {
oopDesc::encode_store_heap_oop_not_null(p, new_obj); oopDesc::encode_store_heap_oop_not_null(p, new_obj);
} }
} }
VALIDATE_MARK_SWEEP_ONLY(track_adjusted_pointer(p, isroot));
} }
template <class T> template <class T>
inline void PSParallelCompact::KeepAliveClosure::do_oop_work(T* p) { inline void PSParallelCompact::KeepAliveClosure::do_oop_work(T* p) {
#ifdef VALIDATE_MARK_SWEEP
if (ValidateMarkSweep) {
if (!Universe::heap()->is_in_reserved(p)) {
_root_refs_stack->push(p);
} else {
_other_refs_stack->push(p);
}
}
#endif
mark_and_push(_compaction_manager, p); mark_and_push(_compaction_manager, p);
} }
......
...@@ -42,26 +42,6 @@ size_t MarkSweep::_preserved_count_max = 0; ...@@ -42,26 +42,6 @@ size_t MarkSweep::_preserved_count_max = 0;
PreservedMark* MarkSweep::_preserved_marks = NULL; PreservedMark* MarkSweep::_preserved_marks = NULL;
ReferenceProcessor* MarkSweep::_ref_processor = NULL; ReferenceProcessor* MarkSweep::_ref_processor = NULL;
#ifdef VALIDATE_MARK_SWEEP
GrowableArray<void*>* MarkSweep::_root_refs_stack = NULL;
GrowableArray<oop> * MarkSweep::_live_oops = NULL;
GrowableArray<oop> * MarkSweep::_live_oops_moved_to = NULL;
GrowableArray<size_t>* MarkSweep::_live_oops_size = NULL;
size_t MarkSweep::_live_oops_index = 0;
size_t MarkSweep::_live_oops_index_at_perm = 0;
GrowableArray<void*>* MarkSweep::_other_refs_stack = NULL;
GrowableArray<void*>* MarkSweep::_adjusted_pointers = NULL;
bool MarkSweep::_pointer_tracking = false;
bool MarkSweep::_root_tracking = true;
GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops = NULL;
GrowableArray<HeapWord*>* MarkSweep::_cur_gc_live_oops_moved_to = NULL;
GrowableArray<size_t> * MarkSweep::_cur_gc_live_oops_size = NULL;
GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops = NULL;
GrowableArray<HeapWord*>* MarkSweep::_last_gc_live_oops_moved_to = NULL;
GrowableArray<size_t> * MarkSweep::_last_gc_live_oops_size = NULL;
#endif
MarkSweep::FollowRootClosure MarkSweep::follow_root_closure; MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true); CodeBlobToOopClosure MarkSweep::follow_code_root_closure(&MarkSweep::follow_root_closure, /*do_marking=*/ true);
...@@ -185,142 +165,6 @@ void MarkSweep::restore_marks() { ...@@ -185,142 +165,6 @@ void MarkSweep::restore_marks() {
} }
} }
#ifdef VALIDATE_MARK_SWEEP
void MarkSweep::track_adjusted_pointer(void* p, bool isroot) {
if (!ValidateMarkSweep)
return;
if (!isroot) {
if (_pointer_tracking) {
guarantee(_adjusted_pointers->contains(p), "should have seen this pointer");
_adjusted_pointers->remove(p);
}
} else {
ptrdiff_t index = _root_refs_stack->find(p);
if (index != -1) {
int l = _root_refs_stack->length();
if (l > 0 && l - 1 != index) {
void* last = _root_refs_stack->pop();
assert(last != p, "should be different");
_root_refs_stack->at_put(index, last);
} else {
_root_refs_stack->remove(p);
}
}
}
}
void MarkSweep::check_adjust_pointer(void* p) {
_adjusted_pointers->push(p);
}
class AdjusterTracker: public OopClosure {
public:
AdjusterTracker() {}
void do_oop(oop* o) { MarkSweep::check_adjust_pointer(o); }
void do_oop(narrowOop* o) { MarkSweep::check_adjust_pointer(o); }
};
void MarkSweep::track_interior_pointers(oop obj) {
if (ValidateMarkSweep) {
_adjusted_pointers->clear();
_pointer_tracking = true;
AdjusterTracker checker;
obj->oop_iterate_no_header(&checker);
}
}
void MarkSweep::check_interior_pointers() {
if (ValidateMarkSweep) {
_pointer_tracking = false;
guarantee(_adjusted_pointers->length() == 0, "should have processed the same pointers");
}
}
void MarkSweep::reset_live_oop_tracking() {
if (ValidateMarkSweep) {
guarantee((size_t)_live_oops->length() == _live_oops_index, "should be at end of live oops");
_live_oops_index = 0;
}
}
void MarkSweep::register_live_oop(oop p, size_t size) {
if (ValidateMarkSweep) {
_live_oops->push(p);
_live_oops_size->push(size);
_live_oops_index++;
}
}
void MarkSweep::validate_live_oop(oop p, size_t size) {
if (ValidateMarkSweep) {
oop obj = _live_oops->at((int)_live_oops_index);
guarantee(obj == p, "should be the same object");
guarantee(_live_oops_size->at((int)_live_oops_index) == size, "should be the same size");
_live_oops_index++;
}
}
void MarkSweep::live_oop_moved_to(HeapWord* q, size_t size,
HeapWord* compaction_top) {
assert(oop(q)->forwardee() == NULL || oop(q)->forwardee() == oop(compaction_top),
"should be moved to forwarded location");
if (ValidateMarkSweep) {
MarkSweep::validate_live_oop(oop(q), size);
_live_oops_moved_to->push(oop(compaction_top));
}
if (RecordMarkSweepCompaction) {
_cur_gc_live_oops->push(q);
_cur_gc_live_oops_moved_to->push(compaction_top);
_cur_gc_live_oops_size->push(size);
}
}
void MarkSweep::compaction_complete() {
if (RecordMarkSweepCompaction) {
GrowableArray<HeapWord*>* _tmp_live_oops = _cur_gc_live_oops;
GrowableArray<HeapWord*>* _tmp_live_oops_moved_to = _cur_gc_live_oops_moved_to;
GrowableArray<size_t> * _tmp_live_oops_size = _cur_gc_live_oops_size;
_cur_gc_live_oops = _last_gc_live_oops;
_cur_gc_live_oops_moved_to = _last_gc_live_oops_moved_to;
_cur_gc_live_oops_size = _last_gc_live_oops_size;
_last_gc_live_oops = _tmp_live_oops;
_last_gc_live_oops_moved_to = _tmp_live_oops_moved_to;
_last_gc_live_oops_size = _tmp_live_oops_size;
}
}
void MarkSweep::print_new_location_of_heap_address(HeapWord* q) {
if (!RecordMarkSweepCompaction) {
tty->print_cr("Requires RecordMarkSweepCompaction to be enabled");
return;
}
if (_last_gc_live_oops == NULL) {
tty->print_cr("No compaction information gathered yet");
return;
}
for (int i = 0; i < _last_gc_live_oops->length(); i++) {
HeapWord* old_oop = _last_gc_live_oops->at(i);
size_t sz = _last_gc_live_oops_size->at(i);
if (old_oop <= q && q < (old_oop + sz)) {
HeapWord* new_oop = _last_gc_live_oops_moved_to->at(i);
size_t offset = (q - old_oop);
tty->print_cr("Address " PTR_FORMAT, q);
tty->print_cr(" Was in oop " PTR_FORMAT ", size " SIZE_FORMAT ", at offset " SIZE_FORMAT, old_oop, sz, offset);
tty->print_cr(" Now in oop " PTR_FORMAT ", actual address " PTR_FORMAT, new_oop, new_oop + offset);
return;
}
}
tty->print_cr("Address " PTR_FORMAT " not found in live oop information from last GC", q);
}
#endif //VALIDATE_MARK_SWEEP
MarkSweep::IsAliveClosure MarkSweep::is_alive; MarkSweep::IsAliveClosure MarkSweep::is_alive;
void MarkSweep::IsAliveClosure::do_object(oop p) { ShouldNotReachHere(); } void MarkSweep::IsAliveClosure::do_object(oop p) { ShouldNotReachHere(); }
......
...@@ -44,21 +44,6 @@ class DataLayout; ...@@ -44,21 +44,6 @@ class DataLayout;
// //
// Class unloading will only occur when a full gc is invoked. // Class unloading will only occur when a full gc is invoked.
// If VALIDATE_MARK_SWEEP is defined, the -XX:+ValidateMarkSweep flag will
// be operational, and will provide slow but comprehensive self-checks within
// the GC. This is not enabled by default in product or release builds,
// since the extra call to track_adjusted_pointer() in _adjust_pointer()
// would be too much overhead, and would disturb performance measurement.
// However, debug builds are sometimes way too slow to run GC tests!
#ifdef ASSERT
#define VALIDATE_MARK_SWEEP 1
#endif
#ifdef VALIDATE_MARK_SWEEP
#define VALIDATE_MARK_SWEEP_ONLY(code) code
#else
#define VALIDATE_MARK_SWEEP_ONLY(code)
#endif
// declared at end // declared at end
class PreservedMark; class PreservedMark;
...@@ -147,33 +132,6 @@ class MarkSweep : AllStatic { ...@@ -147,33 +132,6 @@ class MarkSweep : AllStatic {
// Reference processing (used in ...follow_contents) // Reference processing (used in ...follow_contents)
static ReferenceProcessor* _ref_processor; static ReferenceProcessor* _ref_processor;
#ifdef VALIDATE_MARK_SWEEP
static GrowableArray<void*>* _root_refs_stack;
static GrowableArray<oop> * _live_oops;
static GrowableArray<oop> * _live_oops_moved_to;
static GrowableArray<size_t>* _live_oops_size;
static size_t _live_oops_index;
static size_t _live_oops_index_at_perm;
static GrowableArray<void*>* _other_refs_stack;
static GrowableArray<void*>* _adjusted_pointers;
static bool _pointer_tracking;
static bool _root_tracking;
// The following arrays are saved since the time of the last GC and
// assist in tracking down problems where someone has done an errant
// store into the heap, usually to an oop that wasn't properly
// handleized across a GC. If we crash or otherwise fail before the
// next GC, we can query these arrays to find out the object we had
// intended to do the store to (assuming it is still alive) and the
// offset within that object. Covered under RecordMarkSweepCompaction.
static GrowableArray<HeapWord*> * _cur_gc_live_oops;
static GrowableArray<HeapWord*> * _cur_gc_live_oops_moved_to;
static GrowableArray<size_t>* _cur_gc_live_oops_size;
static GrowableArray<HeapWord*> * _last_gc_live_oops;
static GrowableArray<HeapWord*> * _last_gc_live_oops_moved_to;
static GrowableArray<size_t>* _last_gc_live_oops_size;
#endif
// Non public closures // Non public closures
static KeepAliveClosure keep_alive; static KeepAliveClosure keep_alive;
...@@ -227,24 +185,6 @@ class MarkSweep : AllStatic { ...@@ -227,24 +185,6 @@ class MarkSweep : AllStatic {
static void adjust_pointer(oop* p) { adjust_pointer(p, false); } static void adjust_pointer(oop* p) { adjust_pointer(p, false); }
static void adjust_pointer(narrowOop* p) { adjust_pointer(p, false); } static void adjust_pointer(narrowOop* p) { adjust_pointer(p, false); }
#ifdef VALIDATE_MARK_SWEEP
static void track_adjusted_pointer(void* p, bool isroot);
static void check_adjust_pointer(void* p);
static void track_interior_pointers(oop obj);
static void check_interior_pointers();
static void reset_live_oop_tracking();
static void register_live_oop(oop p, size_t size);
static void validate_live_oop(oop p, size_t size);
static void live_oop_moved_to(HeapWord* q, size_t size, HeapWord* compaction_top);
static void compaction_complete();
// Querying operation of RecordMarkSweepCompaction results.
// Finds and prints the current base oop and offset for a word
// within an oop that was live during the last GC. Helpful for
// tracking down heap stomps.
static void print_new_location_of_heap_address(HeapWord* q);
#endif
}; };
class PreservedMark VALUE_OBJ_CLASS_SPEC { class PreservedMark VALUE_OBJ_CLASS_SPEC {
......
...@@ -46,12 +46,6 @@ inline void MarkSweep::mark_object(oop obj) { ...@@ -46,12 +46,6 @@ inline void MarkSweep::mark_object(oop obj) {
template <class T> inline void MarkSweep::follow_root(T* p) { template <class T> inline void MarkSweep::follow_root(T* p) {
assert(!Universe::heap()->is_in_reserved(p), assert(!Universe::heap()->is_in_reserved(p),
"roots shouldn't be things within the heap"); "roots shouldn't be things within the heap");
#ifdef VALIDATE_MARK_SWEEP
if (ValidateMarkSweep) {
guarantee(!_root_refs_stack->contains(p), "should only be in here once");
_root_refs_stack->push(p);
}
#endif
T heap_oop = oopDesc::load_heap_oop(p); T heap_oop = oopDesc::load_heap_oop(p);
if (!oopDesc::is_null(heap_oop)) { if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
...@@ -97,19 +91,9 @@ template <class T> inline void MarkSweep::adjust_pointer(T* p, bool isroot) { ...@@ -97,19 +91,9 @@ template <class T> inline void MarkSweep::adjust_pointer(T* p, bool isroot) {
oopDesc::encode_store_heap_oop_not_null(p, new_obj); oopDesc::encode_store_heap_oop_not_null(p, new_obj);
} }
} }
VALIDATE_MARK_SWEEP_ONLY(track_adjusted_pointer(p, isroot));
} }
template <class T> inline void MarkSweep::KeepAliveClosure::do_oop_work(T* p) { template <class T> inline void MarkSweep::KeepAliveClosure::do_oop_work(T* p) {
#ifdef VALIDATE_MARK_SWEEP
if (ValidateMarkSweep) {
if (!Universe::heap()->is_in_reserved(p)) {
_root_refs_stack->push(p);
} else {
_other_refs_stack->push(p);
}
}
#endif
mark_and_push(p); mark_and_push(p);
} }
......
...@@ -100,21 +100,8 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, ...@@ -100,21 +100,8 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp,
mark_sweep_phase3(level); mark_sweep_phase3(level);
VALIDATE_MARK_SWEEP_ONLY(
if (ValidateMarkSweep) {
guarantee(_root_refs_stack->length() == 0, "should be empty by now");
}
)
mark_sweep_phase4(); mark_sweep_phase4();
VALIDATE_MARK_SWEEP_ONLY(
if (ValidateMarkSweep) {
guarantee(_live_oops->length() == _live_oops_moved_to->length(),
"should be the same size");
}
)
restore_marks(); restore_marks();
// Set saved marks for allocation profiler (and other things? -- dld) // Set saved marks for allocation profiler (and other things? -- dld)
...@@ -187,31 +174,6 @@ void GenMarkSweep::allocate_stacks() { ...@@ -187,31 +174,6 @@ void GenMarkSweep::allocate_stacks() {
_preserved_marks = (PreservedMark*)scratch; _preserved_marks = (PreservedMark*)scratch;
_preserved_count = 0; _preserved_count = 0;
#ifdef VALIDATE_MARK_SWEEP
if (ValidateMarkSweep) {
_root_refs_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray<void*>(100, true);
_other_refs_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray<void*>(100, true);
_adjusted_pointers = new (ResourceObj::C_HEAP, mtGC) GrowableArray<void*>(100, true);
_live_oops = new (ResourceObj::C_HEAP, mtGC) GrowableArray<oop>(100, true);
_live_oops_moved_to = new (ResourceObj::C_HEAP, mtGC) GrowableArray<oop>(100, true);
_live_oops_size = new (ResourceObj::C_HEAP, mtGC) GrowableArray<size_t>(100, true);
}
if (RecordMarkSweepCompaction) {
if (_cur_gc_live_oops == NULL) {
_cur_gc_live_oops = new(ResourceObj::C_HEAP, mtGC) GrowableArray<HeapWord*>(100, true);
_cur_gc_live_oops_moved_to = new(ResourceObj::C_HEAP, mtGC) GrowableArray<HeapWord*>(100, true);
_cur_gc_live_oops_size = new(ResourceObj::C_HEAP, mtGC) GrowableArray<size_t>(100, true);
_last_gc_live_oops = new(ResourceObj::C_HEAP, mtGC) GrowableArray<HeapWord*>(100, true);
_last_gc_live_oops_moved_to = new(ResourceObj::C_HEAP, mtGC) GrowableArray<HeapWord*>(100, true);
_last_gc_live_oops_size = new(ResourceObj::C_HEAP, mtGC) GrowableArray<size_t>(100, true);
} else {
_cur_gc_live_oops->clear();
_cur_gc_live_oops_moved_to->clear();
_cur_gc_live_oops_size->clear();
}
}
#endif
} }
...@@ -225,19 +187,6 @@ void GenMarkSweep::deallocate_stacks() { ...@@ -225,19 +187,6 @@ void GenMarkSweep::deallocate_stacks() {
_preserved_oop_stack.clear(true); _preserved_oop_stack.clear(true);
_marking_stack.clear(); _marking_stack.clear();
_objarray_stack.clear(true); _objarray_stack.clear(true);
#ifdef VALIDATE_MARK_SWEEP
if (ValidateMarkSweep) {
delete _root_refs_stack;
delete _other_refs_stack;
delete _adjusted_pointers;
delete _live_oops;
delete _live_oops_size;
delete _live_oops_moved_to;
_live_oops_index = 0;
_live_oops_index_at_perm = 0;
}
#endif
} }
void GenMarkSweep::mark_sweep_phase1(int level, void GenMarkSweep::mark_sweep_phase1(int level,
...@@ -246,8 +195,6 @@ void GenMarkSweep::mark_sweep_phase1(int level, ...@@ -246,8 +195,6 @@ void GenMarkSweep::mark_sweep_phase1(int level,
TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty); TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty);
trace(" 1"); trace(" 1");
VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking());
GenCollectedHeap* gch = GenCollectedHeap::heap(); GenCollectedHeap* gch = GenCollectedHeap::heap();
// Because follow_root_closure is created statically, cannot // Because follow_root_closure is created statically, cannot
...@@ -315,8 +262,6 @@ void GenMarkSweep::mark_sweep_phase2() { ...@@ -315,8 +262,6 @@ void GenMarkSweep::mark_sweep_phase2() {
TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty); TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty);
trace("2"); trace("2");
VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking());
gch->prepare_for_compaction(); gch->prepare_for_compaction();
} }
...@@ -337,8 +282,6 @@ void GenMarkSweep::mark_sweep_phase3(int level) { ...@@ -337,8 +282,6 @@ void GenMarkSweep::mark_sweep_phase3(int level) {
// Need new claim bits for the pointer adjustment tracing. // Need new claim bits for the pointer adjustment tracing.
ClassLoaderDataGraph::clear_claimed_marks(); ClassLoaderDataGraph::clear_claimed_marks();
VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking());
// Because the two closures below are created statically, cannot // Because the two closures below are created statically, cannot
// use OopsInGenClosure constructor which takes a generation, // use OopsInGenClosure constructor which takes a generation,
// as the Universe has not been created when the static constructors // as the Universe has not been created when the static constructors
...@@ -393,10 +336,6 @@ void GenMarkSweep::mark_sweep_phase4() { ...@@ -393,10 +336,6 @@ void GenMarkSweep::mark_sweep_phase4() {
TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty); TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty);
trace("4"); trace("4");
VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking());
GenCompactClosure blk; GenCompactClosure blk;
gch->generation_iterate(&blk, true); gch->generation_iterate(&blk, true);
VALIDATE_MARK_SWEEP_ONLY(compaction_complete());
} }
...@@ -411,7 +411,6 @@ HeapWord* CompactibleSpace::forward(oop q, size_t size, ...@@ -411,7 +411,6 @@ HeapWord* CompactibleSpace::forward(oop q, size_t size,
assert(q->forwardee() == NULL, "should be forwarded to NULL"); assert(q->forwardee() == NULL, "should be forwarded to NULL");
} }
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::register_live_oop(q, size));
compact_top += size; compact_top += size;
// we need to update the offset table so that the beginnings of objects can be // we need to update the offset table so that the beginnings of objects can be
...@@ -470,13 +469,10 @@ void Space::adjust_pointers() { ...@@ -470,13 +469,10 @@ void Space::adjust_pointers() {
if (oop(q)->is_gc_marked()) { if (oop(q)->is_gc_marked()) {
// q is alive // q is alive
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));
// point all the oops to the new location // point all the oops to the new location
size_t size = oop(q)->adjust_pointers(); size_t size = oop(q)->adjust_pointers();
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
debug_only(prev_q = q); debug_only(prev_q = q);
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));
q += size; q += size;
} else { } else {
......
...@@ -655,16 +655,10 @@ protected: ...@@ -655,16 +655,10 @@ protected:
assert(block_is_obj(q), \ assert(block_is_obj(q), \
"should be at block boundaries, and should be looking at objs"); \ "should be at block boundaries, and should be looking at objs"); \
\ \
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); \
\
/* point all the oops to the new location */ \ /* point all the oops to the new location */ \
size_t size = oop(q)->adjust_pointers(); \ size_t size = oop(q)->adjust_pointers(); \
size = adjust_obj_size(size); \ size = adjust_obj_size(size); \
\ \
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); \
\
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); \
\
q += size; \ q += size; \
} \ } \
\ \
...@@ -685,12 +679,9 @@ protected: ...@@ -685,12 +679,9 @@ protected:
Prefetch::write(q, interval); \ Prefetch::write(q, interval); \
if (oop(q)->is_gc_marked()) { \ if (oop(q)->is_gc_marked()) { \
/* q is alive */ \ /* q is alive */ \
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q))); \
/* point all the oops to the new location */ \ /* point all the oops to the new location */ \
size_t size = oop(q)->adjust_pointers(); \ size_t size = oop(q)->adjust_pointers(); \
size = adjust_obj_size(size); \ size = adjust_obj_size(size); \
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers()); \
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size)); \
debug_only(prev_q = q); \ debug_only(prev_q = q); \
q += size; \ q += size; \
} else { \ } else { \
...@@ -725,7 +716,6 @@ protected: ...@@ -725,7 +716,6 @@ protected:
size_t size = obj_size(q); \ size_t size = obj_size(q); \
assert(!oop(q)->is_gc_marked(), \ assert(!oop(q)->is_gc_marked(), \
"should be unmarked (special dense prefix handling)"); \ "should be unmarked (special dense prefix handling)"); \
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q)); \
debug_only(prev_q = q); \ debug_only(prev_q = q); \
q += size; \ q += size; \
} \ } \
...@@ -759,8 +749,6 @@ protected: ...@@ -759,8 +749,6 @@ protected:
Prefetch::write(compaction_top, copy_interval); \ Prefetch::write(compaction_top, copy_interval); \
\ \
/* copy object and reinit its mark */ \ /* copy object and reinit its mark */ \
VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, \
compaction_top)); \
assert(q != compaction_top, "everything in this pass should be moving"); \ assert(q != compaction_top, "everything in this pass should be moving"); \
Copy::aligned_conjoint_words(q, compaction_top, size); \ Copy::aligned_conjoint_words(q, compaction_top, size); \
oop(compaction_top)->init_mark(); \ oop(compaction_top)->init_mark(); \
......
...@@ -1101,13 +1101,6 @@ class CommandLineFlags { ...@@ -1101,13 +1101,6 @@ class CommandLineFlags {
product(bool, ReduceSignalUsage, false, \ product(bool, ReduceSignalUsage, false, \
"Reduce the use of OS signals in Java and/or the VM") \ "Reduce the use of OS signals in Java and/or the VM") \
\ \
notproduct(bool, ValidateMarkSweep, false, \
"Do extra validation during MarkSweep collection") \
\
notproduct(bool, RecordMarkSweepCompaction, false, \
"Enable GC-to-GC recording and querying of compaction during " \
"MarkSweep") \
\
develop_pd(bool, ShareVtableStubs, \ develop_pd(bool, ShareVtableStubs, \
"Share vtable stubs (smaller code but worse branch prediction") \ "Share vtable stubs (smaller code but worse branch prediction") \
\ \
......
...@@ -612,21 +612,6 @@ extern "C" void events() { ...@@ -612,21 +612,6 @@ extern "C" void events() {
Events::print(); Events::print();
} }
// Given a heap address that was valid before the most recent GC, if
// the oop that used to contain it is still live, prints the new
// location of the oop and the address. Useful for tracking down
// certain kinds of naked oop and oop map bugs.
extern "C" void pnl(intptr_t old_heap_addr) {
// Print New Location of old heap address
Command c("pnl");
#ifndef VALIDATE_MARK_SWEEP
tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled");
#else
MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr);
#endif
}
extern "C" Method* findm(intptr_t pc) { extern "C" Method* findm(intptr_t pc) {
Command c("findm"); Command c("findm");
nmethod* nm = CodeCache::find_nmethod((address)pc); nmethod* nm = CodeCache::find_nmethod((address)pc);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册