8225409: G1: Remove the Hot Card Cache

Reviewed-by: tschatzl, iwalulya
This commit is contained in:
Albert Mingkun Yang 2023-02-14 10:18:43 +00:00
parent 92474f13f0
commit 7c50ab1612
33 changed files with 43 additions and 1169 deletions

@ -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",