Skip to content
Permalink
Browse files
8261473: Shenandoah: Add breakpoint support
Reviewed-by: rkennke, shade
  • Loading branch information
zhengyu123 committed Feb 18, 2021
1 parent c4664e6 commit 9cf4f90d34fa17c8e9cbe2c4132ff5d7f3d692b7
@@ -0,0 +1,65 @@
/*
* Copyright (c) 2021, Red Hat, Inc. All rights reserved.
* Copyright (c) 2020, 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/shared/concurrentGCBreakpoints.hpp"
#include "gc/shenandoah/shenandoahBreakpoint.hpp"
#include "runtime/mutexLocker.hpp"
#include "utilities/debug.hpp"

bool ShenandoahBreakpoint::_start_gc = false;

void ShenandoahBreakpoint::start_gc() {
MonitorLocker ml(ConcurrentGCBreakpoints::monitor());
assert(ConcurrentGCBreakpoints::is_controlled(), "Invalid state");
assert(!_start_gc, "Invalid state");
_start_gc = true;
ml.notify_all();
}

void ShenandoahBreakpoint::at_before_gc() {
MonitorLocker ml(ConcurrentGCBreakpoints::monitor(), Mutex::_no_safepoint_check_flag);
while (ConcurrentGCBreakpoints::is_controlled() && !_start_gc) {
ml.wait();
}
_start_gc = false;
ConcurrentGCBreakpoints::notify_idle_to_active();
}

void ShenandoahBreakpoint::at_after_gc() {
ConcurrentGCBreakpoints::notify_active_to_idle();
}

void ShenandoahBreakpoint::at_after_marking_started() {
ConcurrentGCBreakpoints::at("AFTER MARKING STARTED");
}

void ShenandoahBreakpoint::at_before_marking_completed() {
ConcurrentGCBreakpoints::at("BEFORE MARKING COMPLETED");
}

void ShenandoahBreakpoint::at_after_reference_processing_started() {
ConcurrentGCBreakpoints::at("AFTER CONCURRENT REFERENCE PROCESSING STARTED");
}
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2021, Red Hat, Inc. All rights reserved.
* Copyright (c) 2020, 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_SHENANDOAH_SHENANDOAHBREAKPOINT_HPP
#define SHARE_GC_SHENANDOAH_SHENANDOAHBREAKPOINT_HPP

#include "memory/allocation.hpp"

class ShenandoahBreakpoint : public AllStatic {
private:
static bool _start_gc;

public:
static void start_gc();

static void at_before_gc();
static void at_after_gc();
static void at_after_marking_started();
static void at_before_marking_completed();
static void at_after_reference_processing_started();
};
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHBREAKPOINT_HPP
@@ -26,6 +26,7 @@

#include "gc/shared/barrierSetNMethod.hpp"
#include "gc/shared/collectorCounters.hpp"
#include "gc/shenandoah/shenandoahBreakpoint.hpp"
#include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
#include "gc/shenandoah/shenandoahConcurrentGC.hpp"
#include "gc/shenandoah/shenandoahFreeSet.hpp"
@@ -42,9 +43,34 @@
#include "gc/shenandoah/shenandoahVMOperations.hpp"
#include "gc/shenandoah/shenandoahWorkGroup.hpp"
#include "gc/shenandoah/shenandoahWorkerPolicy.hpp"
#include "memory/allocation.hpp"
#include "prims/jvmtiTagMap.hpp"
#include "runtime/vmThread.hpp"
#include "utilities/events.hpp"

// Breakpoint support
class ShenandoahBreakpointGCScope : public StackObj {
public:
ShenandoahBreakpointGCScope() {
ShenandoahBreakpoint::at_before_gc();
}

~ShenandoahBreakpointGCScope() {
ShenandoahBreakpoint::at_after_gc();
}
};

class ShenandoahBreakpointMarkScope : public StackObj {
public:
ShenandoahBreakpointMarkScope() {
ShenandoahBreakpoint::at_after_marking_started();
}

~ShenandoahBreakpointMarkScope() {
ShenandoahBreakpoint::at_before_marking_completed();
}
};

ShenandoahConcurrentGC::ShenandoahConcurrentGC() :
_mark(),
_degen_point(ShenandoahDegenPoint::_degenerated_unset) {
@@ -60,20 +86,27 @@ void ShenandoahConcurrentGC::cancel() {

bool ShenandoahConcurrentGC::collect(GCCause::Cause cause) {
ShenandoahHeap* const heap = ShenandoahHeap::heap();
if (cause == GCCause::_wb_breakpoint) {
ShenandoahBreakpoint::start_gc();
}
ShenandoahBreakpointGCScope breakpoint_gc_scope;

// Reset for upcoming marking
entry_reset();

// Start initial mark under STW
vmop_entry_init_mark();

{
ShenandoahBreakpointMarkScope breakpoint_mark_scope;
// Concurrent mark roots
entry_mark_roots();
if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_outside_cycle)) return false;
entry_mark_roots();
if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_outside_cycle)) return false;

// Continue concurrent mark
entry_mark();
if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_mark)) return false;
// Continue concurrent mark
entry_mark();
if (check_cancellation_and_abort(ShenandoahDegenPoint::_degenerated_mark)) return false;
}

// Complete marking under STW, and start evacuation
vmop_entry_final_mark();
@@ -621,6 +654,7 @@ void ShenandoahConcurrentGC::op_weak_refs() {
assert(heap->is_concurrent_weak_root_in_progress(), "Only during this phase");
// Concurrent weak refs processing
ShenandoahGCWorkerPhase worker_phase(ShenandoahPhaseTimings::conc_weak_refs);
ShenandoahBreakpoint::at_after_reference_processing_started();
heap->ref_processor()->process_references(ShenandoahPhaseTimings::conc_weak_refs, heap->workers(), true /* concurrent */);
}

