8015486: PSScavenge::is_obj_in_young is unnecessarily slow with UseCompressedOops
Compare compressed oops to a compressed young gen boundary instead of uncompressing the oops before doing the young gen boundary check. Reviewed-by: brutisso, jmasa
This commit is contained in:
parent
de314e391b
commit
c39235c377
@ -42,7 +42,7 @@ inline void PSPromotionManager::claim_or_forward_internal_depth(T* p) {
|
|||||||
if (o->is_forwarded()) {
|
if (o->is_forwarded()) {
|
||||||
o = o->forwardee();
|
o = o->forwardee();
|
||||||
// Card mark
|
// Card mark
|
||||||
if (PSScavenge::is_obj_in_young((HeapWord*) o)) {
|
if (PSScavenge::is_obj_in_young(o)) {
|
||||||
PSScavenge::card_table()->inline_write_ref_field_gc(p, o);
|
PSScavenge::card_table()->inline_write_ref_field_gc(p, o);
|
||||||
}
|
}
|
||||||
oopDesc::encode_store_heap_oop_not_null(p, o);
|
oopDesc::encode_store_heap_oop_not_null(p, o);
|
||||||
|
@ -61,6 +61,7 @@ CardTableExtension* PSScavenge::_card_table = NULL;
|
|||||||
bool PSScavenge::_survivor_overflow = false;
|
bool PSScavenge::_survivor_overflow = false;
|
||||||
uint PSScavenge::_tenuring_threshold = 0;
|
uint PSScavenge::_tenuring_threshold = 0;
|
||||||
HeapWord* PSScavenge::_young_generation_boundary = NULL;
|
HeapWord* PSScavenge::_young_generation_boundary = NULL;
|
||||||
|
uintptr_t PSScavenge::_young_generation_boundary_compressed = 0;
|
||||||
elapsedTimer PSScavenge::_accumulated_time;
|
elapsedTimer PSScavenge::_accumulated_time;
|
||||||
Stack<markOop, mtGC> PSScavenge::_preserved_mark_stack;
|
Stack<markOop, mtGC> PSScavenge::_preserved_mark_stack;
|
||||||
Stack<oop, mtGC> PSScavenge::_preserved_oop_stack;
|
Stack<oop, mtGC> PSScavenge::_preserved_oop_stack;
|
||||||
@ -71,7 +72,7 @@ bool PSScavenge::_promotion_failed = false;
|
|||||||
class PSIsAliveClosure: public BoolObjectClosure {
|
class PSIsAliveClosure: public BoolObjectClosure {
|
||||||
public:
|
public:
|
||||||
bool do_object_b(oop p) {
|
bool do_object_b(oop p) {
|
||||||
return (!PSScavenge::is_obj_in_young((HeapWord*) p)) || p->is_forwarded();
|
return (!PSScavenge::is_obj_in_young(p)) || p->is_forwarded();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -815,7 +816,7 @@ void PSScavenge::initialize() {
|
|||||||
// Set boundary between young_gen and old_gen
|
// Set boundary between young_gen and old_gen
|
||||||
assert(old_gen->reserved().end() <= young_gen->eden_space()->bottom(),
|
assert(old_gen->reserved().end() <= young_gen->eden_space()->bottom(),
|
||||||
"old above young");
|
"old above young");
|
||||||
_young_generation_boundary = young_gen->eden_space()->bottom();
|
set_young_generation_boundary(young_gen->eden_space()->bottom());
|
||||||
|
|
||||||
// Initialize ref handling object for scavenging.
|
// Initialize ref handling object for scavenging.
|
||||||
MemRegion mr = young_gen->reserved();
|
MemRegion mr = young_gen->reserved();
|
||||||
|
@ -62,19 +62,22 @@ class PSScavenge: AllStatic {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Flags/counters
|
// Flags/counters
|
||||||
static ReferenceProcessor* _ref_processor; // Reference processor for scavenging.
|
static ReferenceProcessor* _ref_processor; // Reference processor for scavenging.
|
||||||
static PSIsAliveClosure _is_alive_closure; // Closure used for reference processing
|
static PSIsAliveClosure _is_alive_closure; // Closure used for reference processing
|
||||||
static CardTableExtension* _card_table; // We cache the card table for fast access.
|
static CardTableExtension* _card_table; // We cache the card table for fast access.
|
||||||
static bool _survivor_overflow; // Overflow this collection
|
static bool _survivor_overflow; // Overflow this collection
|
||||||
static uint _tenuring_threshold; // tenuring threshold for next scavenge
|
static uint _tenuring_threshold; // tenuring threshold for next scavenge
|
||||||
static elapsedTimer _accumulated_time; // total time spent on scavenge
|
static elapsedTimer _accumulated_time; // total time spent on scavenge
|
||||||
static HeapWord* _young_generation_boundary; // The lowest address possible for the young_gen.
|
// The lowest address possible for the young_gen.
|
||||||
// This is used to decide if an oop should be scavenged,
|
// This is used to decide if an oop should be scavenged,
|
||||||
// cards should be marked, etc.
|
// cards should be marked, etc.
|
||||||
|
static HeapWord* _young_generation_boundary;
|
||||||
|
// Used to optimize compressed oops young gen boundary checking.
|
||||||
|
static uintptr_t _young_generation_boundary_compressed;
|
||||||
static Stack<markOop, mtGC> _preserved_mark_stack; // List of marks to be restored after failed promotion
|
static Stack<markOop, mtGC> _preserved_mark_stack; // List of marks to be restored after failed promotion
|
||||||
static Stack<oop, mtGC> _preserved_oop_stack; // List of oops that need their mark restored.
|
static Stack<oop, mtGC> _preserved_oop_stack; // List of oops that need their mark restored.
|
||||||
static CollectorCounters* _counters; // collector performance counters
|
static CollectorCounters* _counters; // collector performance counters
|
||||||
static bool _promotion_failed;
|
static bool _promotion_failed;
|
||||||
|
|
||||||
static void clean_up_failed_promotion();
|
static void clean_up_failed_promotion();
|
||||||
|
|
||||||
@ -112,6 +115,9 @@ class PSScavenge: AllStatic {
|
|||||||
// boundary moves, _young_generation_boundary must be reset
|
// boundary moves, _young_generation_boundary must be reset
|
||||||
static void set_young_generation_boundary(HeapWord* v) {
|
static void set_young_generation_boundary(HeapWord* v) {
|
||||||
_young_generation_boundary = v;
|
_young_generation_boundary = v;
|
||||||
|
if (UseCompressedOops) {
|
||||||
|
_young_generation_boundary_compressed = (uintptr_t)oopDesc::encode_heap_oop((oop)v);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called by parallelScavengeHeap to init the tenuring threshold
|
// Called by parallelScavengeHeap to init the tenuring threshold
|
||||||
@ -140,11 +146,19 @@ class PSScavenge: AllStatic {
|
|||||||
static void copy_and_push_safe_barrier_from_klass(PSPromotionManager* pm, oop* p);
|
static void copy_and_push_safe_barrier_from_klass(PSPromotionManager* pm, oop* p);
|
||||||
|
|
||||||
// Is an object in the young generation
|
// Is an object in the young generation
|
||||||
// This assumes that the HeapWord argument is in the heap,
|
// This assumes that the 'o' is in the heap,
|
||||||
// so it only checks one side of the complete predicate.
|
// so it only checks one side of the complete predicate.
|
||||||
|
|
||||||
|
inline static bool is_obj_in_young(oop o) {
|
||||||
|
return (HeapWord*)o >= _young_generation_boundary;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static bool is_obj_in_young(narrowOop o) {
|
||||||
|
return (uintptr_t)o >= _young_generation_boundary_compressed;
|
||||||
|
}
|
||||||
|
|
||||||
inline static bool is_obj_in_young(HeapWord* o) {
|
inline static bool is_obj_in_young(HeapWord* o) {
|
||||||
const bool result = (o >= _young_generation_boundary);
|
return o >= _young_generation_boundary;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -39,9 +39,7 @@ inline void PSScavenge::save_to_space_top_before_gc() {
|
|||||||
|
|
||||||
template <class T> inline bool PSScavenge::should_scavenge(T* p) {
|
template <class T> inline bool PSScavenge::should_scavenge(T* p) {
|
||||||
T heap_oop = oopDesc::load_heap_oop(p);
|
T heap_oop = oopDesc::load_heap_oop(p);
|
||||||
if (oopDesc::is_null(heap_oop)) return false;
|
return PSScavenge::is_obj_in_young(heap_oop);
|
||||||
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
|
|
||||||
return PSScavenge::is_obj_in_young((HeapWord*)obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@ -94,7 +92,7 @@ inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm,
|
|||||||
// or from metadata.
|
// or from metadata.
|
||||||
if ((!PSScavenge::is_obj_in_young((HeapWord*)p)) &&
|
if ((!PSScavenge::is_obj_in_young((HeapWord*)p)) &&
|
||||||
Universe::heap()->is_in_reserved(p)) {
|
Universe::heap()->is_in_reserved(p)) {
|
||||||
if (PSScavenge::is_obj_in_young((HeapWord*)new_obj)) {
|
if (PSScavenge::is_obj_in_young(new_obj)) {
|
||||||
card_table()->inline_write_ref_field_gc(p, new_obj);
|
card_table()->inline_write_ref_field_gc(p, new_obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,7 +145,7 @@ class PSScavengeFromKlassClosure: public OopClosure {
|
|||||||
}
|
}
|
||||||
oopDesc::encode_store_heap_oop_not_null(p, new_obj);
|
oopDesc::encode_store_heap_oop_not_null(p, new_obj);
|
||||||
|
|
||||||
if (PSScavenge::is_obj_in_young((HeapWord*)new_obj)) {
|
if (PSScavenge::is_obj_in_young(new_obj)) {
|
||||||
do_klass_barrier();
|
do_klass_barrier();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user