8225409: G1: Remove the Hot Card Cache
Reviewed-by: tschatzl, iwalulya
This commit is contained in:
parent
92474f13f0
commit
7c50ab1612
src/hotspot/share
gc/g1
g1CardCounts.cppg1CardCounts.hppg1CollectedHeap.cppg1CollectedHeap.hppg1CollectionSet.cppg1FullGCPrepareTask.cppg1GCPhaseTimes.cppg1GCPhaseTimes.hppg1HotCardCache.cppg1HotCardCache.hppg1Policy.cppg1RemSet.cppg1RemSet.hppg1YoungCollector.cppg1YoungCollector.hppg1YoungGCPostEvacuateTasks.cppg1YoungGCPostEvacuateTasks.hppg1_globals.hppheapRegionManager.cppheapRegionManager.hpp
runtime
test
hotspot/jtreg/gc/g1
TestGCLogMessages.javaTestLargePageUseForAuxMemory.javaTestNoUseHCC.javaTestShrinkAuxiliaryData.javaTestShrinkAuxiliaryData05.javaTestShrinkAuxiliaryData10.javaTestShrinkAuxiliaryData15.javaTestShrinkAuxiliaryData20.javaTestShrinkAuxiliaryData25.javaTestShrinkAuxiliaryData27.javaTestShrinkAuxiliaryDataRunner.java
jdk/jdk/jfr/event/gc/collection
@ -1,157 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2018, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/g1/g1CardCounts.hpp"
|
||||
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
||||
#include "gc/shared/cardTableBarrierSet.hpp"
|
||||
#include "services/memTracker.hpp"
|
||||
#include "utilities/copy.hpp"
|
||||
|
||||
void G1CardCountsMappingChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
|
||||
if (zero_filled) {
|
||||
return;
|
||||
}
|
||||
MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_idx), num_regions * HeapRegion::GrainWords);
|
||||
_counts->clear_range(mr);
|
||||
}
|
||||
|
||||
size_t G1CardCounts::compute_size(size_t mem_region_size_in_words) {
|
||||
// We keep card counts for every card, so the size of the card counts table must
|
||||
// be the same as the card table.
|
||||
return G1CardTable::compute_size(mem_region_size_in_words);
|
||||
}
|
||||
|
||||
size_t G1CardCounts::heap_map_factor() {
|
||||
// See G1CardCounts::compute_size() why we reuse the card table value.
|
||||
return G1CardTable::heap_map_factor();
|
||||
}
|
||||
|
||||
void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
|
||||
if (has_count_table()) {
|
||||
assert(from_card_num < to_card_num,
|
||||
"Wrong order? from: " SIZE_FORMAT ", to: " SIZE_FORMAT,
|
||||
from_card_num, to_card_num);
|
||||
Copy::fill_to_bytes(&_card_counts[from_card_num], (to_card_num - from_card_num));
|
||||
}
|
||||
}
|
||||
|
||||
G1CardCounts::G1CardCounts(G1CollectedHeap *g1h):
|
||||
_listener(), _g1h(g1h), _ct(NULL), _card_counts(NULL), _reserved_max_card_num(0), _ct_bot(NULL) {
|
||||
_listener.set_cardcounts(this);
|
||||
}
|
||||
|
||||
void G1CardCounts::initialize(G1RegionToSpaceMapper* mapper) {
|
||||
assert(_g1h->reserved().byte_size() > 0, "initialization order");
|
||||
assert(_g1h->capacity() == 0, "initialization order");
|
||||
|
||||
if (G1ConcRSHotCardLimit > 0) {
|
||||
// The max value we can store in the counts table is
|
||||
// max_jubyte. Guarantee the value of the hot
|
||||
// threshold limit is no more than this.
|
||||
guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity");
|
||||
|
||||
_ct = _g1h->card_table();
|
||||
_ct_bot = _ct->byte_for_const(_g1h->reserved().start());
|
||||
|
||||
_card_counts = (jubyte*) mapper->reserved().start();
|
||||
_reserved_max_card_num = mapper->reserved().byte_size();
|
||||
mapper->set_mapping_changed_listener(&_listener);
|
||||
}
|
||||
}
|
||||
|
||||
uint G1CardCounts::add_card_count(CardValue* card_ptr) {
|
||||
// Returns the number of times the card has been refined.
|
||||
// If we failed to reserve/commit the counts table, return 0.
|
||||
// If card_ptr is beyond the committed end of the counts table,
|
||||
// return 0.
|
||||
// Otherwise return the actual count.
|
||||
// Unless G1ConcRSHotCardLimit has been set appropriately,
|
||||
// returning 0 will result in the card being considered
|
||||
// cold and will be refined immediately.
|
||||
uint count = 0;
|
||||
if (has_count_table()) {
|
||||
size_t card_num = ptr_2_card_num(card_ptr);
|
||||
assert(card_num < _reserved_max_card_num,
|
||||
"Card " SIZE_FORMAT " outside of card counts table (max size " SIZE_FORMAT ")",
|
||||
card_num, _reserved_max_card_num);
|
||||
count = (uint) _card_counts[card_num];
|
||||
if (count < G1ConcRSHotCardLimit) {
|
||||
_card_counts[card_num] =
|
||||
(jubyte)(MIN2((uintx)(_card_counts[card_num] + 1), G1ConcRSHotCardLimit));
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool G1CardCounts::is_hot(uint count) {
|
||||
return (count >= G1ConcRSHotCardLimit);
|
||||
}
|
||||
|
||||
void G1CardCounts::clear_region(HeapRegion* hr) {
|
||||
MemRegion mr(hr->bottom(), hr->end());
|
||||
clear_range(mr);
|
||||
}
|
||||
|
||||
void G1CardCounts::clear_range(MemRegion mr) {
|
||||
if (has_count_table()) {
|
||||
const CardValue* from_card_ptr = _ct->byte_for_const(mr.start());
|
||||
// We use the last address in the range as the range could represent the
|
||||
// last region in the heap. In which case trying to find the card will be an
|
||||
// OOB access to the card table.
|
||||
const CardValue* last_card_ptr = _ct->byte_for_const(mr.last());
|
||||
|
||||
#ifdef ASSERT
|
||||
HeapWord* start_addr = _ct->addr_for(from_card_ptr);
|
||||
assert(start_addr == mr.start(), "MemRegion start must be aligned to a card.");
|
||||
HeapWord* last_addr = _ct->addr_for(last_card_ptr);
|
||||
assert((last_addr + G1CardTable::card_size_in_words()) == mr.end(), "MemRegion end must be aligned to a card.");
|
||||
#endif // ASSERT
|
||||
|
||||
// Clear the counts for the (exclusive) card range.
|
||||
size_t from_card_num = ptr_2_card_num(from_card_ptr);
|
||||
size_t to_card_num = ptr_2_card_num(last_card_ptr) + 1;
|
||||
clear_range(from_card_num, to_card_num);
|
||||
}
|
||||
}
|
||||
|
||||
class G1CardCountsClearClosure : public HeapRegionClosure {
|
||||
private:
|
||||
G1CardCounts* _card_counts;
|
||||
public:
|
||||
G1CardCountsClearClosure(G1CardCounts* card_counts) :
|
||||
HeapRegionClosure(), _card_counts(card_counts) { }
|
||||
|
||||
|
||||
virtual bool do_heap_region(HeapRegion* r) {
|
||||
_card_counts->clear_region(r);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void G1CardCounts::clear_all() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "don't call this otherwise");
|
||||
G1CardCountsClearClosure cl(this);
|
||||
_g1h->heap_region_iterate(&cl);
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_GC_G1_G1CARDCOUNTS_HPP
|
||||
#define SHARE_GC_G1_G1CARDCOUNTS_HPP
|
||||
|
||||
#include "gc/g1/g1CardTable.hpp"
|
||||
#include "gc/g1/g1RegionToSpaceMapper.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/virtualspace.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
class CardTableBarrierSet;
|
||||
class G1CardCounts;
|
||||
class G1CollectedHeap;
|
||||
class G1RegionToSpaceMapper;
|
||||
class HeapRegion;
|
||||
|
||||
class G1CardCountsMappingChangedListener : public G1MappingChangedListener {
|
||||
private:
|
||||
G1CardCounts* _counts;
|
||||
public:
|
||||
void set_cardcounts(G1CardCounts* counts) { _counts = counts; }
|
||||
|
||||
virtual void on_commit(uint start_idx, size_t num_regions, bool zero_filled);
|
||||
};
|
||||
|
||||
// Table to track the number of times a card has been refined. Once
|
||||
// a card has been refined a certain number of times, it is
|
||||
// considered 'hot' and its refinement is delayed by inserting the
|
||||
// card into the hot card cache. The card will then be refined when
|
||||
// it is evicted from the hot card cache, or when the hot card cache
|
||||
// is 'drained' during the next evacuation pause.
|
||||
|
||||
class G1CardCounts: public CHeapObj<mtGC> {
|
||||
public:
|
||||
typedef CardTable::CardValue CardValue;
|
||||
|
||||
private:
|
||||
G1CardCountsMappingChangedListener _listener;
|
||||
|
||||
G1CollectedHeap* _g1h;
|
||||
G1CardTable* _ct;
|
||||
|
||||
// The table of counts
|
||||
uint8_t* _card_counts;
|
||||
|
||||
// Max capacity of the reserved space for the counts table
|
||||
size_t _reserved_max_card_num;
|
||||
|
||||
// CardTable bottom.
|
||||
const CardValue* _ct_bot;
|
||||
|
||||
// Returns true if the card counts table has been reserved.
|
||||
bool has_reserved_count_table() { return _card_counts != NULL; }
|
||||
|
||||
// Returns true if the card counts table has been reserved and committed.
|
||||
bool has_count_table() {
|
||||
return has_reserved_count_table();
|
||||
}
|
||||
|
||||
size_t ptr_2_card_num(const CardValue* card_ptr) {
|
||||
assert(card_ptr >= _ct_bot,
|
||||
"Invalid card pointer: "
|
||||
"card_ptr: " PTR_FORMAT ", "
|
||||
"_ct_bot: " PTR_FORMAT,
|
||||
p2i(card_ptr), p2i(_ct_bot));
|
||||
size_t card_num = pointer_delta(card_ptr, _ct_bot, sizeof(CardValue));
|
||||
assert(card_num < _reserved_max_card_num,
|
||||
"card pointer out of range: " PTR_FORMAT, p2i(card_ptr));
|
||||
return card_num;
|
||||
}
|
||||
|
||||
CardValue* card_num_2_ptr(size_t card_num) {
|
||||
assert(card_num < _reserved_max_card_num,
|
||||
"card num out of range: " SIZE_FORMAT, card_num);
|
||||
return (CardValue*) (_ct_bot + card_num);
|
||||
}
|
||||
|
||||
// Clear the counts table for the given (exclusive) index range.
|
||||
void clear_range(size_t from_card_num, size_t to_card_num);
|
||||
|
||||
public:
|
||||
G1CardCounts(G1CollectedHeap* g1h);
|
||||
|
||||
// Return the number of slots needed for a card counts table
|
||||
// that covers mem_region_words words.
|
||||
static size_t compute_size(size_t mem_region_size_in_words);
|
||||
|
||||
// Returns how many bytes of the heap a single byte of the card counts table
|
||||
// corresponds to.
|
||||
static size_t heap_map_factor();
|
||||
|
||||
void initialize(G1RegionToSpaceMapper* mapper);
|
||||
|
||||
// Increments the refinement count for the given card.
|
||||
// Returns the pre-increment count value.
|
||||
uint add_card_count(CardValue* card_ptr);
|
||||
|
||||
// Returns true if the given count is high enough to be considered
|
||||
// 'hot'; false otherwise.
|
||||
bool is_hot(uint count);
|
||||
|
||||
// Clears the card counts for the cards spanned by the region
|
||||
void clear_region(HeapRegion* hr);
|
||||
|
||||
// Clears the card counts for the cards spanned by the MemRegion
|
||||
void clear_range(MemRegion mr);
|
||||
|
||||
// Clear the entire card counts table during GC.
|
||||
void clear_all();
|
||||
};
|
||||
|
||||
#endif // SHARE_GC_G1_G1CARDCOUNTS_HPP
|
@ -50,7 +50,6 @@
|
||||
#include "gc/g1/g1HeapSizingPolicy.hpp"
|
||||
#include "gc/g1/g1HeapTransition.hpp"
|
||||
#include "gc/g1/g1HeapVerifier.hpp"
|
||||
#include "gc/g1/g1HotCardCache.hpp"
|
||||
#include "gc/g1/g1InitLogger.hpp"
|
||||
#include "gc/g1/g1MemoryPool.hpp"
|
||||
#include "gc/g1/g1MonotonicArenaFreeMemoryTask.hpp"
|
||||
@ -1033,10 +1032,6 @@ void G1CollectedHeap::prepare_for_mutator_after_full_collection() {
|
||||
}
|
||||
|
||||
void G1CollectedHeap::abort_refinement() {
|
||||
if (G1HotCardCache::use_cache()) {
|
||||
_hot_card_cache->reset_hot_cache();
|
||||
}
|
||||
|
||||
// Discard all remembered set updates and reset refinement statistics.
|
||||
G1BarrierSet::dirty_card_queue_set().abandon_logs_and_stats();
|
||||
assert(G1BarrierSet::dirty_card_queue_set().num_cards() == 0,
|
||||
@ -1438,7 +1433,6 @@ G1CollectedHeap::G1CollectedHeap() :
|
||||
_policy(new G1Policy(_gc_timer_stw)),
|
||||
_heap_sizing_policy(NULL),
|
||||
_collection_set(this, _policy),
|
||||
_hot_card_cache(NULL),
|
||||
_rem_set(NULL),
|
||||
_card_set_config(),
|
||||
_card_set_freelist_pool(G1CardSetConfiguration::num_mem_object_types()),
|
||||
@ -1576,9 +1570,6 @@ jint G1CollectedHeap::initialize() {
|
||||
satbqs.set_buffer_enqueue_threshold_percentage(G1SATBBufferEnqueueingThresholdPercent);
|
||||
}
|
||||
|
||||
// Create the hot card cache.
|
||||
_hot_card_cache = new G1HotCardCache(this);
|
||||
|
||||
// Create space mappers.
|
||||
size_t page_size = heap_rs.page_size();
|
||||
G1RegionToSpaceMapper* heap_storage =
|
||||
@ -1601,7 +1592,7 @@ jint G1CollectedHeap::initialize() {
|
||||
heap_rs.size());
|
||||
heap_storage->set_mapping_changed_listener(&_listener);
|
||||
|
||||
// Create storage for the BOT, card table, card counts table (hot card cache) and the bitmap.
|
||||
// Create storage for the BOT, card table and the bitmap.
|
||||
G1RegionToSpaceMapper* bot_storage =
|
||||
create_aux_memory_mapper("Block Offset Table",
|
||||
G1BlockOffsetTable::compute_size(heap_rs.size() / HeapWordSize),
|
||||
@ -1612,21 +1603,13 @@ jint G1CollectedHeap::initialize() {
|
||||
G1CardTable::compute_size(heap_rs.size() / HeapWordSize),
|
||||
G1CardTable::heap_map_factor());
|
||||
|
||||
G1RegionToSpaceMapper* card_counts_storage =
|
||||
create_aux_memory_mapper("Card Counts Table",
|
||||
G1CardCounts::compute_size(heap_rs.size() / HeapWordSize),
|
||||
G1CardCounts::heap_map_factor());
|
||||
|
||||
size_t bitmap_size = G1CMBitMap::compute_size(heap_rs.size());
|
||||
G1RegionToSpaceMapper* bitmap_storage =
|
||||
create_aux_memory_mapper("Mark Bitmap", bitmap_size, G1CMBitMap::heap_map_factor());
|
||||
|
||||
_hrm.initialize(heap_storage, bitmap_storage, bot_storage, cardtable_storage, card_counts_storage);
|
||||
_hrm.initialize(heap_storage, bitmap_storage, bot_storage, cardtable_storage);
|
||||
_card_table->initialize(cardtable_storage);
|
||||
|
||||
// Do later initialization work for concurrent refinement.
|
||||
_hot_card_cache->initialize(card_counts_storage);
|
||||
|
||||
// 6843694 - ensure that the maximum region index can fit
|
||||
// in the remembered set structures.
|
||||
const uint max_region_idx = (1U << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1;
|
||||
@ -1637,7 +1620,7 @@ jint G1CollectedHeap::initialize() {
|
||||
guarantee((uintptr_t)(heap_rs.base()) >= G1CardTable::card_size(), "Java heap must not start within the first card.");
|
||||
G1FromCardCache::initialize(max_reserved_regions());
|
||||
// Also create a G1 rem set.
|
||||
_rem_set = new G1RemSet(this, _card_table, _hot_card_cache);
|
||||
_rem_set = new G1RemSet(this, _card_table);
|
||||
_rem_set->initialize(max_reserved_regions());
|
||||
|
||||
size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1;
|
||||
@ -1817,10 +1800,6 @@ size_t G1CollectedHeap::unused_committed_regions_in_bytes() const {
|
||||
return _hrm.total_free_bytes();
|
||||
}
|
||||
|
||||
void G1CollectedHeap::iterate_hcc_closure(G1CardTableEntryClosure* cl, uint worker_id) {
|
||||
_hot_card_cache->drain(cl, worker_id);
|
||||
}
|
||||
|
||||
// Computes the sum of the storage used by the various regions.
|
||||
size_t G1CollectedHeap::used() const {
|
||||
size_t result = _summary_bytes_used + _allocator->used_in_alloc_regions();
|
||||
@ -2846,13 +2825,6 @@ void G1CollectedHeap::free_region(HeapRegion* hr, FreeRegionList* free_list) {
|
||||
assert(!hr->is_empty(), "the region should not be empty");
|
||||
assert(_hrm.is_available(hr->hrm_index()), "region should be committed");
|
||||
|
||||
// Clear the card counts for this region.
|
||||
// Note: we only need to do this if the region is not young
|
||||
// (since we don't refine cards in young regions).
|
||||
if (!hr->is_young()) {
|
||||
_hot_card_cache->reset_card_counts(hr);
|
||||
}
|
||||
|
||||
// Reset region metadata to allow reuse.
|
||||
hr->hr_clear(true /* clear_space */);
|
||||
_policy->remset_tracker()->update_at_free(hr);
|
||||
@ -3281,10 +3253,6 @@ void G1CollectedHeap::update_used_after_gc(bool evacuation_failed) {
|
||||
}
|
||||
}
|
||||
|
||||
void G1CollectedHeap::reset_hot_card_cache() {
|
||||
_hot_card_cache->reset_hot_cache();
|
||||
}
|
||||
|
||||
class RebuildCodeRootClosure: public CodeBlobClosure {
|
||||
G1CollectedHeap* _g1h;
|
||||
|
||||
|
@ -76,7 +76,6 @@ class G1ConcurrentRefine;
|
||||
class G1GCCounters;
|
||||
class G1GCPhaseTimes;
|
||||
class G1HeapSizingPolicy;
|
||||
class G1HotCardCache;
|
||||
class G1NewTracer;
|
||||
class G1RemSet;
|
||||
class G1ServiceTask;
|
||||
@ -799,9 +798,6 @@ public:
|
||||
void record_obj_copy_mem_stats();
|
||||
|
||||
private:
|
||||
// The hot card cache for remembered set insertion optimization.
|
||||
G1HotCardCache* _hot_card_cache;
|
||||
|
||||
// The g1 remembered set of the heap.
|
||||
G1RemSet* _rem_set;
|
||||
// Global card set configuration
|
||||
@ -955,9 +951,6 @@ public:
|
||||
static void start_codecache_marking_cycle_if_inactive(bool concurrent_mark_start);
|
||||
static void finish_codecache_marking_cycle();
|
||||
|
||||
// Apply the given closure on all cards in the Hot Card Cache, emptying it.
|
||||
void iterate_hcc_closure(G1CardTableEntryClosure* cl, uint worker_id);
|
||||
|
||||
// The shared block offset table array.
|
||||
G1BlockOffsetTable* bot() const { return _bot; }
|
||||
|
||||
@ -1085,8 +1078,6 @@ public:
|
||||
return reserved().contains(addr);
|
||||
}
|
||||
|
||||
G1HotCardCache* hot_card_cache() const { return _hot_card_cache; }
|
||||
|
||||
G1CardTable* card_table() const {
|
||||
return _card_table;
|
||||
}
|
||||
@ -1288,10 +1279,6 @@ public:
|
||||
// Recalculate amount of used memory after GC. Must be called after all allocation
|
||||
// has finished.
|
||||
void update_used_after_gc(bool evacuation_failed);
|
||||
// Reset and re-enable the hot card cache.
|
||||
// Note the counts for the cards in the regions in the
|
||||
// collection set are reset when the collection set is freed.
|
||||
void reset_hot_card_cache();
|
||||
|
||||
// Rebuild the code root lists for each region
|
||||
// after a full GC.
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "gc/g1/g1CollectionSet.hpp"
|
||||
#include "gc/g1/g1CollectionSetCandidates.hpp"
|
||||
#include "gc/g1/g1CollectorState.hpp"
|
||||
#include "gc/g1/g1HotCardCache.hpp"
|
||||
#include "gc/g1/g1ParScanThreadState.hpp"
|
||||
#include "gc/g1/g1Policy.hpp"
|
||||
#include "gc/g1/heapRegion.inline.hpp"
|
||||
@ -293,8 +292,7 @@ double G1CollectionSet::finalize_young_part(double target_pause_time_ms, G1Survi
|
||||
guarantee(target_pause_time_ms > 0.0,
|
||||
"target_pause_time_ms = %1.6lf should be positive", target_pause_time_ms);
|
||||
|
||||
size_t pending_cards = _policy->pending_cards_at_gc_start() +
|
||||
_g1h->hot_card_cache()->num_entries();
|
||||
size_t pending_cards = _policy->pending_cards_at_gc_start();
|
||||
|
||||
log_trace(gc, ergo, cset)("Start choosing CSet. Pending cards: " SIZE_FORMAT " target pause time: %1.2fms",
|
||||
pending_cards, target_pause_time_ms);
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "gc/g1/g1FullGCMarker.hpp"
|
||||
#include "gc/g1/g1FullGCOopClosures.inline.hpp"
|
||||
#include "gc/g1/g1FullGCPrepareTask.inline.hpp"
|
||||
#include "gc/g1/g1HotCardCache.hpp"
|
||||
#include "gc/g1/heapRegion.inline.hpp"
|
||||
#include "gc/shared/gcTraceTime.inline.hpp"
|
||||
#include "gc/shared/referenceProcessor.hpp"
|
||||
@ -119,11 +118,6 @@ G1FullGCPrepareTask::G1ResetMetadataClosure::G1ResetMetadataClosure(G1FullCollec
|
||||
void G1FullGCPrepareTask::G1ResetMetadataClosure::reset_region_metadata(HeapRegion* hr) {
|
||||
hr->rem_set()->clear();
|
||||
hr->clear_cardtable();
|
||||
|
||||
G1HotCardCache* hcc = _g1h->hot_card_cache();
|
||||
if (G1HotCardCache::use_cache()) {
|
||||
hcc->reset_card_counts(hr);
|
||||
}
|
||||
}
|
||||
|
||||
bool G1FullGCPrepareTask::G1ResetMetadataClosure::do_heap_region(HeapRegion* hr) {
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
||||
#include "gc/g1/g1GCParPhaseTimesTracker.hpp"
|
||||
#include "gc/g1/g1GCPhaseTimes.hpp"
|
||||
#include "gc/g1/g1HotCardCache.hpp"
|
||||
#include "gc/g1/g1ParScanThreadState.inline.hpp"
|
||||
#include "gc/shared/gcTimer.hpp"
|
||||
#include "gc/shared/oopStorage.hpp"
|
||||
@ -83,13 +82,6 @@ G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) :
|
||||
}
|
||||
|
||||
_gc_par_phases[MergeLB] = new WorkerDataArray<double>("MergeLB", "Log Buffers (ms):", max_gc_threads);
|
||||
if (G1HotCardCache::use_cache()) {
|
||||
_gc_par_phases[MergeHCC] = new WorkerDataArray<double>("MergeHCC", "Hot Card Cache (ms):", max_gc_threads);
|
||||
_gc_par_phases[MergeHCC]->create_thread_work_items("Dirty Cards:", MergeHCCDirtyCards);
|
||||
_gc_par_phases[MergeHCC]->create_thread_work_items("Skipped Cards:", MergeHCCSkippedCards);
|
||||
} else {
|
||||
_gc_par_phases[MergeHCC] = NULL;
|
||||
}
|
||||
_gc_par_phases[ScanHR] = new WorkerDataArray<double>("ScanHR", "Scan Heap Roots (ms):", max_gc_threads);
|
||||
_gc_par_phases[OptScanHR] = new WorkerDataArray<double>("OptScanHR", "Optional Scan Heap Roots (ms):", max_gc_threads);
|
||||
_gc_par_phases[CodeRoots] = new WorkerDataArray<double>("CodeRoots", "Code Root Scan (ms):", max_gc_threads);
|
||||
@ -106,7 +98,6 @@ G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) :
|
||||
_gc_par_phases[RemoveSelfForwards] = new WorkerDataArray<double>("RemoveSelfForwards", "Remove Self Forwards (ms):", max_gc_threads);
|
||||
_gc_par_phases[ClearCardTable] = new WorkerDataArray<double>("ClearLoggedCards", "Clear Logged Cards (ms):", max_gc_threads);
|
||||
_gc_par_phases[RecalculateUsed] = new WorkerDataArray<double>("RecalculateUsed", "Recalculate Used Memory (ms):", max_gc_threads);
|
||||
_gc_par_phases[ResetHotCardCache] = new WorkerDataArray<double>("ResetHotCardCache", "Reset Hot Card Cache (ms):", max_gc_threads);
|
||||
#if COMPILER2_OR_JVMCI
|
||||
_gc_par_phases[UpdateDerivedPointers] = new WorkerDataArray<double>("UpdateDerivedPointers", "Update Derived Pointers (ms):", max_gc_threads);
|
||||
#endif
|
||||
@ -248,7 +239,6 @@ void G1GCPhaseTimes::record_gc_pause_end() {
|
||||
ASSERT_PHASE_UNINITIALIZED(MergeER);
|
||||
ASSERT_PHASE_UNINITIALIZED(MergeRS);
|
||||
ASSERT_PHASE_UNINITIALIZED(OptMergeRS);
|
||||
ASSERT_PHASE_UNINITIALIZED(MergeHCC);
|
||||
ASSERT_PHASE_UNINITIALIZED(MergeLB);
|
||||
ASSERT_PHASE_UNINITIALIZED(ScanHR);
|
||||
ASSERT_PHASE_UNINITIALIZED(CodeRoots);
|
||||
@ -460,9 +450,6 @@ double G1GCPhaseTimes::print_evacuate_initial_collection_set() const {
|
||||
debug_time("Prepare Merge Heap Roots", _cur_prepare_merge_heap_roots_time_ms);
|
||||
debug_phase_merge_remset();
|
||||
|
||||
if (G1HotCardCache::use_cache()) {
|
||||
debug_phase(_gc_par_phases[MergeHCC]);
|
||||
}
|
||||
debug_phase(_gc_par_phases[MergeLB]);
|
||||
|
||||
info_time("Evacuate Collection Set", _cur_collection_initial_evac_time_ms);
|
||||
@ -518,7 +505,6 @@ double G1GCPhaseTimes::print_post_evacuate_collection_set(bool evacuation_failed
|
||||
debug_phase(_gc_par_phases[RestorePreservedMarks], 1);
|
||||
debug_phase(_gc_par_phases[ClearRetainedRegionBitmaps], 1);
|
||||
}
|
||||
debug_phase(_gc_par_phases[ResetHotCardCache], 1);
|
||||
#if COMPILER2_OR_JVMCI
|
||||
debug_phase(_gc_par_phases[UpdateDerivedPointers], 1);
|
||||
#endif
|
||||
|
@ -58,7 +58,6 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
|
||||
MergeRS,
|
||||
OptMergeRS,
|
||||
MergeLB,
|
||||
MergeHCC,
|
||||
ScanHR,
|
||||
OptScanHR,
|
||||
CodeRoots,
|
||||
@ -82,7 +81,6 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
|
||||
RemoveSelfForwards,
|
||||
ClearCardTable,
|
||||
RecalculateUsed,
|
||||
ResetHotCardCache,
|
||||
#if COMPILER2_OR_JVMCI
|
||||
UpdateDerivedPointers,
|
||||
#endif
|
||||
@ -129,11 +127,6 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
|
||||
ScanHRUsedMemory
|
||||
};
|
||||
|
||||
enum GCMergeHCCWorkItems {
|
||||
MergeHCCDirtyCards,
|
||||
MergeHCCSkippedCards
|
||||
};
|
||||
|
||||
enum GCMergeLBWorkItems {
|
||||
MergeLBDirtyCards,
|
||||
MergeLBSkippedCards
|
||||
|
@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/g1/g1CardTableEntryClosure.hpp"
|
||||
#include "gc/g1/g1CollectedHeap.inline.hpp"
|
||||
#include "gc/g1/g1DirtyCardQueue.hpp"
|
||||
#include "gc/g1/g1HotCardCache.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
|
||||
G1HotCardCache::G1HotCardCache(G1CollectedHeap *g1h):
|
||||
_g1h(g1h), _card_counts(g1h),
|
||||
_hot_cache(NULL), _hot_cache_size(0), _hot_cache_par_chunk_size(0),
|
||||
_hot_cache_idx(0), _hot_cache_par_claimed_idx(0), _cache_wrapped_around(false)
|
||||
{}
|
||||
|
||||
void G1HotCardCache::initialize(G1RegionToSpaceMapper* card_counts_storage) {
|
||||
if (use_cache()) {
|
||||
_hot_cache_size = (size_t)1 << G1ConcRSLogCacheSize;
|
||||
_hot_cache = ArrayAllocator<CardValue*>::allocate(_hot_cache_size, mtGC);
|
||||
|
||||
reset_hot_cache_internal();
|
||||
|
||||
// For refining the cards in the hot cache in parallel
|
||||
_hot_cache_par_chunk_size = ClaimChunkSize;
|
||||
_hot_cache_par_claimed_idx = 0;
|
||||
|
||||
_cache_wrapped_around = false;
|
||||
|
||||
_card_counts.initialize(card_counts_storage);
|
||||
}
|
||||
}
|
||||
|
||||
G1HotCardCache::~G1HotCardCache() {
|
||||
if (use_cache()) {
|
||||
assert(_hot_cache != NULL, "Logic");
|
||||
ArrayAllocator<CardValue*>::free(_hot_cache, _hot_cache_size);
|
||||
_hot_cache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
CardTable::CardValue* G1HotCardCache::insert(CardValue* card_ptr) {
|
||||
uint count = _card_counts.add_card_count(card_ptr);
|
||||
if (!_card_counts.is_hot(count)) {
|
||||
// The card is not hot so do not store it in the cache;
|
||||
// return it for immediate refining.
|
||||
return card_ptr;
|
||||
}
|
||||
// Otherwise, the card is hot.
|
||||
size_t index = Atomic::fetch_and_add(&_hot_cache_idx, 1u);
|
||||
if (index == _hot_cache_size) {
|
||||
// Can use relaxed store because all racing threads are writing the same
|
||||
// value and there aren't any concurrent readers.
|
||||
Atomic::store(&_cache_wrapped_around, true);
|
||||
}
|
||||
size_t masked_index = index & (_hot_cache_size - 1);
|
||||
CardValue* current_ptr = _hot_cache[masked_index];
|
||||
|
||||
// Try to store the new card pointer into the cache. Compare-and-swap to guard
|
||||
// against the unlikely event of a race resulting in another card pointer to
|
||||
// have already been written to the cache. In this case we will return
|
||||
// card_ptr in favor of the other option, which would be starting over. This
|
||||
// should be OK since card_ptr will likely be the older card already when/if
|
||||
// this ever happens.
|
||||
CardValue* previous_ptr = Atomic::cmpxchg(&_hot_cache[masked_index],
|
||||
current_ptr,
|
||||
card_ptr);
|
||||
return (previous_ptr == current_ptr) ? previous_ptr : card_ptr;
|
||||
}
|
||||
|
||||
void G1HotCardCache::drain(G1CardTableEntryClosure* cl, uint worker_id) {
|
||||
assert(use_cache(), "Drain only necessary if we use the hot card cache.");
|
||||
|
||||
assert(_hot_cache != NULL, "Logic");
|
||||
|
||||
while (_hot_cache_par_claimed_idx < _hot_cache_size) {
|
||||
size_t end_idx = Atomic::add(&_hot_cache_par_claimed_idx,
|
||||
_hot_cache_par_chunk_size);
|
||||
size_t start_idx = end_idx - _hot_cache_par_chunk_size;
|
||||
// The current worker has successfully claimed the chunk [start_idx..end_idx)
|
||||
end_idx = MIN2(end_idx, _hot_cache_size);
|
||||
for (size_t i = start_idx; i < end_idx; i++) {
|
||||
CardValue* card_ptr = _hot_cache[i];
|
||||
if (card_ptr != NULL) {
|
||||
cl->do_card_ptr(card_ptr, worker_id);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The existing entries in the hot card cache, which were just refined
|
||||
// above, are discarded prior to re-enabling the cache near the end of the GC.
|
||||
}
|
||||
|
||||
void G1HotCardCache::reset_card_counts(HeapRegion* hr) {
|
||||
_card_counts.clear_region(hr);
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 2019, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_GC_G1_G1HOTCARDCACHE_HPP
|
||||
#define SHARE_GC_G1_G1HOTCARDCACHE_HPP
|
||||
|
||||
#include "gc/g1/g1CardCounts.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "runtime/javaThread.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
class G1CardTableEntryClosure;
|
||||
class G1CollectedHeap;
|
||||
class HeapRegion;
|
||||
|
||||
// An evicting cache of cards that have been logged by the G1 post
|
||||
// write barrier. Placing a card in the cache delays the refinement
|
||||
// of the card until the card is evicted, or the cache is drained
|
||||
// during the next evacuation pause.
|
||||
//
|
||||
// The first thing the G1 post write barrier does is to check whether
|
||||
// the card containing the updated pointer is already dirty and, if
|
||||
// so, skips the remaining code in the barrier.
|
||||
//
|
||||
// Delaying the refinement of a card will make the card fail the
|
||||
// first is_dirty check in the write barrier, skipping the remainder
|
||||
// of the write barrier.
|
||||
//
|
||||
// This can significantly reduce the overhead of the write barrier
|
||||
// code, increasing throughput.
|
||||
|
||||
class G1HotCardCache: public CHeapObj<mtGC> {
|
||||
public:
|
||||
typedef CardTable::CardValue CardValue;
|
||||
|
||||
private:
|
||||
G1CollectedHeap* _g1h;
|
||||
|
||||
G1CardCounts _card_counts;
|
||||
|
||||
|
||||
// The card cache table
|
||||
CardValue** _hot_cache;
|
||||
|
||||
size_t _hot_cache_size;
|
||||
|
||||
size_t _hot_cache_par_chunk_size;
|
||||
|
||||
// Avoids false sharing when concurrently updating _hot_cache_idx or
|
||||
// _hot_cache_par_claimed_idx. These are never updated at the same time
|
||||
// thus it's not necessary to separate them as well
|
||||
char _pad_before[DEFAULT_CACHE_LINE_SIZE];
|
||||
|
||||
volatile size_t _hot_cache_idx;
|
||||
|
||||
volatile size_t _hot_cache_par_claimed_idx;
|
||||
|
||||
char _pad_after[DEFAULT_CACHE_LINE_SIZE];
|
||||
|
||||
// Records whether insertion overflowed the hot card cache at least once. This
|
||||
// avoids the need for a separate atomic counter of how many valid entries are
|
||||
// in the HCC.
|
||||
volatile bool _cache_wrapped_around;
|
||||
|
||||
// The number of cached cards a thread claims when flushing the cache
|
||||
static const int ClaimChunkSize = 32;
|
||||
|
||||
public:
|
||||
static bool use_cache() {
|
||||
return (G1ConcRSLogCacheSize > 0);
|
||||
}
|
||||
|
||||
G1HotCardCache(G1CollectedHeap* g1h);
|
||||
~G1HotCardCache();
|
||||
|
||||
void initialize(G1RegionToSpaceMapper* card_counts_storage);
|
||||
|
||||
// Returns the card to be refined or NULL.
|
||||
//
|
||||
// Increments the count for given the card. if the card is not 'hot',
|
||||
// it is returned for immediate refining. Otherwise the card is
|
||||
// added to the hot card cache.
|
||||
// If there is enough room in the hot card cache for the card we're
|
||||
// adding, NULL is returned and no further action in needed.
|
||||
// If we evict a card from the cache to make room for the new card,
|
||||
// the evicted card is then returned for refinement.
|
||||
CardValue* insert(CardValue* card_ptr);
|
||||
|
||||
// Refine the cards that have delayed as a result of
|
||||
// being in the cache.
|
||||
void drain(G1CardTableEntryClosure* cl, uint worker_id);
|
||||
|
||||
// Set up for parallel processing of the cards in the hot cache
|
||||
void reset_hot_cache_claimed_index() {
|
||||
_hot_cache_par_claimed_idx = 0;
|
||||
}
|
||||
|
||||
// Resets the hot card cache and discards the entries.
|
||||
void reset_hot_cache() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "Should be at a safepoint");
|
||||
if (use_cache()) {
|
||||
reset_hot_cache_internal();
|
||||
}
|
||||
}
|
||||
|
||||
// Zeros the values in the card counts table for the given region
|
||||
void reset_card_counts(HeapRegion* hr);
|
||||
|
||||
// Number of entries in the HCC.
|
||||
size_t num_entries() const {
|
||||
return _cache_wrapped_around ? _hot_cache_size : _hot_cache_idx + 1;
|
||||
}
|
||||
private:
|
||||
void reset_hot_cache_internal() {
|
||||
assert(_hot_cache != NULL, "Logic");
|
||||
_hot_cache_idx = 0;
|
||||
for (size_t i = 0; i < _hot_cache_size; i++) {
|
||||
_hot_cache[i] = NULL;
|
||||
}
|
||||
_cache_wrapped_around = false;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SHARE_GC_G1_G1HOTCARDCACHE_HPP
|
@ -34,7 +34,6 @@
|
||||
#include "gc/g1/g1ConcurrentRefine.hpp"
|
||||
#include "gc/g1/g1ConcurrentRefineStats.hpp"
|
||||
#include "gc/g1/g1CollectionSetChooser.hpp"
|
||||
#include "gc/g1/g1HotCardCache.hpp"
|
||||
#include "gc/g1/g1IHOPControl.hpp"
|
||||
#include "gc/g1/g1GCPhaseTimes.hpp"
|
||||
#include "gc/g1/g1Policy.hpp"
|
||||
@ -800,11 +799,9 @@ void G1Policy::record_young_collection_end(bool concurrent_operation_is_full_mar
|
||||
|
||||
_eden_surv_rate_group->start_adding_regions();
|
||||
|
||||
double merge_hcc_time_ms = average_time_ms(G1GCPhaseTimes::MergeHCC);
|
||||
if (update_stats) {
|
||||
// Update prediction for card merge.
|
||||
size_t const merged_cards_from_log_buffers = p->sum_thread_work_items(G1GCPhaseTimes::MergeHCC, G1GCPhaseTimes::MergeHCCDirtyCards) +
|
||||
p->sum_thread_work_items(G1GCPhaseTimes::MergeLB, G1GCPhaseTimes::MergeLBDirtyCards);
|
||||
size_t const merged_cards_from_log_buffers = p->sum_thread_work_items(G1GCPhaseTimes::MergeLB, G1GCPhaseTimes::MergeLBDirtyCards);
|
||||
// MergeRSCards includes the cards from the Eager Reclaim phase.
|
||||
size_t const merged_cards_from_rs = p->sum_thread_work_items(G1GCPhaseTimes::MergeRS, G1GCPhaseTimes::MergeRSCards) +
|
||||
p->sum_thread_work_items(G1GCPhaseTimes::OptMergeRS, G1GCPhaseTimes::MergeRSCards);
|
||||
@ -814,7 +811,6 @@ void G1Policy::record_young_collection_end(bool concurrent_operation_is_full_mar
|
||||
if (total_cards_merged >= G1NumCardsCostSampleThreshold) {
|
||||
double avg_time_merge_cards = average_time_ms(G1GCPhaseTimes::MergeER) +
|
||||
average_time_ms(G1GCPhaseTimes::MergeRS) +
|
||||
average_time_ms(G1GCPhaseTimes::MergeHCC) +
|
||||
average_time_ms(G1GCPhaseTimes::MergeLB) +
|
||||
average_time_ms(G1GCPhaseTimes::OptMergeRS);
|
||||
_analytics->report_cost_per_card_merge_ms(avg_time_merge_cards / total_cards_merged, is_young_only_pause);
|
||||
@ -897,36 +893,21 @@ void G1Policy::record_young_collection_end(bool concurrent_operation_is_full_mar
|
||||
// Note that _mmu_tracker->max_gc_time() returns the time in seconds.
|
||||
double logged_cards_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
|
||||
|
||||
if (logged_cards_time_goal_ms < merge_hcc_time_ms) {
|
||||
log_debug(gc, ergo, refine)("Adjust concurrent refinement thresholds (scanning the HCC expected to take longer than Update RS time goal)."
|
||||
"Logged Cards Scan time goal: %1.2fms Scan HCC time: %1.2fms",
|
||||
logged_cards_time_goal_ms, merge_hcc_time_ms);
|
||||
|
||||
logged_cards_time_goal_ms = 0;
|
||||
} else {
|
||||
logged_cards_time_goal_ms -= merge_hcc_time_ms;
|
||||
}
|
||||
|
||||
double const logged_cards_time_ms = logged_cards_processing_time();
|
||||
size_t logged_cards =
|
||||
phase_times()->sum_thread_work_items(G1GCPhaseTimes::MergeLB,
|
||||
G1GCPhaseTimes::MergeLBDirtyCards);
|
||||
size_t hcc_cards =
|
||||
phase_times()->sum_thread_work_items(G1GCPhaseTimes::MergeHCC,
|
||||
G1GCPhaseTimes::MergeHCCDirtyCards);
|
||||
bool exceeded_goal = logged_cards_time_goal_ms < logged_cards_time_ms;
|
||||
size_t predicted_thread_buffer_cards = _analytics->predict_dirtied_cards_in_thread_buffers();
|
||||
G1ConcurrentRefine* cr = _g1h->concurrent_refine();
|
||||
|
||||
log_debug(gc, ergo, refine)
|
||||
("GC refinement: goal: %zu + %zu / %1.2fms, actual: %zu / %1.2fms, HCC: %zu / %1.2fms%s",
|
||||
("GC refinement: goal: %zu + %zu / %1.2fms, actual: %zu / %1.2fms, %s",
|
||||
cr->pending_cards_target(),
|
||||
predicted_thread_buffer_cards,
|
||||
logged_cards_time_goal_ms,
|
||||
logged_cards,
|
||||
logged_cards_time_ms,
|
||||
hcc_cards,
|
||||
merge_hcc_time_ms,
|
||||
(exceeded_goal ? " (exceeded goal)" : ""));
|
||||
|
||||
cr->adjust_after_gc(logged_cards_time_ms,
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "gc/g1/g1FromCardCache.hpp"
|
||||
#include "gc/g1/g1GCParPhaseTimesTracker.hpp"
|
||||
#include "gc/g1/g1GCPhaseTimes.hpp"
|
||||
#include "gc/g1/g1HotCardCache.hpp"
|
||||
#include "gc/g1/g1OopClosures.inline.hpp"
|
||||
#include "gc/g1/g1Policy.hpp"
|
||||
#include "gc/g1/g1RootClosures.hpp"
|
||||
@ -64,7 +63,7 @@
|
||||
// Collects information about the overall heap root scan progress during an evacuation.
|
||||
//
|
||||
// Scanning the remembered sets works by first merging all sources of cards to be
|
||||
// scanned (log buffers, hcc, remembered sets) into a single data structure to remove
|
||||
// scanned (log buffers, remembered sets) into a single data structure to remove
|
||||
// duplicates and simplify work distribution.
|
||||
//
|
||||
// During the following card scanning we not only scan this combined set of cards, but
|
||||
@ -467,14 +466,12 @@ public:
|
||||
};
|
||||
|
||||
G1RemSet::G1RemSet(G1CollectedHeap* g1h,
|
||||
G1CardTable* ct,
|
||||
G1HotCardCache* hot_card_cache) :
|
||||
G1CardTable* ct) :
|
||||
_scan_state(new G1RemSetScanState()),
|
||||
_prev_period_summary(false),
|
||||
_g1h(g1h),
|
||||
_ct(ct),
|
||||
_g1p(_g1h->policy()),
|
||||
_hot_card_cache(hot_card_cache) {
|
||||
_g1p(_g1h->policy()) {
|
||||
}
|
||||
|
||||
G1RemSet::~G1RemSet() {
|
||||
@ -1370,17 +1367,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Apply closure to log entries in the HCC.
|
||||
if (_initial_evacuation && G1HotCardCache::use_cache()) {
|
||||
assert(merge_remset_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase");
|
||||
G1GCParPhaseTimesTracker x(p, G1GCPhaseTimes::MergeHCC, worker_id);
|
||||
G1MergeLogBufferCardsClosure cl(g1h, _scan_state);
|
||||
g1h->iterate_hcc_closure(&cl, worker_id);
|
||||
|
||||
p->record_thread_work_item(G1GCPhaseTimes::MergeHCC, worker_id, cl.cards_dirty(), G1GCPhaseTimes::MergeHCCDirtyCards);
|
||||
p->record_thread_work_item(G1GCPhaseTimes::MergeHCC, worker_id, cl.cards_skipped(), G1GCPhaseTimes::MergeHCCSkippedCards);
|
||||
}
|
||||
|
||||
// Now apply the closure to all remaining log entries.
|
||||
if (_initial_evacuation) {
|
||||
assert(merge_remset_phase == G1GCPhaseTimes::MergeRS, "Wrong merge phase");
|
||||
@ -1528,37 +1514,6 @@ bool G1RemSet::clean_card_before_refine(CardValue** const card_ptr_addr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The result from the hot card cache insert call is either:
|
||||
// * pointer to the current card
|
||||
// (implying that the current card is not 'hot'),
|
||||
// * null
|
||||
// (meaning we had inserted the card ptr into the "hot" card cache,
|
||||
// which had some headroom),
|
||||
// * a pointer to a "hot" card that was evicted from the "hot" cache.
|
||||
//
|
||||
|
||||
if (G1HotCardCache::use_cache()) {
|
||||
const CardValue* orig_card_ptr = card_ptr;
|
||||
card_ptr = _hot_card_cache->insert(card_ptr);
|
||||
if (card_ptr == NULL) {
|
||||
// There was no eviction. Nothing to do.
|
||||
return false;
|
||||
} else if (card_ptr != orig_card_ptr) {
|
||||
// Original card was inserted and an old card was evicted.
|
||||
start = _ct->addr_for(card_ptr);
|
||||
r = _g1h->heap_region_containing_or_null(start);
|
||||
|
||||
// Check whether the region formerly in the cache should be
|
||||
// ignored, as discussed earlier for the original card. The
|
||||
// region could have been freed (or even uncommitted) while
|
||||
// in the cache.
|
||||
if (r == nullptr || !r->is_old_or_humongous_or_archive()) {
|
||||
return false;
|
||||
}
|
||||
*card_ptr_addr = card_ptr;
|
||||
} // Else we still have the original card.
|
||||
}
|
||||
|
||||
// Trim the region designated by the card to what's been allocated
|
||||
// in the region. The card could be stale, or the card could cover
|
||||
// (part of) an object at the end of the allocated space and extend
|
||||
|
@ -43,7 +43,6 @@ class CodeBlobClosure;
|
||||
class G1AbstractSubTask;
|
||||
class G1CollectedHeap;
|
||||
class G1CMBitMap;
|
||||
class G1HotCardCache;
|
||||
class G1RemSetScanState;
|
||||
class G1ParScanThreadState;
|
||||
class G1ParScanThreadStateSet;
|
||||
@ -69,7 +68,6 @@ private:
|
||||
|
||||
G1CardTable* _ct;
|
||||
G1Policy* _g1p;
|
||||
G1HotCardCache* _hot_card_cache;
|
||||
|
||||
void print_merge_heap_roots_stats();
|
||||
|
||||
@ -81,9 +79,7 @@ public:
|
||||
// Initialize data that depends on the heap size being known.
|
||||
void initialize(uint max_reserved_regions);
|
||||
|
||||
G1RemSet(G1CollectedHeap* g1h,
|
||||
G1CardTable* ct,
|
||||
G1HotCardCache* hot_card_cache);
|
||||
G1RemSet(G1CollectedHeap* g1h, G1CardTable* ct);
|
||||
~G1RemSet();
|
||||
|
||||
// Scan all cards in the non-collection set regions that potentially contain
|
||||
@ -94,7 +90,7 @@ public:
|
||||
G1GCPhaseTimes::GCParPhases objcopy_phase,
|
||||
bool remember_already_scanned_cards);
|
||||
|
||||
// Merge cards from various sources (remembered sets, hot card cache, log buffers)
|
||||
// Merge cards from various sources (remembered sets, log buffers)
|
||||
// and calculate the cards that need to be scanned later (via scan_heap_roots()).
|
||||
// If initial_evacuation is set, this is called during the initial evacuation.
|
||||
void merge_heap_roots(bool initial_evacuation);
|
||||
@ -126,8 +122,7 @@ public:
|
||||
// Two methods for concurrent refinement support, executed concurrently to
|
||||
// the mutator:
|
||||
// Cleans the card at "*card_ptr_addr" before refinement, returns true iff the
|
||||
// card needs later refinement. Note that "*card_ptr_addr" could be updated to
|
||||
// a different card due to use of hot card cache.
|
||||
// card needs later refinement.
|
||||
bool clean_card_before_refine(CardValue** const card_ptr_addr);
|
||||
// Refine the region corresponding to "card_ptr". Must be called after
|
||||
// being filtered by clean_card_before_refine(), and after proper
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "gc/g1/g1YoungGCEvacFailureInjector.hpp"
|
||||
#include "gc/g1/g1EvacInfo.hpp"
|
||||
#include "gc/g1/g1HRPrinter.hpp"
|
||||
#include "gc/g1/g1HotCardCache.hpp"
|
||||
#include "gc/g1/g1MonitoringSupport.hpp"
|
||||
#include "gc/g1/g1ParScanThreadState.inline.hpp"
|
||||
#include "gc/g1/g1Policy.hpp"
|
||||
@ -202,10 +201,6 @@ G1GCPhaseTimes* G1YoungCollector::phase_times() const {
|
||||
return _g1h->phase_times();
|
||||
}
|
||||
|
||||
G1HotCardCache* G1YoungCollector::hot_card_cache() const {
|
||||
return _g1h->hot_card_cache();
|
||||
}
|
||||
|
||||
G1HRPrinter* G1YoungCollector::hr_printer() const {
|
||||
return _g1h->hr_printer();
|
||||
}
|
||||
@ -520,8 +515,6 @@ void G1YoungCollector::pre_evacuate_collection_set(G1EvacInfo* evacuation_info)
|
||||
|
||||
_g1h->gc_prologue(false);
|
||||
|
||||
hot_card_cache()->reset_hot_cache_claimed_index();
|
||||
|
||||
// Initialize the GC alloc regions.
|
||||
allocator()->init_gc_alloc_regions(evacuation_info);
|
||||
|
||||
|
@ -40,7 +40,6 @@ class G1ConcurrentMark;
|
||||
class G1EvacFailureRegions;
|
||||
class G1EvacInfo;
|
||||
class G1GCPhaseTimes;
|
||||
class G1HotCardCache;
|
||||
class G1HRPrinter;
|
||||
class G1MonitoringSupport;
|
||||
class G1MonotonicArenaMemoryStats;
|
||||
@ -69,7 +68,7 @@ class G1YoungCollector {
|
||||
G1ConcurrentMark* concurrent_mark() const;
|
||||
STWGCTimer* gc_timer_stw() const;
|
||||
G1NewTracer* gc_tracer_stw() const;
|
||||
G1HotCardCache* hot_card_cache() const;
|
||||
|
||||
G1HRPrinter* hr_printer() const;
|
||||
G1MonitoringSupport* monitoring_support() const;
|
||||
G1GCPhaseTimes* phase_times() const;
|
||||
|
@ -239,14 +239,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class G1PostEvacuateCollectionSetCleanupTask2::ResetHotCardCacheTask : public G1AbstractSubTask {
|
||||
public:
|
||||
ResetHotCardCacheTask() : G1AbstractSubTask(G1GCPhaseTimes::ResetHotCardCache) { }
|
||||
|
||||
double worker_cost() const override { return 0.5; }
|
||||
void do_work(uint worker_id) override { G1CollectedHeap::heap()->reset_hot_card_cache(); }
|
||||
};
|
||||
|
||||
#if COMPILER2_OR_JVMCI
|
||||
class G1PostEvacuateCollectionSetCleanupTask2::UpdateDerivedPointersTask : public G1AbstractSubTask {
|
||||
public:
|
||||
@ -733,7 +725,6 @@ G1PostEvacuateCollectionSetCleanupTask2::G1PostEvacuateCollectionSetCleanupTask2
|
||||
G1EvacFailureRegions* evac_failure_regions) :
|
||||
G1BatchedTask("Post Evacuate Cleanup 2", G1CollectedHeap::heap()->phase_times())
|
||||
{
|
||||
add_serial_task(new ResetHotCardCacheTask());
|
||||
#if COMPILER2_OR_JVMCI
|
||||
add_serial_task(new UpdateDerivedPointersTask());
|
||||
#endif
|
||||
|
@ -54,7 +54,6 @@ public:
|
||||
|
||||
// Second set of post evacuate collection set tasks containing (s means serial):
|
||||
// - Eagerly Reclaim Humongous Objects (s)
|
||||
// - Reset Hot Card Cache (s)
|
||||
// - Update Derived Pointers (s)
|
||||
// - Clear Retained Region Bitmaps (on evacuation failure)
|
||||
// - Redirty Logged Cards
|
||||
@ -63,7 +62,6 @@ public:
|
||||
// - Resize TLABs
|
||||
class G1PostEvacuateCollectionSetCleanupTask2 : public G1BatchedTask {
|
||||
class EagerlyReclaimHumongousObjectsTask;
|
||||
class ResetHotCardCacheTask;
|
||||
#if COMPILER2_OR_JVMCI
|
||||
class UpdateDerivedPointersTask;
|
||||
#endif
|
||||
|
@ -178,14 +178,6 @@
|
||||
"Control whether concurrent refinement is performed. " \
|
||||
"Disabling effectively ignores G1RSetUpdatingPauseTimePercent") \
|
||||
\
|
||||
product(size_t, G1ConcRSLogCacheSize, 10, \
|
||||
"Log base 2 of the length of conc RS hot-card cache.") \
|
||||
range(0, 27) \
|
||||
\
|
||||
product(uintx, G1ConcRSHotCardLimit, 4, \
|
||||
"The threshold that defines (>=) a hot card.") \
|
||||
range(0, max_jubyte) \
|
||||
\
|
||||
develop(uint, G1RemSetArrayOfCardsEntriesBase, 8, \
|
||||
"Maximum number of entries per region in the Array of Cards " \
|
||||
"card set container per MB of a heap region.") \
|
||||
|
@ -64,7 +64,6 @@ public:
|
||||
HeapRegionManager::HeapRegionManager() :
|
||||
_bot_mapper(NULL),
|
||||
_cardtable_mapper(NULL),
|
||||
_card_counts_mapper(NULL),
|
||||
_committed_map(),
|
||||
_allocated_heapregions_length(0),
|
||||
_regions(), _heap_mapper(NULL),
|
||||
@ -75,8 +74,7 @@ HeapRegionManager::HeapRegionManager() :
|
||||
void HeapRegionManager::initialize(G1RegionToSpaceMapper* heap_storage,
|
||||
G1RegionToSpaceMapper* bitmap,
|
||||
G1RegionToSpaceMapper* bot,
|
||||
G1RegionToSpaceMapper* cardtable,
|
||||
G1RegionToSpaceMapper* card_counts) {
|
||||
G1RegionToSpaceMapper* cardtable) {
|
||||
_allocated_heapregions_length = 0;
|
||||
|
||||
_heap_mapper = heap_storage;
|
||||
@ -86,8 +84,6 @@ void HeapRegionManager::initialize(G1RegionToSpaceMapper* heap_storage,
|
||||
_bot_mapper = bot;
|
||||
_cardtable_mapper = cardtable;
|
||||
|
||||
_card_counts_mapper = card_counts;
|
||||
|
||||
_regions.initialize(heap_storage->reserved(), HeapRegion::GrainBytes);
|
||||
|
||||
_committed_map.initialize(reserved_length());
|
||||
@ -191,8 +187,6 @@ void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkerThr
|
||||
|
||||
_bot_mapper->commit_regions(index, num_regions, pretouch_workers);
|
||||
_cardtable_mapper->commit_regions(index, num_regions, pretouch_workers);
|
||||
|
||||
_card_counts_mapper->commit_regions(index, num_regions, pretouch_workers);
|
||||
}
|
||||
|
||||
void HeapRegionManager::uncommit_regions(uint start, uint num_regions) {
|
||||
@ -218,8 +212,6 @@ void HeapRegionManager::uncommit_regions(uint start, uint num_regions) {
|
||||
_bot_mapper->uncommit_regions(start, num_regions);
|
||||
_cardtable_mapper->uncommit_regions(start, num_regions);
|
||||
|
||||
_card_counts_mapper->uncommit_regions(start, num_regions);
|
||||
|
||||
_committed_map.uncommit(start, end);
|
||||
}
|
||||
|
||||
@ -271,22 +263,18 @@ void HeapRegionManager::clear_auxiliary_data_structures(uint start, uint num_reg
|
||||
_bot_mapper->signal_mapping_changed(start, num_regions);
|
||||
// Signal G1CardTable to clear the given regions.
|
||||
_cardtable_mapper->signal_mapping_changed(start, num_regions);
|
||||
// Signal G1CardCounts to clear the given regions.
|
||||
_card_counts_mapper->signal_mapping_changed(start, num_regions);
|
||||
}
|
||||
|
||||
MemoryUsage HeapRegionManager::get_auxiliary_data_memory_usage() const {
|
||||
size_t used_sz =
|
||||
_bitmap_mapper->committed_size() +
|
||||
_bot_mapper->committed_size() +
|
||||
_cardtable_mapper->committed_size() +
|
||||
_card_counts_mapper->committed_size();
|
||||
_cardtable_mapper->committed_size();
|
||||
|
||||
size_t committed_sz =
|
||||
_bitmap_mapper->reserved_size() +
|
||||
_bot_mapper->reserved_size() +
|
||||
_cardtable_mapper->reserved_size() +
|
||||
_card_counts_mapper->reserved_size();
|
||||
_cardtable_mapper->reserved_size();
|
||||
|
||||
return MemoryUsage(0, used_sz, committed_sz, committed_sz);
|
||||
}
|
||||
|
@ -76,7 +76,6 @@ class HeapRegionManager: public CHeapObj<mtGC> {
|
||||
|
||||
G1RegionToSpaceMapper* _bot_mapper;
|
||||
G1RegionToSpaceMapper* _cardtable_mapper;
|
||||
G1RegionToSpaceMapper* _card_counts_mapper;
|
||||
|
||||
// Keeps track of the currently committed regions in the heap. The committed regions
|
||||
// can either be active (ready for use) or inactive (ready for uncommit).
|
||||
@ -163,8 +162,7 @@ public:
|
||||
void initialize(G1RegionToSpaceMapper* heap_storage,
|
||||
G1RegionToSpaceMapper* bitmap,
|
||||
G1RegionToSpaceMapper* bot,
|
||||
G1RegionToSpaceMapper* cardtable,
|
||||
G1RegionToSpaceMapper* card_counts);
|
||||
G1RegionToSpaceMapper* cardtable);
|
||||
|
||||
// Return the "dummy" region used for G1AllocRegion. This is currently a hardwired
|
||||
// new HeapRegion that owns HeapRegion at index 0. Since at the moment we commit
|
||||
|
@ -555,6 +555,9 @@ static SpecialFlag const special_jvm_flags[] = {
|
||||
{ "G1UseAdaptiveConcRefinement", JDK_Version::undefined(), JDK_Version::jdk(20), JDK_Version::undefined() },
|
||||
{ "G1ConcRefinementServiceIntervalMillis", JDK_Version::undefined(), JDK_Version::jdk(20), JDK_Version::undefined() },
|
||||
|
||||
{ "G1ConcRSLogCacheSize", JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() },
|
||||
{ "G1ConcRSHotCardLimit", JDK_Version::undefined(), JDK_Version::jdk(21), JDK_Version::undefined() },
|
||||
|
||||
#ifdef ASSERT
|
||||
{ "DummyObsoleteTestFlag", JDK_Version::undefined(), JDK_Version::jdk(18), JDK_Version::undefined() },
|
||||
#endif
|
||||
|
@ -126,7 +126,6 @@ public class TestGCLogMessages {
|
||||
new LogMessageWithLevel("Merged Howl ArrayOfCards", Level.DEBUG),
|
||||
new LogMessageWithLevel("Merged Howl BitMap", Level.DEBUG),
|
||||
new LogMessageWithLevel("Merged Howl Full", Level.DEBUG),
|
||||
new LogMessageWithLevel("Hot Card Cache", Level.DEBUG),
|
||||
new LogMessageWithLevel("Log Buffers", Level.DEBUG),
|
||||
new LogMessageWithLevel("Dirty Cards", Level.DEBUG),
|
||||
new LogMessageWithLevel("Merged Cards", Level.DEBUG),
|
||||
@ -179,7 +178,6 @@ public class TestGCLogMessages {
|
||||
|
||||
// Post Evacuate Cleanup 2
|
||||
new LogMessageWithLevel("Post Evacuate Cleanup 2", Level.DEBUG),
|
||||
new LogMessageWithLevel("Reset Hot Card Cache", Level.DEBUG),
|
||||
new LogMessageWithLevelC2OrJVMCIOnly("Update Derived Pointers", Level.DEBUG),
|
||||
new LogMessageWithLevel("Redirty Logged Cards", Level.DEBUG),
|
||||
new LogMessageWithLevel("Redirtied Cards", Level.DEBUG),
|
||||
|
@ -102,7 +102,6 @@ public class TestLargePageUseForAuxMemory {
|
||||
|
||||
static void checkSmallTables(OutputAnalyzer output, long expectedPageSize) throws Exception {
|
||||
checkSize(output, expectedPageSize, "Block Offset Table: .*page_size=([^ ]+)");
|
||||
checkSize(output, expectedPageSize, "Card Counts Table: .*page_size=([^ ]+)");
|
||||
}
|
||||
|
||||
static void checkBitmap(OutputAnalyzer output, long expectedPageSize) throws Exception {
|
||||
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, 2022, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package gc.g1;
|
||||
|
||||
/*
|
||||
* @test TestNoUseHCC
|
||||
* @summary Check that G1 survives a GC without HCC enabled
|
||||
* @requires vm.gc.G1
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @library /test/lib
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/othervm -Xbootclasspath/a:. -Xlog:gc+phases=debug -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:+UseG1GC -Xmx64M -XX:G1ConcRSLogCacheSize=0 gc.g1.TestNoUseHCC
|
||||
*/
|
||||
|
||||
import jdk.test.whitebox.WhiteBox;
|
||||
|
||||
public class TestNoUseHCC {
|
||||
|
||||
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||
|
||||
public static void main(String [] args) {
|
||||
WB.youngGC();
|
||||
}
|
||||
}
|
||||
|
@ -39,7 +39,6 @@ import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import jdk.internal.misc.Unsafe; // for ADDRESS_SIZE
|
||||
import jdk.test.whitebox.WhiteBox;
|
||||
|
||||
public class TestShrinkAuxiliaryData {
|
||||
@ -61,26 +60,14 @@ public class TestShrinkAuxiliaryData {
|
||||
"-Xbootclasspath/a:.",
|
||||
};
|
||||
|
||||
private final int hotCardTableSize;
|
||||
|
||||
protected TestShrinkAuxiliaryData(int hotCardTableSize) {
|
||||
this.hotCardTableSize = hotCardTableSize;
|
||||
protected TestShrinkAuxiliaryData() {
|
||||
}
|
||||
|
||||
protected void test() throws Exception {
|
||||
ArrayList<String> vmOpts = new ArrayList<>();
|
||||
Collections.addAll(vmOpts, initialOpts);
|
||||
|
||||
int maxCacheSize = Math.max(0, Math.min(31, getMaxCacheSize()));
|
||||
if (maxCacheSize < hotCardTableSize) {
|
||||
throw new SkippedException(String.format(
|
||||
"Skiping test for %d cache size due max cache size %d",
|
||||
hotCardTableSize, maxCacheSize));
|
||||
}
|
||||
|
||||
printTestInfo(maxCacheSize);
|
||||
|
||||
vmOpts.add("-XX:G1ConcRSLogCacheSize=" + hotCardTableSize);
|
||||
printTestInfo();
|
||||
|
||||
// for 32 bits ObjectAlignmentInBytes is not a option
|
||||
if (Platform.is32bit()) {
|
||||
@ -109,47 +96,19 @@ public class TestShrinkAuxiliaryData {
|
||||
output.shouldHaveExitValue(0);
|
||||
}
|
||||
|
||||
private void printTestInfo(int maxCacheSize) {
|
||||
|
||||
private void printTestInfo() {
|
||||
DecimalFormat grouped = new DecimalFormat("000,000");
|
||||
DecimalFormatSymbols formatSymbols = grouped.getDecimalFormatSymbols();
|
||||
formatSymbols.setGroupingSeparator(' ');
|
||||
grouped.setDecimalFormatSymbols(formatSymbols);
|
||||
|
||||
System.out.format(
|
||||
"Test will use %s bytes of memory of %s available%n"
|
||||
+ "Available memory is %s with %d bytes pointer size - can save %s pointers%n"
|
||||
+ "Max cache size: 2^%d = %s elements%n",
|
||||
"Test will use %s bytes of memory of %s available%n",
|
||||
grouped.format(ShrinkAuxiliaryDataTest.getMemoryUsedByTest()),
|
||||
grouped.format(Runtime.getRuntime().maxMemory()),
|
||||
grouped.format(Runtime.getRuntime().maxMemory()
|
||||
- ShrinkAuxiliaryDataTest.getMemoryUsedByTest()),
|
||||
Unsafe.ADDRESS_SIZE,
|
||||
grouped.format((Runtime.getRuntime().freeMemory()
|
||||
- ShrinkAuxiliaryDataTest.getMemoryUsedByTest())
|
||||
/ Unsafe.ADDRESS_SIZE),
|
||||
maxCacheSize,
|
||||
grouped.format((int) Math.pow(2, maxCacheSize))
|
||||
grouped.format(Runtime.getRuntime().maxMemory())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects maximum possible size of G1ConcRSLogCacheSize available for
|
||||
* current process based on maximum available process memory size
|
||||
*
|
||||
* @return power of two
|
||||
*/
|
||||
private static int getMaxCacheSize() {
|
||||
long availableMemory = Runtime.getRuntime().freeMemory()
|
||||
- ShrinkAuxiliaryDataTest.getMemoryUsedByTest() - 1l;
|
||||
if (availableMemory <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
long availablePointersCount = availableMemory / Unsafe.ADDRESS_SIZE;
|
||||
return (63 - (int) Long.numberOfLeadingZeros(availablePointersCount));
|
||||
}
|
||||
|
||||
static class ShrinkAuxiliaryDataTest {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
@ -166,19 +125,19 @@ public class TestShrinkAuxiliaryData {
|
||||
/**
|
||||
* Checks is this environment suitable to run this test
|
||||
* - memory is enough to decommit (page size is not big)
|
||||
* - RSet cache size is not too big
|
||||
*
|
||||
* @return true if test could run, false if test should be skipped
|
||||
*/
|
||||
protected boolean checkEnvApplicability() {
|
||||
|
||||
int pageSize = WhiteBox.getWhiteBox().getVMPageSize();
|
||||
// Auxiliary data size is about ~1.9% of heap size.
|
||||
int auxDataSize = REGION_SIZE * REGIONS_TO_ALLOCATE * 19 / 1000;
|
||||
System.out.println( "Page size = " + pageSize
|
||||
+ " region size = " + REGION_SIZE
|
||||
+ " aux data ~= " + (REGION_SIZE * 3 / 100));
|
||||
+ " aux data ~= " + auxDataSize);
|
||||
// If auxdata size will be less than page size it wouldn't decommit.
|
||||
// Auxiliary data size is about ~3.6% of heap size.
|
||||
if (pageSize >= REGION_SIZE * 3 / 100) {
|
||||
if (pageSize >= auxDataSize) {
|
||||
System.out.format("Skipping test for too large page size = %d",
|
||||
pageSize
|
||||
);
|
||||
@ -229,13 +188,10 @@ public class TestShrinkAuxiliaryData {
|
||||
mutate();
|
||||
|
||||
muFull = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
|
||||
long numUsedRegions = WhiteBox.getWhiteBox().g1NumMaxRegions()
|
||||
- WhiteBox.getWhiteBox().g1NumFreeRegions();
|
||||
muAuxDataFull = WhiteBox.getWhiteBox().g1AuxiliaryMemoryUsage();
|
||||
auxFull = (float)muAuxDataFull.getUsed() / numUsedRegions;
|
||||
|
||||
System.out.format("Full aux data ratio= %f, regions max= %d, used= %d\n",
|
||||
auxFull, WhiteBox.getWhiteBox().g1NumMaxRegions(), numUsedRegions
|
||||
System.out.format("Full -- heap capacity: %d, Aux data: %d\n",
|
||||
muFull.getCommitted(), muAuxDataFull.getUsed()
|
||||
);
|
||||
|
||||
deallocate();
|
||||
@ -252,32 +208,17 @@ public class TestShrinkAuxiliaryData {
|
||||
muFree = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
|
||||
muAuxDataFree = WhiteBox.getWhiteBox().g1AuxiliaryMemoryUsage();
|
||||
|
||||
numUsedRegions = WhiteBox.getWhiteBox().g1NumMaxRegions()
|
||||
- WhiteBox.getWhiteBox().g1NumFreeRegions();
|
||||
auxFree = (float)muAuxDataFree.getUsed() / numUsedRegions;
|
||||
|
||||
System.out.format("Free aux data ratio= %f, regions max= %d, used= %d\n",
|
||||
auxFree, WhiteBox.getWhiteBox().g1NumMaxRegions(), numUsedRegions
|
||||
System.out.format("Free -- heap capacity: %d, Aux data: %d\n",
|
||||
muFree.getCommitted(), muAuxDataFree.getUsed()
|
||||
);
|
||||
|
||||
Asserts.assertLessThanOrEqual(muFree.getCommitted(), muFull.getCommitted(),
|
||||
String.format("heap decommit failed - full > free: %d > %d",
|
||||
muFree.getCommitted(), muFull.getCommitted()
|
||||
)
|
||||
Asserts.assertLessThan(muFree.getCommitted(), muFull.getCommitted(),
|
||||
"heap decommit failed"
|
||||
);
|
||||
|
||||
System.out.format("State used committed\n");
|
||||
System.out.format("Full aux data: %10d %10d\n", muAuxDataFull.getUsed(), muAuxDataFull.getCommitted());
|
||||
System.out.format("Free aux data: %10d %10d\n", muAuxDataFree.getUsed(), muAuxDataFree.getCommitted());
|
||||
|
||||
// if decommited check that aux data has same ratio
|
||||
if (muFree.getCommitted() < muFull.getCommitted()) {
|
||||
Asserts.assertLessThanOrEqual(auxFree, auxFull,
|
||||
String.format("auxiliary data decommit failed - full > free: %f > %f",
|
||||
auxFree, auxFull
|
||||
)
|
||||
);
|
||||
}
|
||||
Asserts.assertLessThan(muAuxDataFree.getUsed(), muAuxDataFull.getUsed(),
|
||||
"auxiliary data decommit failed"
|
||||
);
|
||||
}
|
||||
|
||||
private void allocate() {
|
||||
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2022, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package gc.g1;
|
||||
|
||||
/**
|
||||
* @test TestShrinkAuxiliaryData05
|
||||
* @key randomness
|
||||
* @bug 8038423 8061715 8078405
|
||||
* @summary Checks that decommitment occurs for JVM with different
|
||||
* G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
|
||||
* @requires vm.gc.G1
|
||||
* @library /test/lib
|
||||
* @library /
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData05
|
||||
*/
|
||||
public class TestShrinkAuxiliaryData05 {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new TestShrinkAuxiliaryData(5).test();
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2022, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package gc.g1;
|
||||
|
||||
/**
|
||||
* @test TestShrinkAuxiliaryData10
|
||||
* @key randomness
|
||||
* @bug 8038423 8061715 8078405
|
||||
* @summary Checks that decommitment occurs for JVM with different
|
||||
* G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
|
||||
* @requires vm.gc.G1
|
||||
* @library /test/lib
|
||||
* @library /
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData10
|
||||
*/
|
||||
public class TestShrinkAuxiliaryData10 {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new TestShrinkAuxiliaryData(10).test();
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2022, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package gc.g1;
|
||||
|
||||
/**
|
||||
* @test TestShrinkAuxiliaryData15
|
||||
* @bug 8038423 8061715 8078405
|
||||
* @key randomness
|
||||
* @summary Checks that decommitment occurs for JVM with different
|
||||
* G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
|
||||
* @requires vm.gc.G1
|
||||
* @library /test/lib
|
||||
* @library /
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData15
|
||||
*/
|
||||
public class TestShrinkAuxiliaryData15 {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new TestShrinkAuxiliaryData(15).test();
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2022, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package gc.g1;
|
||||
|
||||
/**
|
||||
* @test TestShrinkAuxiliaryData20
|
||||
* @key randomness
|
||||
* @bug 8038423 8061715 8078405
|
||||
* @summary Checks that decommitment occurs for JVM with different
|
||||
* G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
|
||||
* @requires vm.gc.G1
|
||||
* @library /test/lib
|
||||
* @library /
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData20
|
||||
*/
|
||||
public class TestShrinkAuxiliaryData20 {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new TestShrinkAuxiliaryData(20).test();
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2022, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package gc.g1;
|
||||
|
||||
/**
|
||||
* @test TestShrinkAuxiliaryData25
|
||||
* @key randomness
|
||||
* @bug 8038423 8061715 8078405
|
||||
* @summary Checks that decommitment occurs for JVM with different
|
||||
* G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
|
||||
* @requires vm.gc.G1
|
||||
* @library /test/lib
|
||||
* @library /
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData25
|
||||
*/
|
||||
public class TestShrinkAuxiliaryData25 {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new TestShrinkAuxiliaryData(25).test();
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2022, 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.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package gc.g1;
|
||||
|
||||
/**
|
||||
* @test TestShrinkAuxiliaryData27
|
||||
* @key randomness
|
||||
* @bug 8038423 8061715 8078405
|
||||
* @summary Checks that decommitment occurs for JVM with different
|
||||
* G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
|
||||
* @requires vm.gc.G1
|
||||
* @library /test/lib
|
||||
* @library /
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* java.management
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData27
|
||||
*/
|
||||
public class TestShrinkAuxiliaryData27 {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new TestShrinkAuxiliaryData(27).test();
|
||||
}
|
||||
}
|
@ -24,11 +24,10 @@
|
||||
package gc.g1;
|
||||
|
||||
/**
|
||||
* @test TestShrinkAuxiliaryData00
|
||||
* @test TestShrinkAuxiliaryDataRunner
|
||||
* @key randomness
|
||||
* @bug 8038423 8061715
|
||||
* @summary Checks that decommitment occurs for JVM with different
|
||||
* G1ConcRSLogCacheSize and ObjectAlignmentInBytes options values
|
||||
* @summary Checks that decommitment occurs for JVM with different ObjectAlignmentInBytes values
|
||||
* @requires vm.gc.G1
|
||||
* @library /test/lib
|
||||
* @library /
|
||||
@ -36,11 +35,11 @@ package gc.g1;
|
||||
* java.management
|
||||
* @build jdk.test.whitebox.WhiteBox
|
||||
* @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
|
||||
* @run main/timeout=720 gc.g1.TestShrinkAuxiliaryData00
|
||||
* @run main/timeout=720 gc.g1.TestShrinkAuxiliaryDataRunner
|
||||
*/
|
||||
public class TestShrinkAuxiliaryData00 {
|
||||
public class TestShrinkAuxiliaryDataRunner {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new TestShrinkAuxiliaryData(0).test();
|
||||
new TestShrinkAuxiliaryData().test();
|
||||
}
|
||||
}
|
@ -97,7 +97,6 @@ public class TestG1ParallelPhases {
|
||||
"CLDGRoots",
|
||||
"CMRefRoots",
|
||||
"MergeER",
|
||||
"MergeHCC",
|
||||
"MergeRS",
|
||||
"MergeLB",
|
||||
"ScanHR",
|
||||
@ -106,7 +105,6 @@ public class TestG1ParallelPhases {
|
||||
"Termination",
|
||||
"RedirtyCards",
|
||||
"RecalculateUsed",
|
||||
"ResetHotCardCache",
|
||||
"ResizeTLABs",
|
||||
"FreeCSet",
|
||||
"UpdateDerivedPointers",
|
||||
|
Loading…
x
Reference in New Issue
Block a user