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:
Stefan Karlsson 2013-05-30 10:58:16 +02:00
parent de314e391b
commit c39235c377
4 changed files with 35 additions and 22 deletions

View File

@ -42,7 +42,7 @@ inline void PSPromotionManager::claim_or_forward_internal_depth(T* p) {
if (o->is_forwarded()) {
o = o->forwardee();
// 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);
}
oopDesc::encode_store_heap_oop_not_null(p, o);

View File

@ -61,6 +61,7 @@ CardTableExtension* PSScavenge::_card_table = NULL;
bool PSScavenge::_survivor_overflow = false;
uint PSScavenge::_tenuring_threshold = 0;
HeapWord* PSScavenge::_young_generation_boundary = NULL;
uintptr_t PSScavenge::_young_generation_boundary_compressed = 0;
elapsedTimer PSScavenge::_accumulated_time;
Stack<markOop, mtGC> PSScavenge::_preserved_mark_stack;
Stack<oop, mtGC> PSScavenge::_preserved_oop_stack;
@ -71,7 +72,7 @@ bool PSScavenge::_promotion_failed = false;
class PSIsAliveClosure: public BoolObjectClosure {
public:
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
assert(old_gen->reserved().end() <= young_gen->eden_space()->bottom(),
"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.
MemRegion mr = young_gen->reserved();

View File

@ -62,19 +62,22 @@ class PSScavenge: AllStatic {
protected:
// Flags/counters
static ReferenceProcessor* _ref_processor; // Reference processor for scavenging.
static PSIsAliveClosure _is_alive_closure; // Closure used for reference processing
static CardTableExtension* _card_table; // We cache the card table for fast access.
static bool _survivor_overflow; // Overflow this collection
static uint _tenuring_threshold; // tenuring threshold for next scavenge
static elapsedTimer _accumulated_time; // total time spent on scavenge
static HeapWord* _young_generation_boundary; // The lowest address possible for the young_gen.
// This is used to decide if an oop should be scavenged,
// cards should be marked, etc.
static ReferenceProcessor* _ref_processor; // Reference processor for scavenging.
static PSIsAliveClosure _is_alive_closure; // Closure used for reference processing
static CardTableExtension* _card_table; // We cache the card table for fast access.
static bool _survivor_overflow; // Overflow this collection
static uint _tenuring_threshold; // tenuring threshold for next scavenge
static elapsedTimer _accumulated_time; // total time spent on scavenge
// The lowest address possible for the young_gen.
// This is used to decide if an oop should be scavenged,
// 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<oop, mtGC> _preserved_oop_stack; // List of oops that need their mark restored.
static CollectorCounters* _counters; // collector performance counters
static bool _promotion_failed;
static CollectorCounters* _counters; // collector performance counters
static bool _promotion_failed;
static void clean_up_failed_promotion();
@ -112,6 +115,9 @@ class PSScavenge: AllStatic {
// boundary moves, _young_generation_boundary must be reset
static void set_young_generation_boundary(HeapWord* 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
@ -140,11 +146,19 @@ class PSScavenge: AllStatic {
static void copy_and_push_safe_barrier_from_klass(PSPromotionManager* pm, oop* p);
// 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.
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) {
const bool result = (o >= _young_generation_boundary);
return result;
return o >= _young_generation_boundary;
}
};

View File

@ -39,9 +39,7 @@ inline void PSScavenge::save_to_space_top_before_gc() {
template <class T> inline bool PSScavenge::should_scavenge(T* p) {
T heap_oop = oopDesc::load_heap_oop(p);
if (oopDesc::is_null(heap_oop)) return false;
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
return PSScavenge::is_obj_in_young((HeapWord*)obj);
return PSScavenge::is_obj_in_young(heap_oop);
}
template <class T>
@ -94,7 +92,7 @@ inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm,
// or from metadata.
if ((!PSScavenge::is_obj_in_young((HeapWord*)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);
}
}
@ -147,7 +145,7 @@ class PSScavengeFromKlassClosure: public OopClosure {
}
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();
}
}