mirror of
https://github.com/openjdk/jdk.git
synced 2026-04-28 15:51:02 +00:00
8369013: Shenandoah: passive mode should support enabling ShenandoahCardBarrier
Reviewed-by: wkemper
This commit is contained in:
parent
d62553d8dc
commit
f3dfdfa3fd
@ -48,11 +48,6 @@ void ShenandoahPassiveMode::initialize_flags() const {
|
||||
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCloneBarrier);
|
||||
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahStackWatermarkBarrier);
|
||||
SHENANDOAH_ERGO_DISABLE_FLAG(ShenandoahCardBarrier);
|
||||
|
||||
// Final configuration checks
|
||||
// Passive mode does not instantiate the machinery to support the card table.
|
||||
// Exit if the flag has been explicitly set.
|
||||
SHENANDOAH_CHECK_FLAG_UNSET(ShenandoahCardBarrier);
|
||||
}
|
||||
|
||||
ShenandoahHeuristics* ShenandoahPassiveMode::initialize_heuristics(ShenandoahSpaceInfo* space_info) const {
|
||||
|
||||
@ -95,6 +95,12 @@ void ShenandoahDegenGC::op_degenerated() {
|
||||
// some phase, we have to upgrade the Degenerate GC to Full GC.
|
||||
heap->clear_cancelled_gc();
|
||||
|
||||
// If it's passive mode with ShenandoahCardBarrier turned on: clean the write table
|
||||
// without swapping the tables since no scan happens in passive mode anyway
|
||||
if (ShenandoahCardBarrier && !heap->mode()->is_generational()) {
|
||||
heap->old_generation()->card_scan()->mark_write_table_as_clean();
|
||||
}
|
||||
|
||||
#ifdef ASSERT
|
||||
if (heap->mode()->is_generational()) {
|
||||
ShenandoahOldGeneration* old_generation = heap->old_generation();
|
||||
|
||||
@ -25,7 +25,6 @@
|
||||
#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHGENERATIONALHEAP
|
||||
#define SHARE_GC_SHENANDOAH_SHENANDOAHGENERATIONALHEAP
|
||||
|
||||
#include "gc/shenandoah/shenandoahAsserts.hpp"
|
||||
#include "gc/shenandoah/shenandoahHeap.hpp"
|
||||
#include "memory/universe.hpp"
|
||||
#include "utilities/checkedCast.hpp"
|
||||
@ -44,13 +43,13 @@ public:
|
||||
void initialize_heuristics() override;
|
||||
|
||||
static ShenandoahGenerationalHeap* heap() {
|
||||
shenandoah_assert_generational();
|
||||
assert(ShenandoahCardBarrier, "Should have card barrier to use genenrational heap");
|
||||
CollectedHeap* heap = Universe::heap();
|
||||
return cast(heap);
|
||||
}
|
||||
|
||||
static ShenandoahGenerationalHeap* cast(CollectedHeap* heap) {
|
||||
shenandoah_assert_generational();
|
||||
assert(ShenandoahCardBarrier, "Should have card barrier to use genenrational heap");
|
||||
return checked_cast<ShenandoahGenerationalHeap*>(heap);
|
||||
}
|
||||
|
||||
|
||||
@ -248,6 +248,13 @@ jint ShenandoahHeap::initialize() {
|
||||
// Now we know the number of regions and heap sizes, initialize the heuristics.
|
||||
initialize_heuristics();
|
||||
|
||||
// If ShenandoahCardBarrier is enabled but it's not generational mode
|
||||
// it means we're under passive mode and we have to initialize old gen
|
||||
// for the purpose of having card table.
|
||||
if (ShenandoahCardBarrier && !(mode()->is_generational())) {
|
||||
_old_generation = new ShenandoahOldGeneration(max_workers(), max_capacity());
|
||||
}
|
||||
|
||||
assert(_heap_region.byte_size() == heap_rs.size(), "Need to know reserved size for card table");
|
||||
|
||||
//
|
||||
|
||||
@ -530,7 +530,7 @@ public:
|
||||
}
|
||||
|
||||
ShenandoahOldGeneration* old_generation() const {
|
||||
assert(mode()->is_generational(), "Old generation requires generational mode");
|
||||
assert(ShenandoahCardBarrier, "Card mark barrier should be on");
|
||||
return _old_generation;
|
||||
}
|
||||
|
||||
|
||||
@ -123,6 +123,18 @@ void ShenandoahDirectCardMarkRememberedSet::mark_read_table_as_clean() {
|
||||
log_develop_debug(gc, barrier)("Cleaned read_table from " PTR_FORMAT " to " PTR_FORMAT, p2i(&(read_table[0])), p2i(end_bp));
|
||||
}
|
||||
|
||||
void ShenandoahDirectCardMarkRememberedSet::mark_write_table_as_clean() {
|
||||
CardValue* write_table = _card_table->write_byte_map();
|
||||
CardValue* bp = &(write_table)[0];
|
||||
CardValue* end_bp = &(write_table)[_card_table->last_valid_index()];
|
||||
|
||||
while (bp <= end_bp) {
|
||||
*bp++ = CardTable::clean_card_val();
|
||||
}
|
||||
|
||||
log_develop_debug(gc, barrier)("Cleaned write_table from " PTR_FORMAT " to " PTR_FORMAT, p2i(&(write_table[0])), p2i(end_bp));
|
||||
}
|
||||
|
||||
// No lock required because arguments align with card boundaries.
|
||||
void ShenandoahCardCluster::reset_object_range(HeapWord* from, HeapWord* to) {
|
||||
assert(((((unsigned long long) from) & (CardTable::card_size() - 1)) == 0) &&
|
||||
@ -330,6 +342,10 @@ void ShenandoahScanRemembered::mark_read_table_as_clean() {
|
||||
_rs->mark_read_table_as_clean();
|
||||
}
|
||||
|
||||
void ShenandoahScanRemembered::mark_write_table_as_clean() {
|
||||
_rs->mark_write_table_as_clean();
|
||||
}
|
||||
|
||||
void ShenandoahScanRemembered::reset_object_range(HeapWord* from, HeapWord* to) {
|
||||
_scc->reset_object_range(from, to);
|
||||
}
|
||||
|
||||
@ -244,6 +244,8 @@ public:
|
||||
// See comment in ShenandoahScanRemembered
|
||||
inline void mark_read_table_as_clean();
|
||||
|
||||
inline void mark_write_table_as_clean();
|
||||
|
||||
// Merge any dirty values from write table into the read table, while leaving
|
||||
// the write table unchanged.
|
||||
void merge_write_table(HeapWord* start, size_t word_count);
|
||||
@ -769,6 +771,8 @@ public:
|
||||
// the "write" table.
|
||||
void mark_read_table_as_clean();
|
||||
|
||||
void mark_write_table_as_clean();
|
||||
|
||||
// Swaps read and write card tables pointers in effect setting a clean card
|
||||
// table for the next GC cycle.
|
||||
void swap_card_tables() { _rs->swap_card_tables(); }
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright Amazon.com Inc. 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test passive mode with card barrier with a gc heavy app. A simple hello world in TestSelectiveBarrierFlags
|
||||
* does not always surface crashes
|
||||
* @requires vm.gc.Shenandoah
|
||||
* @library /test/lib
|
||||
*
|
||||
* @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+UseShenandoahGC -Xmx128m -XX:ShenandoahGCMode=passive -XX:+ShenandoahCardBarrier TestPassiveModeWithCardBarrier
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
public class TestPassiveModeWithCardBarrier {
|
||||
public static void main(String[] args) throws Exception {
|
||||
List<byte[]> junk = new ArrayList<>();
|
||||
int junkLength = 1000;
|
||||
int totalRounds = 10;
|
||||
int round = 0;
|
||||
|
||||
while (round++ < totalRounds) {
|
||||
for (int i = 0; i < junkLength; i++) {
|
||||
junk.add(new byte[1024]);
|
||||
}
|
||||
|
||||
System.out.println(junk.hashCode());
|
||||
}
|
||||
|
||||
// trigger a full gc in case it was all degen
|
||||
System.gc();
|
||||
}
|
||||
}
|
||||
@ -37,18 +37,30 @@ import jdk.test.lib.process.OutputAnalyzer;
|
||||
public class TestWrongBarrierEnable {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String[] concurrent = { "ShenandoahSATBBarrier" };
|
||||
String[] concurrent = {
|
||||
"ShenandoahLoadRefBarrier",
|
||||
"ShenandoahSATBBarrier",
|
||||
"ShenandoahCASBarrier",
|
||||
"ShenandoahCloneBarrier",
|
||||
"ShenandoahStackWatermarkBarrier",
|
||||
};
|
||||
String[] generational = { "ShenandoahCardBarrier" };
|
||||
String[] all = { "ShenandoahSATBBarrier", "ShenandoahCardBarrier" };
|
||||
String[] all = {
|
||||
"ShenandoahLoadRefBarrier",
|
||||
"ShenandoahSATBBarrier",
|
||||
"ShenandoahCASBarrier",
|
||||
"ShenandoahCloneBarrier",
|
||||
"ShenandoahStackWatermarkBarrier",
|
||||
"ShenandoahCardBarrier"
|
||||
};
|
||||
|
||||
shouldPassAll("-XX:ShenandoahGCHeuristics=adaptive", concurrent);
|
||||
shouldPassAll("-XX:ShenandoahGCHeuristics=static", concurrent);
|
||||
shouldPassAll("-XX:ShenandoahGCHeuristics=compact", concurrent);
|
||||
shouldPassAll("-XX:ShenandoahGCHeuristics=aggressive", concurrent);
|
||||
shouldPassAll("-XX:ShenandoahGCMode=passive", concurrent);
|
||||
shouldPassAll("-XX:ShenandoahGCMode=passive", all);
|
||||
shouldPassAll("-XX:ShenandoahGCMode=generational", all);
|
||||
shouldFailAll("-XX:ShenandoahGCMode=satb", generational);
|
||||
shouldFailAll("-XX:ShenandoahGCMode=passive", generational);
|
||||
}
|
||||
|
||||
private static void shouldFailAll(String h, String[] barriers) throws Exception {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user