mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-15 16:44:36 +02:00
8221507: Implement JFR Events for Shenandoah
Reviewed-by: rkennke, shade, egahlin, mseledtsov
This commit is contained in:
parent
1645161cad
commit
8cab46d6ca
13 changed files with 383 additions and 21 deletions
|
@ -67,6 +67,10 @@
|
||||||
#include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp"
|
#include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp"
|
||||||
#include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp"
|
#include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp"
|
||||||
#include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp"
|
#include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp"
|
||||||
|
#if INCLUDE_JFR
|
||||||
|
#include "gc/shenandoah/shenandoahJfrSupport.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "memory/metaspace.hpp"
|
#include "memory/metaspace.hpp"
|
||||||
#include "oops/compressedOops.inline.hpp"
|
#include "oops/compressedOops.inline.hpp"
|
||||||
#include "runtime/globals.hpp"
|
#include "runtime/globals.hpp"
|
||||||
|
@ -596,6 +600,8 @@ void ShenandoahHeap::post_initialize() {
|
||||||
ref_processing_init();
|
ref_processing_init();
|
||||||
|
|
||||||
_heuristics->initialize();
|
_heuristics->initialize();
|
||||||
|
|
||||||
|
JFR_ONLY(ShenandoahJFRSupport::register_jfr_type_serializers());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ShenandoahHeap::used() const {
|
size_t ShenandoahHeap::used() const {
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
|
#include "gc/shenandoah/shenandoahMarkingContext.inline.hpp"
|
||||||
#include "gc/shenandoah/shenandoahTraversalGC.hpp"
|
#include "gc/shenandoah/shenandoahTraversalGC.hpp"
|
||||||
#include "gc/shared/space.inline.hpp"
|
#include "gc/shared/space.inline.hpp"
|
||||||
|
#include "jfr/jfrEvents.hpp"
|
||||||
#include "memory/iterator.inline.hpp"
|
#include "memory/iterator.inline.hpp"
|
||||||
#include "memory/resourceArea.hpp"
|
#include "memory/resourceArea.hpp"
|
||||||
#include "memory/universe.hpp"
|
#include "memory/universe.hpp"
|
||||||
|
@ -93,7 +94,7 @@ void ShenandoahHeapRegion::make_regular_allocation() {
|
||||||
case _empty_uncommitted:
|
case _empty_uncommitted:
|
||||||
do_commit();
|
do_commit();
|
||||||
case _empty_committed:
|
case _empty_committed:
|
||||||
_state = _regular;
|
set_state(_regular);
|
||||||
case _regular:
|
case _regular:
|
||||||
case _pinned:
|
case _pinned:
|
||||||
return;
|
return;
|
||||||
|
@ -114,10 +115,10 @@ void ShenandoahHeapRegion::make_regular_bypass() {
|
||||||
case _cset:
|
case _cset:
|
||||||
case _humongous_start:
|
case _humongous_start:
|
||||||
case _humongous_cont:
|
case _humongous_cont:
|
||||||
_state = _regular;
|
set_state(_regular);
|
||||||
return;
|
return;
|
||||||
case _pinned_cset:
|
case _pinned_cset:
|
||||||
_state = _pinned;
|
set_state(_pinned);
|
||||||
return;
|
return;
|
||||||
case _regular:
|
case _regular:
|
||||||
case _pinned:
|
case _pinned:
|
||||||
|
@ -133,7 +134,7 @@ void ShenandoahHeapRegion::make_humongous_start() {
|
||||||
case _empty_uncommitted:
|
case _empty_uncommitted:
|
||||||
do_commit();
|
do_commit();
|
||||||
case _empty_committed:
|
case _empty_committed:
|
||||||
_state = _humongous_start;
|
set_state(_humongous_start);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
report_illegal_transition("humongous start allocation");
|
report_illegal_transition("humongous start allocation");
|
||||||
|
@ -149,7 +150,7 @@ void ShenandoahHeapRegion::make_humongous_start_bypass() {
|
||||||
case _regular:
|
case _regular:
|
||||||
case _humongous_start:
|
case _humongous_start:
|
||||||
case _humongous_cont:
|
case _humongous_cont:
|
||||||
_state = _humongous_start;
|
set_state(_humongous_start);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
report_illegal_transition("humongous start bypass");
|
report_illegal_transition("humongous start bypass");
|
||||||
|
@ -162,7 +163,7 @@ void ShenandoahHeapRegion::make_humongous_cont() {
|
||||||
case _empty_uncommitted:
|
case _empty_uncommitted:
|
||||||
do_commit();
|
do_commit();
|
||||||
case _empty_committed:
|
case _empty_committed:
|
||||||
_state = _humongous_cont;
|
set_state(_humongous_cont);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
report_illegal_transition("humongous continuation allocation");
|
report_illegal_transition("humongous continuation allocation");
|
||||||
|
@ -178,7 +179,7 @@ void ShenandoahHeapRegion::make_humongous_cont_bypass() {
|
||||||
case _regular:
|
case _regular:
|
||||||
case _humongous_start:
|
case _humongous_start:
|
||||||
case _humongous_cont:
|
case _humongous_cont:
|
||||||
_state = _humongous_cont;
|
set_state(_humongous_cont);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
report_illegal_transition("humongous continuation bypass");
|
report_illegal_transition("humongous continuation bypass");
|
||||||
|
@ -190,14 +191,14 @@ void ShenandoahHeapRegion::make_pinned() {
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case _regular:
|
case _regular:
|
||||||
assert (_critical_pins == 0, "sanity");
|
assert (_critical_pins == 0, "sanity");
|
||||||
_state = _pinned;
|
set_state(_pinned);
|
||||||
case _pinned_cset:
|
case _pinned_cset:
|
||||||
case _pinned:
|
case _pinned:
|
||||||
_critical_pins++;
|
_critical_pins++;
|
||||||
return;
|
return;
|
||||||
case _humongous_start:
|
case _humongous_start:
|
||||||
assert (_critical_pins == 0, "sanity");
|
assert (_critical_pins == 0, "sanity");
|
||||||
_state = _pinned_humongous_start;
|
set_state(_pinned_humongous_start);
|
||||||
case _pinned_humongous_start:
|
case _pinned_humongous_start:
|
||||||
_critical_pins++;
|
_critical_pins++;
|
||||||
return;
|
return;
|
||||||
|
@ -219,7 +220,7 @@ void ShenandoahHeapRegion::make_unpinned() {
|
||||||
assert (_critical_pins > 0, "sanity");
|
assert (_critical_pins > 0, "sanity");
|
||||||
_critical_pins--;
|
_critical_pins--;
|
||||||
if (_critical_pins == 0) {
|
if (_critical_pins == 0) {
|
||||||
_state = _regular;
|
set_state(_regular);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case _regular:
|
case _regular:
|
||||||
|
@ -231,14 +232,14 @@ void ShenandoahHeapRegion::make_unpinned() {
|
||||||
assert (_critical_pins > 0, "sanity");
|
assert (_critical_pins > 0, "sanity");
|
||||||
_critical_pins--;
|
_critical_pins--;
|
||||||
if (_critical_pins == 0) {
|
if (_critical_pins == 0) {
|
||||||
_state = _cset;
|
set_state(_cset);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case _pinned_humongous_start:
|
case _pinned_humongous_start:
|
||||||
assert (_critical_pins > 0, "sanity");
|
assert (_critical_pins > 0, "sanity");
|
||||||
_critical_pins--;
|
_critical_pins--;
|
||||||
if (_critical_pins == 0) {
|
if (_critical_pins == 0) {
|
||||||
_state = _humongous_start;
|
set_state(_humongous_start);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
|
@ -250,7 +251,7 @@ void ShenandoahHeapRegion::make_cset() {
|
||||||
_heap->assert_heaplock_owned_by_current_thread();
|
_heap->assert_heaplock_owned_by_current_thread();
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case _regular:
|
case _regular:
|
||||||
_state = _cset;
|
set_state(_cset);
|
||||||
case _cset:
|
case _cset:
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
|
@ -268,7 +269,7 @@ void ShenandoahHeapRegion::make_trash() {
|
||||||
// Reclaiming humongous regions
|
// Reclaiming humongous regions
|
||||||
case _regular:
|
case _regular:
|
||||||
// Immediate region reclaim
|
// Immediate region reclaim
|
||||||
_state = _trash;
|
set_state(_trash);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
report_illegal_transition("trashing");
|
report_illegal_transition("trashing");
|
||||||
|
@ -287,7 +288,7 @@ void ShenandoahHeapRegion::make_empty() {
|
||||||
_heap->assert_heaplock_owned_by_current_thread();
|
_heap->assert_heaplock_owned_by_current_thread();
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case _trash:
|
case _trash:
|
||||||
_state = _empty_committed;
|
set_state(_empty_committed);
|
||||||
_empty_time = os::elapsedTime();
|
_empty_time = os::elapsedTime();
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
|
@ -300,7 +301,7 @@ void ShenandoahHeapRegion::make_uncommitted() {
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case _empty_committed:
|
case _empty_committed:
|
||||||
do_uncommit();
|
do_uncommit();
|
||||||
_state = _empty_uncommitted;
|
set_state(_empty_uncommitted);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
report_illegal_transition("uncommiting");
|
report_illegal_transition("uncommiting");
|
||||||
|
@ -314,7 +315,7 @@ void ShenandoahHeapRegion::make_committed_bypass() {
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case _empty_uncommitted:
|
case _empty_uncommitted:
|
||||||
do_commit();
|
do_commit();
|
||||||
_state = _empty_committed;
|
set_state(_empty_committed);
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
report_illegal_transition("commit bypass");
|
report_illegal_transition("commit bypass");
|
||||||
|
@ -679,3 +680,16 @@ void ShenandoahHeapRegion::do_uncommit() {
|
||||||
}
|
}
|
||||||
_heap->decrease_committed(ShenandoahHeapRegion::region_size_bytes());
|
_heap->decrease_committed(ShenandoahHeapRegion::region_size_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShenandoahHeapRegion::set_state(RegionState to) {
|
||||||
|
EventShenandoahHeapRegionStateChange evt;
|
||||||
|
if (evt.should_commit()){
|
||||||
|
evt.set_index(region_number());
|
||||||
|
evt.set_start((uintptr_t)bottom());
|
||||||
|
evt.set_used(used());
|
||||||
|
evt.set_from(_state);
|
||||||
|
evt.set_to(to);
|
||||||
|
evt.commit();
|
||||||
|
}
|
||||||
|
_state = to;
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2018, Red Hat, Inc. All rights reserved.
|
* Copyright (c) 2013, 2019, Red Hat, Inc. All rights reserved.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
@ -32,9 +32,11 @@
|
||||||
#include "utilities/sizes.hpp"
|
#include "utilities/sizes.hpp"
|
||||||
|
|
||||||
class VMStructs;
|
class VMStructs;
|
||||||
|
class ShenandoahHeapRegionStateConstant;
|
||||||
|
|
||||||
class ShenandoahHeapRegion : public ContiguousSpace {
|
class ShenandoahHeapRegion : public ContiguousSpace {
|
||||||
friend class VMStructs;
|
friend class VMStructs;
|
||||||
|
friend class ShenandoahHeapRegionStateConstant;
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
Region state is described by a state machine. Transitions are guarded by
|
Region state is described by a state machine. Transitions are guarded by
|
||||||
|
@ -114,10 +116,11 @@ private:
|
||||||
_cset, // region is in collection set
|
_cset, // region is in collection set
|
||||||
_pinned, // region is pinned
|
_pinned, // region is pinned
|
||||||
_pinned_cset, // region is pinned and in cset (evac failure path)
|
_pinned_cset, // region is pinned and in cset (evac failure path)
|
||||||
_trash // region contains only trash
|
_trash, // region contains only trash
|
||||||
|
_REGION_STATES_NUM // last
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* region_state_to_string(RegionState s) const {
|
static const char* region_state_to_string(RegionState s) {
|
||||||
switch (s) {
|
switch (s) {
|
||||||
case _empty_uncommitted: return "Empty Uncommitted";
|
case _empty_uncommitted: return "Empty Uncommitted";
|
||||||
case _empty_committed: return "Empty Committed";
|
case _empty_committed: return "Empty Committed";
|
||||||
|
@ -157,6 +160,10 @@ private:
|
||||||
void report_illegal_transition(const char* method);
|
void report_illegal_transition(const char* method);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const int region_states_num() {
|
||||||
|
return _REGION_STATES_NUM;
|
||||||
|
}
|
||||||
|
|
||||||
// Allowed transitions from the outside code:
|
// Allowed transitions from the outside code:
|
||||||
void make_regular_allocation();
|
void make_regular_allocation();
|
||||||
void make_regular_bypass();
|
void make_regular_bypass();
|
||||||
|
@ -424,6 +431,8 @@ private:
|
||||||
void oop_iterate_humongous(OopIterateClosure* cl);
|
void oop_iterate_humongous(OopIterateClosure* cl);
|
||||||
|
|
||||||
inline void internal_increase_live_data(size_t s);
|
inline void internal_increase_live_data(size_t s);
|
||||||
|
|
||||||
|
void set_state(RegionState to);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
|
#endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP
|
||||||
|
|
71
src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp
Normal file
71
src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* 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/shenandoah/shenandoahHeap.hpp"
|
||||||
|
#include "gc/shenandoah/shenandoahHeapRegion.hpp"
|
||||||
|
#include "gc/shenandoah/shenandoahJfrSupport.hpp"
|
||||||
|
#include "jfr/jfrEvents.hpp"
|
||||||
|
#if INCLUDE_JFR
|
||||||
|
#include "jfr/metadata/jfrSerializer.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if INCLUDE_JFR
|
||||||
|
|
||||||
|
class ShenandoahHeapRegionStateConstant : public JfrSerializer {
|
||||||
|
friend class ShenandoahHeapRegion;
|
||||||
|
public:
|
||||||
|
virtual void serialize(JfrCheckpointWriter& writer) {
|
||||||
|
static const u4 nof_entries = ShenandoahHeapRegion::region_states_num();
|
||||||
|
writer.write_count(nof_entries);
|
||||||
|
for (u4 i = 0; i < nof_entries; ++i) {
|
||||||
|
writer.write_key(i);
|
||||||
|
writer.write(ShenandoahHeapRegion::region_state_to_string((ShenandoahHeapRegion::RegionState)i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void ShenandoahJFRSupport::register_jfr_type_serializers() {
|
||||||
|
JfrSerializer::register_serializer(TYPE_SHENANDOAHHEAPREGIONSTATE,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
new ShenandoahHeapRegionStateConstant());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class ShenandoahDumpHeapRegionInfoClosure : public ShenandoahHeapRegionClosure {
|
||||||
|
public:
|
||||||
|
virtual void heap_region_do(ShenandoahHeapRegion* r) {
|
||||||
|
EventShenandoahHeapRegionInformation evt;
|
||||||
|
evt.set_index(r->region_number());
|
||||||
|
evt.set_state((u8)r->state());
|
||||||
|
evt.set_start((uintptr_t)r->bottom());
|
||||||
|
evt.set_used(r->used());
|
||||||
|
evt.commit();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void VM_ShenandoahSendHeapRegionInfoEvents::doit() {
|
||||||
|
ShenandoahDumpHeapRegionInfoClosure c;
|
||||||
|
ShenandoahHeap::heap()->heap_region_iterate(&c);
|
||||||
|
}
|
40
src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.hpp
Normal file
40
src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.hpp
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* 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_SHENANDOAHJFRSUPPORT_HPP
|
||||||
|
#define SHARE_GC_SHENANDOAH_SHENANDOAHJFRSUPPORT_HPP
|
||||||
|
|
||||||
|
#include "runtime/vmOperations.hpp"
|
||||||
|
|
||||||
|
class VM_ShenandoahSendHeapRegionInfoEvents : public VM_Operation {
|
||||||
|
public:
|
||||||
|
virtual void doit();
|
||||||
|
virtual VMOp_Type type() const { return VMOp_HeapIterateOperation; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class ShenandoahJFRSupport {
|
||||||
|
public:
|
||||||
|
static void register_jfr_type_serializers();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAHJFRSUPPORT_HPP
|
|
@ -983,6 +983,27 @@
|
||||||
<Field type="ulong" name="value" label="Value" />
|
<Field type="ulong" name="value" label="Value" />
|
||||||
</Event>
|
</Event>
|
||||||
|
|
||||||
|
<Event name="ShenandoahHeapRegionStateChange" category="Java Virtual Machine, GC, Detailed" label="Shenandoah Heap Region State Change" description="Information about a Shenandoah heap region state change"
|
||||||
|
startTime="false">
|
||||||
|
<Field type="uint" name="index" label="Index" />
|
||||||
|
<Field type="ShenandoahHeapRegionState" name="from" label="From" />
|
||||||
|
<Field type="ShenandoahHeapRegionState" name="to" label="To" />
|
||||||
|
<Field type="ulong" contentType="address" name="start" label="Start" />
|
||||||
|
<Field type="ulong" contentType="bytes" name="used" label="Used" />
|
||||||
|
</Event>
|
||||||
|
|
||||||
|
<Event name="ShenandoahHeapRegionInformation" category="Java Virtual Machine, GC, Detailed" label="Shenandoah Heap Region Information" description="Information about a specific heap region in the Shenandoah GC"
|
||||||
|
period="everyChunk">
|
||||||
|
<Field type="uint" name="index" label="Index" />
|
||||||
|
<Field type="ShenandoahHeapRegionState" name="state" label="State" />
|
||||||
|
<Field type="ulong" contentType="address" name="start" label="Start" />
|
||||||
|
<Field type="ulong" contentType="bytes" name="used" label="Used" />
|
||||||
|
</Event>
|
||||||
|
|
||||||
|
<Type name="ShenandoahHeapRegionState" label="Shenandoah Heap Region State">
|
||||||
|
<Field type="string" name="state" label="State" />
|
||||||
|
</Type>
|
||||||
|
|
||||||
<Type name="ZStatisticsCounterType" label="Z Statistics Counter">
|
<Type name="ZStatisticsCounterType" label="Z Statistics Counter">
|
||||||
<Field type="string" name="counter" label="Counter" />
|
<Field type="string" name="counter" label="Counter" />
|
||||||
</Type>
|
</Type>
|
||||||
|
|
|
@ -65,7 +65,9 @@
|
||||||
#include "services/threadService.hpp"
|
#include "services/threadService.hpp"
|
||||||
#include "utilities/exceptions.hpp"
|
#include "utilities/exceptions.hpp"
|
||||||
#include "utilities/globalDefinitions.hpp"
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
#if INCLUDE_SHENANDOAHGC
|
||||||
|
#include "gc/shenandoah/shenandoahJfrSupport.hpp"
|
||||||
|
#endif
|
||||||
/**
|
/**
|
||||||
* JfrPeriodic class
|
* JfrPeriodic class
|
||||||
* Implementation of declarations in
|
* Implementation of declarations in
|
||||||
|
@ -626,3 +628,14 @@ TRACE_REQUEST_FUNC(CodeSweeperConfiguration) {
|
||||||
event.set_flushingEnabled(UseCodeCacheFlushing);
|
event.set_flushingEnabled(UseCodeCacheFlushing);
|
||||||
event.commit();
|
event.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TRACE_REQUEST_FUNC(ShenandoahHeapRegionInformation) {
|
||||||
|
#if INCLUDE_SHENANDOAHGC
|
||||||
|
if (UseShenandoahGC) {
|
||||||
|
VM_ShenandoahSendHeapRegionInfoEvents op;
|
||||||
|
VMThread::execute(&op);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -445,6 +445,15 @@
|
||||||
<setting name="enabled" control="gc-enabled-all">false</setting>
|
<setting name="enabled" control="gc-enabled-all">false</setting>
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
<event name="jdk.ShenandoahHeapRegionInformation">
|
||||||
|
<setting name="enabled" control="gc-enabled-all">false</setting>
|
||||||
|
<setting name="period">everyChunk</setting>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="jdk.ShenandoahHeapRegionStateChange">
|
||||||
|
<setting name="enabled" control="gc-enabled-all">false</setting>
|
||||||
|
</event>
|
||||||
|
|
||||||
<event name="jdk.OldObjectSample">
|
<event name="jdk.OldObjectSample">
|
||||||
<setting name="enabled" control="memory-leak-detection-enabled">true</setting>
|
<setting name="enabled" control="memory-leak-detection-enabled">true</setting>
|
||||||
<setting name="stackTrace" control="memory-leak-detection-stack-trace">false</setting>
|
<setting name="stackTrace" control="memory-leak-detection-stack-trace">false</setting>
|
||||||
|
|
|
@ -445,6 +445,15 @@
|
||||||
<setting name="enabled" control="gc-enabled-all">false</setting>
|
<setting name="enabled" control="gc-enabled-all">false</setting>
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
<event name="jdk.ShenandoahHeapRegionInformation">
|
||||||
|
<setting name="enabled" control="gc-enabled-all">false</setting>
|
||||||
|
<setting name="period">everyChunk</setting>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="jdk.ShenandoahHeapRegionStateChange">
|
||||||
|
<setting name="enabled" control="gc-enabled-all">false</setting>
|
||||||
|
</event>
|
||||||
|
|
||||||
<event name="jdk.OldObjectSample">
|
<event name="jdk.OldObjectSample">
|
||||||
<setting name="enabled" control="memory-leak-detection-enabled">true</setting>
|
<setting name="enabled" control="memory-leak-detection-enabled">true</setting>
|
||||||
<setting name="stackTrace" control="memory-leak-detection-stack-trace">true</setting>
|
<setting name="stackTrace" control="memory-leak-detection-stack-trace">true</setting>
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* 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 jdk.jfr.event.gc.detailed;
|
||||||
|
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jdk.jfr.EventType;
|
||||||
|
import jdk.jfr.FlightRecorder;
|
||||||
|
import jdk.jfr.Recording;
|
||||||
|
import jdk.jfr.consumer.RecordedEvent;
|
||||||
|
import jdk.test.lib.Asserts;
|
||||||
|
import jdk.test.lib.jfr.EventNames;
|
||||||
|
import jdk.test.lib.jfr.Events;
|
||||||
|
import jdk.test.lib.jfr.GCHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8221507
|
||||||
|
* @requires vm.hasJFR
|
||||||
|
* @requires vm.gc == "Shenandoah" | vm.gc == null
|
||||||
|
* @key jfr
|
||||||
|
* @library /test/lib /test/jdk
|
||||||
|
* @run main/othervm -Xmx32m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGarbageThreshold=1 jdk.jfr.event.gc.detailed.TestShenandoahHeapRegionInformationEvent
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
public class TestShenandoahHeapRegionInformationEvent {
|
||||||
|
private final static String EVENT_NAME = EventNames.ShenandoahHeapRegionInformation;
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
try (Recording recording = new Recording()) {
|
||||||
|
// activate the event we are interested in and start recording
|
||||||
|
for (EventType t : FlightRecorder.getFlightRecorder().getEventTypes()) {
|
||||||
|
System.out.println(t.getName());
|
||||||
|
}
|
||||||
|
recording.enable(EVENT_NAME);
|
||||||
|
recording.start();
|
||||||
|
recording.stop();
|
||||||
|
|
||||||
|
// Verify recording
|
||||||
|
List<RecordedEvent> events = Events.fromRecording(recording);
|
||||||
|
Events.hasEvents(events);
|
||||||
|
for (RecordedEvent event : events) {
|
||||||
|
Events.assertField(event, "index").notEqual(-1);
|
||||||
|
GCHelper.assertIsValidShenandoahHeapRegionState(Events.assertField(event, "state").getValue());
|
||||||
|
Events.assertField(event, "used").atMost(1L*1024*1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019, Red Hat, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* 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 jdk.jfr.event.gc.detailed;
|
||||||
|
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import jdk.jfr.Recording;
|
||||||
|
import jdk.jfr.consumer.RecordedEvent;
|
||||||
|
import jdk.test.lib.Asserts;
|
||||||
|
import jdk.test.lib.jfr.EventNames;
|
||||||
|
import jdk.test.lib.jfr.Events;
|
||||||
|
import jdk.test.lib.jfr.GCHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @bug 8221507
|
||||||
|
* @requires vm.hasJFR
|
||||||
|
* @requires vm.gc == "Shenandoah" | vm.gc == null
|
||||||
|
* @key jfr
|
||||||
|
* @library /test/lib /test/jdk
|
||||||
|
* @run main/othervm -Xmx32m -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGarbageThreshold=1 jdk.jfr.event.gc.detailed.TestShenandoahHeapRegionStateChangeEvent
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class TestShenandoahHeapRegionStateChangeEvent {
|
||||||
|
private final static String EVENT_NAME = EventNames.ShenandoahHeapRegionStateChange;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
try (Recording recording = new Recording()) {
|
||||||
|
// activate the event we are interested in and start recording
|
||||||
|
recording.enable(EVENT_NAME).withThreshold(Duration.ofMillis(0));
|
||||||
|
recording.start();
|
||||||
|
|
||||||
|
byte[][] array = new byte[1024][];
|
||||||
|
for (int i = 0; i < array.length; i++) {
|
||||||
|
array[i] = new byte[20 * 1024];
|
||||||
|
}
|
||||||
|
recording.stop();
|
||||||
|
|
||||||
|
// Verify recording
|
||||||
|
List<RecordedEvent> events = Events.fromRecording(recording);
|
||||||
|
Asserts.assertFalse(events.isEmpty(), "No events found");
|
||||||
|
|
||||||
|
for (RecordedEvent event : events) {
|
||||||
|
Events.assertField(event, "index").notEqual(-1);
|
||||||
|
GCHelper.assertIsValidShenandoahHeapRegionState(Events.assertField(event, "from").getValue());
|
||||||
|
GCHelper.assertIsValidShenandoahHeapRegionState(Events.assertField(event, "to").getValue());
|
||||||
|
Events.assertField(event, "used").atMost(1L*1024*1024);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -101,6 +101,8 @@ public class EventNames {
|
||||||
public final static String G1HeapSummary = PREFIX + "G1HeapSummary";
|
public final static String G1HeapSummary = PREFIX + "G1HeapSummary";
|
||||||
public final static String G1HeapRegionInformation = PREFIX + "G1HeapRegionInformation";
|
public final static String G1HeapRegionInformation = PREFIX + "G1HeapRegionInformation";
|
||||||
public final static String G1HeapRegionTypeChange = PREFIX + "G1HeapRegionTypeChange";
|
public final static String G1HeapRegionTypeChange = PREFIX + "G1HeapRegionTypeChange";
|
||||||
|
public final static String ShenandoahHeapRegionInformation = PREFIX + "ShenandoahHeapRegionInformation";
|
||||||
|
public final static String ShenandoahHeapRegionStateChange = PREFIX + "ShenandoahHeapRegionStateChange";
|
||||||
public final static String TenuringDistribution = PREFIX + "TenuringDistribution";
|
public final static String TenuringDistribution = PREFIX + "TenuringDistribution";
|
||||||
public final static String GarbageCollection = PREFIX + "GarbageCollection";
|
public final static String GarbageCollection = PREFIX + "GarbageCollection";
|
||||||
public final static String ParallelOldGarbageCollection = PREFIX + "ParallelOldGarbageCollection";
|
public final static String ParallelOldGarbageCollection = PREFIX + "ParallelOldGarbageCollection";
|
||||||
|
|
|
@ -80,6 +80,7 @@ public class GCHelper {
|
||||||
public static final String pauseLevelEvent = "GCPhasePauseLevel";
|
public static final String pauseLevelEvent = "GCPhasePauseLevel";
|
||||||
|
|
||||||
private static final List<String> g1HeapRegionTypes;
|
private static final List<String> g1HeapRegionTypes;
|
||||||
|
private static final List<String> shenandoahHeapRegionStates;
|
||||||
private static PrintStream defaultErrorLog = null;
|
private static PrintStream defaultErrorLog = null;
|
||||||
|
|
||||||
public static int getGcId(RecordedEvent event) {
|
public static int getGcId(RecordedEvent event) {
|
||||||
|
@ -207,6 +208,21 @@ public class GCHelper {
|
||||||
};
|
};
|
||||||
|
|
||||||
g1HeapRegionTypes = Collections.unmodifiableList(Arrays.asList(g1HeapRegionTypeLiterals));
|
g1HeapRegionTypes = Collections.unmodifiableList(Arrays.asList(g1HeapRegionTypeLiterals));
|
||||||
|
|
||||||
|
String[] shenandoahHeapRegionStateLiterals = new String[] {
|
||||||
|
"Empty Uncommitted",
|
||||||
|
"Empty Committed",
|
||||||
|
"Regular",
|
||||||
|
"Humongous Start",
|
||||||
|
"Humongous Continuation",
|
||||||
|
"Humongous Start, Pinned",
|
||||||
|
"Collection Set",
|
||||||
|
"Pinned",
|
||||||
|
"Collection Set, Pinned",
|
||||||
|
"Trash"
|
||||||
|
};
|
||||||
|
|
||||||
|
shenandoahHeapRegionStates = Collections.unmodifiableList(Arrays.asList(shenandoahHeapRegionStateLiterals));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -443,6 +459,13 @@ public class GCHelper {
|
||||||
return g1HeapRegionTypes.contains(type);
|
return g1HeapRegionTypes.contains(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean assertIsValidShenandoahHeapRegionState(final String state) {
|
||||||
|
if (!shenandoahHeapRegionStates.contains(state)) {
|
||||||
|
throw new AssertionError("Unknown state '" + state + "', valid heap region states are " + shenandoahHeapRegionStates);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to align heap size up.
|
* Helper function to align heap size up.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue