< prev index next >

src/share/vm/gc/parallel/parMarkBitMap.cpp

Print this page
rev 9846 : [mq]: par-scav-patch
rev 9847 : 8146987: Improve Parallel GC Full GC by caching results of live_words_in_range()
Summary: 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
Contributed-by: ray alex <sky1young@gmail.com>

*** 1,7 **** /* ! * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 22,31 **** --- 22,32 ---- * */ #include "precompiled.hpp" #include "gc/parallel/parMarkBitMap.hpp" + #include "gc/parallel/psCompactionManager.inline.hpp" #include "gc/parallel/psParallelCompact.hpp" #include "oops/oop.inline.hpp" #include "runtime/atomic.inline.hpp" #include "runtime/os.hpp" #include "services/memTracker.hpp"
*** 94,104 **** return true; } return false; } ! size_t ParMarkBitMap::live_words_in_range(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"); idx_t live_bits = 0; --- 95,118 ---- return true; } return false; } ! 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"); idx_t live_bits = 0;
*** 115,124 **** --- 129,172 ---- beg_bit = find_obj_beg(tmp_end + 1, range_end); } 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) { + 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 { DEBUG_ONLY(verify_bit(range_beg);)
< prev index next >