mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 11:34:38 +02:00
8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
A large part of time in the parallel scavenge collector is spent finding out the amount of live words within memory ranges to find out where to move an object to. Try to incrementally calculate this value. Reviewed-by: tschatzl, mgerdin, jmasa
This commit is contained in:
parent
ce491c9057
commit
4f42f17d9e
17 changed files with 180 additions and 81 deletions
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/parallel/parMarkBitMap.hpp"
|
||||
#include "gc/parallel/psCompactionManager.inline.hpp"
|
||||
#include "gc/parallel/psParallelCompact.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/atomic.inline.hpp"
|
||||
|
@ -96,7 +97,20 @@ ParMarkBitMap::mark_obj(HeapWord* addr, size_t size)
|
|||
return false;
|
||||
}
|
||||
|
||||
size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
|
||||
inline bool
|
||||
ParMarkBitMap::is_live_words_in_range_in_cache(ParCompactionManager* cm, HeapWord* beg_addr) const {
|
||||
return cm->last_query_begin() == beg_addr;
|
||||
}
|
||||
|
||||
inline void
|
||||
ParMarkBitMap::update_live_words_in_range_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj, size_t result) const {
|
||||
cm->set_last_query_begin(beg_addr);
|
||||
cm->set_last_query_object(end_obj);
|
||||
cm->set_last_query_return(result);
|
||||
}
|
||||
|
||||
size_t
|
||||
ParMarkBitMap::live_words_in_range_helper(HeapWord* beg_addr, oop end_obj) const
|
||||
{
|
||||
assert(beg_addr <= (HeapWord*)end_obj, "bad range");
|
||||
assert(is_marked(end_obj), "end_obj must be live");
|
||||
|
@ -117,6 +131,42 @@ size_t ParMarkBitMap::live_words_in_range(HeapWord* beg_addr, oop end_obj) const
|
|||
return bits_to_words(live_bits);
|
||||
}
|
||||
|
||||
size_t
|
||||
ParMarkBitMap::live_words_in_range_use_cache(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const
|
||||
{
|
||||
HeapWord* last_beg = cm->last_query_begin();
|
||||
oop last_obj = cm->last_query_object();
|
||||
size_t last_ret = cm->last_query_return();
|
||||
if (end_obj > last_obj) {
|
||||
last_ret = last_ret + live_words_in_range_helper((HeapWord*)last_obj, end_obj);
|
||||
last_obj = end_obj;
|
||||
} else if (end_obj < last_obj) {
|
||||
// The cached value is for an object that is to the left (lower address) of the current
|
||||
// end_obj. Calculate back from that cached value.
|
||||
if (pointer_delta((HeapWord*)end_obj, (HeapWord*)beg_addr) > pointer_delta((HeapWord*)last_obj, (HeapWord*)end_obj)) {
|
||||
last_ret = last_ret - live_words_in_range_helper((HeapWord*)end_obj, last_obj);
|
||||
} else {
|
||||
last_ret = live_words_in_range_helper(beg_addr, end_obj);
|
||||
}
|
||||
last_obj = end_obj;
|
||||
}
|
||||
|
||||
update_live_words_in_range_cache(cm, last_beg, last_obj, last_ret);
|
||||
return last_ret;
|
||||
}
|
||||
|
||||
size_t
|
||||
ParMarkBitMap::live_words_in_range(ParCompactionManager* cm, HeapWord* beg_addr, oop end_obj) const
|
||||
{
|
||||
// Try to reuse result from ParCompactionManager cache first.
|
||||
if (is_live_words_in_range_in_cache(cm, beg_addr)) {
|
||||
return live_words_in_range_use_cache(cm, beg_addr, end_obj);
|
||||
}
|
||||
size_t ret = live_words_in_range_helper(beg_addr, end_obj);
|
||||
update_live_words_in_range_cache(cm, beg_addr, end_obj, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ParMarkBitMap::IterationStatus
|
||||
ParMarkBitMap::iterate(ParMarkBitMapClosure* live_closure,
|
||||
idx_t range_beg, idx_t range_end) const
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue