8143041: Unify G1CollectorPolicy::PauseKind and G1YCType

Reviewed-by: tschatzl, ayang
This commit is contained in:
Ivan Walulya 2021-03-11 09:22:25 +00:00
parent f6b4ba073f
commit 470b15027b
10 changed files with 202 additions and 169 deletions

View File

@ -43,6 +43,7 @@
#include "gc/g1/g1FullCollector.hpp"
#include "gc/g1/g1GCParPhaseTimesTracker.hpp"
#include "gc/g1/g1GCPhaseTimes.hpp"
#include "gc/g1/g1GCTypes.hpp"
#include "gc/g1/g1HeapSizingPolicy.hpp"
#include "gc/g1/g1HeapTransition.hpp"
#include "gc/g1/g1HeapVerifier.hpp"
@ -63,7 +64,6 @@
#include "gc/g1/g1StringDedup.hpp"
#include "gc/g1/g1ThreadLocalData.hpp"
#include "gc/g1/g1Trace.hpp"
#include "gc/g1/g1YCTypes.hpp"
#include "gc/g1/g1ServiceThread.hpp"
#include "gc/g1/g1UncommitRegionTask.hpp"
#include "gc/g1/g1VMOperations.hpp"
@ -2926,7 +2926,7 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus
{
G1EvacuationInfo evacuation_info;
_gc_tracer_stw->report_yc_type(collector_state()->yc_type());
_gc_tracer_stw->report_yc_phase(collector_state()->young_gc_phase());
GCTraceCPUTime tcpu;
@ -2940,7 +2940,7 @@ void G1CollectedHeap::do_collection_pause_at_safepoint_helper(double target_paus
G1MonitoringScope ms(g1mm(),
false /* full_gc */,
collector_state()->yc_type() == Mixed /* all_memory_pools_affected */);
collector_state()->young_gc_phase() == Mixed /* all_memory_pools_affected */);
G1HeapTransition heap_transition(this);

View File

@ -36,6 +36,7 @@
#include "gc/g1/g1EvacStats.hpp"
#include "gc/g1/g1EvacuationInfo.hpp"
#include "gc/g1/g1GCPhaseTimes.hpp"
#include "gc/g1/g1GCTypes.hpp"
#include "gc/g1/g1HeapTransition.hpp"
#include "gc/g1/g1HeapVerifier.hpp"
#include "gc/g1/g1HRPrinter.hpp"
@ -44,7 +45,6 @@
#include "gc/g1/g1NUMA.hpp"
#include "gc/g1/g1RedirtyCardsQueue.hpp"
#include "gc/g1/g1SurvivorRegions.hpp"
#include "gc/g1/g1YCTypes.hpp"
#include "gc/g1/heapRegionManager.hpp"
#include "gc/g1/heapRegionSet.hpp"
#include "gc/shared/barrierSet.hpp"

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2021, 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/g1CollectorState.hpp"
#include "gc/g1/g1GCTypes.hpp"
G1GCPauseType G1CollectorState::young_gc_pause_type(bool concurrent_operation_is_full_mark) const {
assert(!in_full_gc(), "must be");
if (in_concurrent_start_gc()) {
assert(!in_young_gc_before_mixed(), "must be");
return concurrent_operation_is_full_mark ? ConcurrentStartMarkGC : ConcurrentStartUndoGC;
} else if (in_young_gc_before_mixed()) {
assert(!in_concurrent_start_gc(), "must be");
return LastYoungGC;
} else if (in_mixed_phase()) {
assert(!in_concurrent_start_gc(), "must be");
assert(!in_young_gc_before_mixed(), "must be");
return MixedGC;
} else {
assert(!in_concurrent_start_gc(), "must be");
assert(!in_young_gc_before_mixed(), "must be");
return YoungGC;
}
}
G1GCYoungPhase G1CollectorState::young_gc_phase() const {
assert(!in_full_gc(), "must be");
if (in_concurrent_start_gc()) {
return ConcurrentStart;
} else if (mark_or_rebuild_in_progress()) {
return DuringMarkOrRebuild;
} else if (in_young_only_phase()) {
return Normal;
} else {
return Mixed;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, 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
@ -25,7 +25,7 @@
#ifndef SHARE_GC_G1_G1COLLECTORSTATE_HPP
#define SHARE_GC_G1_G1COLLECTORSTATE_HPP
#include "gc/g1/g1YCTypes.hpp"
#include "gc/g1/g1GCTypes.hpp"
#include "utilities/globalDefinitions.hpp"
// State of the G1 collection.
@ -110,17 +110,10 @@ public:
bool mark_or_rebuild_in_progress() const { return _mark_or_rebuild_in_progress; }
bool clearing_next_bitmap() const { return _clearing_next_bitmap; }
G1YCType yc_type() const {
if (in_concurrent_start_gc()) {
return ConcurrentStart;
} else if (mark_or_rebuild_in_progress()) {
return DuringMarkOrRebuild;
} else if (in_young_only_phase()) {
return Normal;
} else {
return Mixed;
}
}
// Calculate GC Pause Type from internal state.
G1GCPauseType young_gc_pause_type(bool concurrent_operation_is_full_mark) const;
G1GCYoungPhase young_gc_phase() const;
};
#endif // SHARE_GC_G1_G1COLLECTORSTATE_HPP

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2021, 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_G1GCTYPES_HPP
#define SHARE_GC_G1_G1GCTYPES_HPP
#include "utilities/debug.hpp"
// Enumarate the phases in which the collection cycle can be.
enum G1GCYoungPhase {
Normal,
ConcurrentStart,
DuringMarkOrRebuild,
Mixed,
G1GCYoungPhaseEndSentinel
};
enum G1GCPauseType {
YoungGC,
LastYoungGC,
ConcurrentStartMarkGC,
ConcurrentStartUndoGC,
Cleanup,
Remark,
MixedGC,
FullGC,
G1GCPauseTypeEndSentinel
};
class G1GCTypeHelper {
public:
static void assert_is_young_pause(G1GCPauseType type) {
assert(type != FullGC, "must be");
assert(type != Remark, "must be");
assert(type != Cleanup, "must be");
}
static bool is_young_only_pause(G1GCPauseType type) {
assert_is_young_pause(type);
return type == ConcurrentStartUndoGC ||
type == ConcurrentStartMarkGC ||
type == LastYoungGC ||
type == YoungGC;
}
static bool is_mixed_pause(G1GCPauseType type) {
assert_is_young_pause(type);
return type == MixedGC;
}
static bool is_last_young_pause(G1GCPauseType type) {
assert_is_young_pause(type);
return type == LastYoungGC;
}
static bool is_concurrent_start_pause(G1GCPauseType type) {
assert_is_young_pause(type);
return type == ConcurrentStartMarkGC || type == ConcurrentStartUndoGC;
}
static const char* to_string(G1GCYoungPhase type) {
switch(type) {
case Normal: return "Normal";
case ConcurrentStart: return "Concurrent Start";
case DuringMarkOrRebuild: return "During Mark";
case Mixed: return "Mixed";
default: ShouldNotReachHere(); return NULL;
}
}
};
#endif // SHARE_GC_G1_G1GCTYPES_HPP

View File

@ -631,11 +631,11 @@ void G1Policy::record_collection_pause_end(double pause_time_ms, bool concurrent
double end_time_sec = os::elapsedTime();
double start_time_sec = phase_times()->cur_collection_start_sec();
PauseKind this_pause = young_gc_pause_kind(concurrent_operation_is_full_mark);
G1GCPauseType this_pause = collector_state()->young_gc_pause_type(concurrent_operation_is_full_mark);
bool update_stats = should_update_gc_stats();
if (is_concurrent_start_pause(this_pause)) {
if (G1GCTypeHelper::is_concurrent_start_pause(this_pause)) {
record_concurrent_mark_init_end();
} else {
maybe_start_marking();
@ -665,15 +665,15 @@ void G1Policy::record_collection_pause_end(double pause_time_ms, bool concurrent
record_pause(this_pause, start_time_sec, end_time_sec);
if (is_last_young_pause(this_pause)) {
assert(!is_concurrent_start_pause(this_pause),
if (G1GCTypeHelper::is_last_young_pause(this_pause)) {
assert(!G1GCTypeHelper::is_concurrent_start_pause(this_pause),
"The young GC before mixed is not allowed to be concurrent start GC");
// This has been the young GC before we start doing mixed GCs. We already
// decided to start mixed GCs much earlier, so there is nothing to do except
// advancing the state.
collector_state()->set_in_young_only_phase(false);
collector_state()->set_in_young_gc_before_mixed(false);
} else if (is_mixed_pause(this_pause)) {
} else if (G1GCTypeHelper::is_mixed_pause(this_pause)) {
// This is a mixed GC. Here we decide whether to continue doing more
// mixed GCs or not.
if (!next_gc_should_be_mixed("continue mixed GCs",
@ -684,7 +684,7 @@ void G1Policy::record_collection_pause_end(double pause_time_ms, bool concurrent
maybe_start_marking();
}
} else {
assert(is_young_only_pause(this_pause), "must be");
assert(G1GCTypeHelper::is_young_only_pause(this_pause), "must be");
}
_eden_surv_rate_group->start_adding_regions();
@ -709,7 +709,7 @@ void G1Policy::record_collection_pause_end(double pause_time_ms, bool concurrent
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(this_pause));
G1GCTypeHelper::is_young_only_pause(this_pause));
}
// Update prediction for card scan
@ -721,7 +721,7 @@ void G1Policy::record_collection_pause_end(double pause_time_ms, bool concurrent
average_time_ms(G1GCPhaseTimes::OptScanHR);
_analytics->report_cost_per_card_scan_ms(avg_time_dirty_card_scan / total_cards_scanned,
is_young_only_pause(this_pause));
G1GCTypeHelper::is_young_only_pause(this_pause));
}
// Update prediction for the ratio between cards from the remembered
@ -736,7 +736,7 @@ void G1Policy::record_collection_pause_end(double pause_time_ms, bool concurrent
merge_to_scan_ratio = (double) from_rs_length_cards / total_cards_scanned;
}
_analytics->report_card_merge_to_scan_ratio(merge_to_scan_ratio,
is_young_only_pause(this_pause));
G1GCTypeHelper::is_young_only_pause(this_pause));
const size_t recorded_rs_length = _collection_set->recorded_rs_length();
const size_t rs_length_diff = _rs_length > recorded_rs_length ? _rs_length - recorded_rs_length : 0;
@ -766,15 +766,15 @@ void G1Policy::record_collection_pause_end(double pause_time_ms, bool concurrent
// these are is wildly different to during young only gc and mess up young gen sizing right
// after the mixed gc phase.
// During mixed gc we do not use them for young gen sizing.
if (is_young_only_pause(this_pause)) {
if (G1GCTypeHelper::is_young_only_pause(this_pause)) {
_analytics->report_pending_cards((double) _pending_cards_at_gc_start);
_analytics->report_rs_length((double) _rs_length);
}
}
assert(!(is_concurrent_start_pause(this_pause) && collector_state()->mark_or_rebuild_in_progress()),
assert(!(G1GCTypeHelper::is_concurrent_start_pause(this_pause) && collector_state()->mark_or_rebuild_in_progress()),
"If the last pause has been concurrent start, we should not have been in the marking window");
if (is_concurrent_start_pause(this_pause)) {
if (G1GCTypeHelper::is_concurrent_start_pause(this_pause)) {
collector_state()->set_mark_or_rebuild_in_progress(concurrent_operation_is_full_mark);
}
@ -794,7 +794,7 @@ void G1Policy::record_collection_pause_end(double pause_time_ms, bool concurrent
_old_gen_alloc_tracker.reset_after_gc(_g1h->humongous_regions_count() * HeapRegion::GrainBytes);
update_ihop_prediction(app_time_ms / 1000.0,
last_unrestrained_young_length * HeapRegion::GrainBytes,
is_young_only_pause(this_pause));
G1GCTypeHelper::is_young_only_pause(this_pause));
_ihop_control->send_trace_event(_g1h->gc_tracer_stw());
} else {
@ -1151,57 +1151,13 @@ void G1Policy::maybe_start_marking() {
}
}
bool G1Policy::is_young_only_pause(PauseKind kind) {
assert(kind != FullGC, "must be");
assert(kind != Remark, "must be");
assert(kind != Cleanup, "must be");
return kind == ConcurrentStartUndoGC ||
kind == ConcurrentStartMarkGC ||
kind == LastYoungGC ||
kind == YoungOnlyGC;
}
bool G1Policy::is_mixed_pause(PauseKind kind) {
assert(kind != FullGC, "must be");
assert(kind != Remark, "must be");
assert(kind != Cleanup, "must be");
return kind == MixedGC;
}
bool G1Policy::is_last_young_pause(PauseKind kind) {
return kind == LastYoungGC;
}
bool G1Policy::is_concurrent_start_pause(PauseKind kind) {
return kind == ConcurrentStartMarkGC || kind == ConcurrentStartUndoGC;
}
G1Policy::PauseKind G1Policy::young_gc_pause_kind(bool concurrent_operation_is_full_mark) const {
assert(!collector_state()->in_full_gc(), "must be");
if (collector_state()->in_concurrent_start_gc()) {
assert(!collector_state()->in_young_gc_before_mixed(), "must be");
return concurrent_operation_is_full_mark ? ConcurrentStartMarkGC : ConcurrentStartUndoGC;
} else if (collector_state()->in_young_gc_before_mixed()) {
assert(!collector_state()->in_concurrent_start_gc(), "must be");
return LastYoungGC;
} else if (collector_state()->in_mixed_phase()) {
assert(!collector_state()->in_concurrent_start_gc(), "must be");
assert(!collector_state()->in_young_gc_before_mixed(), "must be");
return MixedGC;
} else {
assert(!collector_state()->in_concurrent_start_gc(), "must be");
assert(!collector_state()->in_young_gc_before_mixed(), "must be");
return YoungOnlyGC;
}
}
bool G1Policy::should_update_gc_stats() {
// Evacuation failures skew the timing too much to be considered for statistics updates.
// We make the assumption that these are rare.
return !_g1h->evacuation_failed();
}
void G1Policy::update_gc_pause_time_ratios(PauseKind kind, double start_time_sec, double end_time_sec) {
void G1Policy::update_gc_pause_time_ratios(G1GCPauseType gc_type, double start_time_sec, double end_time_sec) {
double pause_time_sec = end_time_sec - start_time_sec;
double pause_time_ms = pause_time_sec * 1000.0;
@ -1209,39 +1165,39 @@ void G1Policy::update_gc_pause_time_ratios(PauseKind kind, double start_time_sec
_analytics->compute_pause_time_ratios(end_time_sec, pause_time_ms);
_analytics->update_recent_gc_times(end_time_sec, pause_time_ms);
if (kind == Cleanup || kind == Remark) {
if (gc_type == Cleanup || gc_type == Remark) {
_analytics->append_prev_collection_pause_end_ms(pause_time_ms);
} else {
_analytics->set_prev_collection_pause_end_ms(end_time_sec * 1000.0);
}
}
void G1Policy::record_pause(PauseKind kind,
void G1Policy::record_pause(G1GCPauseType gc_type,
double start,
double end) {
// Manage the MMU tracker. For some reason it ignores Full GCs.
if (kind != FullGC) {
if (gc_type != FullGC) {
_mmu_tracker->add_pause(start, end);
}
if (should_update_gc_stats()) {
update_gc_pause_time_ratios(kind, start, end);
update_gc_pause_time_ratios(gc_type, start, end);
}
update_time_to_mixed_tracking(kind, start, end);
update_time_to_mixed_tracking(gc_type, start, end);
}
void G1Policy::update_time_to_mixed_tracking(PauseKind kind,
void G1Policy::update_time_to_mixed_tracking(G1GCPauseType gc_type,
double start,
double end) {
// Manage the mutator time tracking from concurrent start to first mixed gc.
switch (kind) {
switch (gc_type) {
case FullGC:
abort_time_to_mixed_tracking();
break;
case Cleanup:
case Remark:
case YoungOnlyGC:
case YoungGC:
case LastYoungGC:
_concurrent_start_to_mixed.add_pause(end - start);
break;

View File

@ -261,33 +261,14 @@ private:
void clear_collection_set_candidates();
// Sets up marking if proper conditions are met.
void maybe_start_marking();
// The kind of STW pause.
enum PauseKind : uint {
FullGC,
YoungOnlyGC,
MixedGC,
LastYoungGC,
ConcurrentStartMarkGC,
ConcurrentStartUndoGC,
Cleanup,
Remark
};
static bool is_young_only_pause(PauseKind kind);
static bool is_mixed_pause(PauseKind kind);
static bool is_last_young_pause(PauseKind kind);
static bool is_concurrent_start_pause(PauseKind kind);
// Calculate PauseKind from internal state.
PauseKind young_gc_pause_kind(bool concurrent_operation_is_full_mark) const;
// Manage time-to-mixed tracking.
void update_time_to_mixed_tracking(PauseKind pause, double start, double end);
void update_time_to_mixed_tracking(G1GCPauseType gc_type, double start, double end);
// Record the given STW pause with the given start and end times (in s).
void record_pause(PauseKind kind, double start, double end);
void record_pause(G1GCPauseType gc_type, double start, double end);
bool should_update_gc_stats();
void update_gc_pause_time_ratios(PauseKind kind, double start_sec, double end_sec);
void update_gc_pause_time_ratios(G1GCPauseType gc_type, double start_sec, double end_sec);
// Indicate that we aborted marking before doing any mixed GCs.
void abort_time_to_mixed_tracking();

View File

@ -26,7 +26,7 @@
#include "gc/g1/g1EvacuationInfo.hpp"
#include "gc/g1/g1HeapRegionTraceType.hpp"
#include "gc/g1/g1Trace.hpp"
#include "gc/g1/g1YCTypes.hpp"
#include "gc/g1/g1GCTypes.hpp"
#include "gc/shared/gcHeapSummary.hpp"
#include "jfr/jfrEvents.hpp"
#if INCLUDE_JFR
@ -49,11 +49,11 @@ public:
class G1YCTypeConstant : public JfrSerializer {
public:
void serialize(JfrCheckpointWriter& writer) {
static const u4 nof_entries = G1YCTypeEndSentinel;
static const u4 nof_entries = G1GCYoungPhaseEndSentinel;
writer.write_count(nof_entries);
for (u4 i = 0; i < nof_entries; ++i) {
writer.write_key(i);
writer.write(G1YCTypeHelper::to_string((G1YCType)i));
writer.write(G1GCTypeHelper::to_string((G1GCYoungPhase)i));
}
}
};
@ -72,8 +72,8 @@ void G1NewTracer::initialize() {
JFR_ONLY(register_jfr_type_constants());
}
void G1NewTracer::report_yc_type(G1YCType type) {
_g1_young_gc_info.set_type(type);
void G1NewTracer::report_yc_phase(G1GCYoungPhase phase) {
_g1_young_gc_info.set_phase(phase);
}
void G1NewTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) {
@ -129,7 +129,7 @@ void G1NewTracer::send_g1_young_gc_event() {
EventG1GarbageCollection e(UNTIMED);
if (e.should_commit()) {
e.set_gcId(GCId::current());
e.set_type(_g1_young_gc_info.type());
e.set_type(_g1_young_gc_info.phase());
e.set_starttime(_shared_gc_info.start_timestamp());
e.set_endtime(_shared_gc_info.end_timestamp());
e.commit();

View File

@ -25,7 +25,7 @@
#ifndef SHARE_GC_G1_G1TRACE_HPP
#define SHARE_GC_G1_G1TRACE_HPP
#include "gc/g1/g1YCTypes.hpp"
#include "gc/g1/g1GCTypes.hpp"
#include "gc/shared/gcTrace.hpp"
class G1EvacuationInfo;
@ -33,13 +33,13 @@ class G1HeapSummary;
class G1EvacSummary;
class G1YoungGCInfo {
G1YCType _type;
G1GCYoungPhase _phase;
public:
G1YoungGCInfo() : _type(G1YCTypeEndSentinel) {}
void set_type(G1YCType type) {
_type = type;
G1YoungGCInfo() : _phase(G1GCYoungPhaseEndSentinel) {}
void set_phase(G1GCYoungPhase phase) {
_phase = phase;
}
G1YCType type() const { return _type; }
G1GCYoungPhase phase() const { return _phase; }
};
class G1NewTracer : public YoungGCTracer {
@ -49,7 +49,7 @@ public:
G1NewTracer() : YoungGCTracer(G1New) {}
void initialize();
void report_yc_type(G1YCType type);
void report_yc_phase(G1GCYoungPhase phase);
void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions);
void report_evacuation_info(G1EvacuationInfo* info);
void report_evacuation_failed(EvacuationFailedInfo& ef_info);

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2012, 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_G1YCTYPES_HPP
#define SHARE_GC_G1_G1YCTYPES_HPP
#include "utilities/debug.hpp"
enum G1YCType {
Normal,
ConcurrentStart,
DuringMarkOrRebuild,
Mixed,
G1YCTypeEndSentinel
};
class G1YCTypeHelper {
public:
static const char* to_string(G1YCType type) {
switch(type) {
case Normal: return "Normal";
case ConcurrentStart: return "Concurrent Start";
case DuringMarkOrRebuild: return "During Mark";
case Mixed: return "Mixed";
default: ShouldNotReachHere(); return NULL;
}
}
};
#endif // SHARE_GC_G1_G1YCTYPES_HPP