@@ -23,7 +23,6 @@
*/

#include "precompiled.hpp"

#include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
#include "gc/shenandoah/shenandoahConcurrentGC.hpp"
#include "gc/shenandoah/shenandoahControlThread.hpp"
@@ -478,6 +477,7 @@ void ShenandoahControlThread::request_gc(GCCause::Cause cause) {
cause == GCCause::_metadata_GC_clear_soft_refs ||
cause == GCCause::_full_gc_alot ||
cause == GCCause::_wb_full_gc ||
cause == GCCause::_wb_breakpoint ||
cause == GCCause::_scavenge_alot,
"only requested GCs here");

@@ -506,7 +506,10 @@ void ShenandoahControlThread::handle_requested_gc(GCCause::Cause cause) {
while (current_gc_id < required_gc_id) {
_gc_requested.set();
_requested_gc_cause = cause;
ml.wait();

if (cause != GCCause::_wb_breakpoint) {
ml.wait();
}
current_gc_id = get_gc_id();
}
}
@@ -162,6 +162,11 @@ class ShenandoahHeap : public CollectedHeap {
void prepare_for_verify();
void verify(VerifyOption vo);

// WhiteBox testing support.
bool supports_concurrent_gc_breakpoints() const {
return true;
}

// ---------- Heap counters and metrics
//
private:
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 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
@@ -117,14 +117,14 @@ private static void test() throws Exception {

private static boolean expectSupported() {
return GC.G1.isSelected() ||
GC.Z.isSelected();
GC.Z.isSelected() ||
GC.Shenandoah.isSelected();
}

private static boolean expectUnsupported() {
return GC.Serial.isSelected() ||
GC.Parallel.isSelected() ||
GC.Epsilon.isSelected() ||
GC.Shenandoah.isSelected();
GC.Epsilon.isSelected();
}

public static void main(String[] args) throws Exception {
@@ -25,7 +25,7 @@

/* @test
* @bug 8256517
* @requires vm.gc.Z
* @requires vm.gc.Z | vm.gc.Shenandoah
* @requires vm.gc != "null"
* @library /test/lib
* @build sun.hotspot.WhiteBox

1 comment on commit 9cf4f90

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on 9cf4f90 Feb 18, 2021

Please sign in to comment.