--- old/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-05-02 15:26:56.470440252 -0400 +++ new/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp 2019-05-02 15:26:56.226441742 -0400 @@ -63,6 +63,9 @@ #include "gc/shenandoah/heuristics/shenandoahPassiveHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" #include "gc/shenandoah/heuristics/shenandoahTraversalHeuristics.hpp" +#if INCLUDE_JFR +#include "gc/shenandoah/shenandoahJfrSupport.hpp" +#endif #include "memory/metaspace.hpp" #include "runtime/vmThread.hpp" @@ -505,6 +508,8 @@ ref_processing_init(); _heuristics->initialize(); + + JFR_ONLY(ShenandoahJFRSupport::register_jfr_type_serializers()); } size_t ShenandoahHeap::used() const { --- old/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp 2019-05-02 15:26:57.156436062 -0400 +++ new/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp 2019-05-02 15:26:56.913437546 -0400 @@ -30,6 +30,7 @@ #include "gc/shenandoah/shenandoahMarkingContext.inline.hpp" #include "gc/shenandoah/shenandoahTraversalGC.hpp" #include "gc/shared/space.inline.hpp" +#include "jfr/jfrEvents.hpp" #include "memory/iterator.inline.hpp" #include "memory/resourceArea.hpp" #include "memory/universe.hpp" @@ -94,7 +95,7 @@ case _empty_uncommitted: do_commit(); case _empty_committed: - _state = _regular; + set_state(_regular); case _regular: case _pinned: return; @@ -115,10 +116,10 @@ case _cset: case _humongous_start: case _humongous_cont: - _state = _regular; + set_state(_regular); return; case _pinned_cset: - _state = _pinned; + set_state(_pinned); return; case _regular: case _pinned: @@ -134,7 +135,7 @@ case _empty_uncommitted: do_commit(); case _empty_committed: - _state = _humongous_start; + set_state(_humongous_start); return; default: report_illegal_transition("humongous start allocation"); @@ -150,7 +151,7 @@ case _regular: case _humongous_start: case _humongous_cont: - _state = _humongous_start; + set_state(_humongous_start); return; default: report_illegal_transition("humongous start bypass"); @@ -163,7 +164,7 @@ case _empty_uncommitted: do_commit(); case _empty_committed: - _state = _humongous_cont; + set_state(_humongous_cont); return; default: report_illegal_transition("humongous continuation allocation"); @@ -179,7 +180,7 @@ case _regular: case _humongous_start: case _humongous_cont: - _state = _humongous_cont; + set_state(_humongous_cont); return; default: report_illegal_transition("humongous continuation bypass"); @@ -191,14 +192,14 @@ switch (_state) { case _regular: assert (_critical_pins == 0, "sanity"); - _state = _pinned; + set_state(_pinned); case _pinned_cset: case _pinned: _critical_pins++; return; case _humongous_start: assert (_critical_pins == 0, "sanity"); - _state = _pinned_humongous_start; + set_state(_pinned_humongous_start); case _pinned_humongous_start: _critical_pins++; return; @@ -220,7 +221,7 @@ assert (_critical_pins > 0, "sanity"); _critical_pins--; if (_critical_pins == 0) { - _state = _regular; + set_state(_regular); } return; case _regular: @@ -232,14 +233,14 @@ assert (_critical_pins > 0, "sanity"); _critical_pins--; if (_critical_pins == 0) { - _state = _cset; + set_state(_cset); } return; case _pinned_humongous_start: assert (_critical_pins > 0, "sanity"); _critical_pins--; if (_critical_pins == 0) { - _state = _humongous_start; + set_state(_humongous_start); } return; default: @@ -251,7 +252,7 @@ _heap->assert_heaplock_owned_by_current_thread(); switch (_state) { case _regular: - _state = _cset; + set_state(_cset); case _cset: return; default: @@ -269,7 +270,7 @@ // Reclaiming humongous regions case _regular: // Immediate region reclaim - _state = _trash; + set_state(_trash); return; default: report_illegal_transition("trashing"); @@ -288,7 +289,7 @@ _heap->assert_heaplock_owned_by_current_thread(); switch (_state) { case _trash: - _state = _empty_committed; + set_state(_empty_committed); _empty_time = os::elapsedTime(); return; default: @@ -301,7 +302,7 @@ switch (_state) { case _empty_committed: do_uncommit(); - _state = _empty_uncommitted; + set_state(_empty_uncommitted); return; default: report_illegal_transition("uncommiting"); @@ -315,7 +316,7 @@ switch (_state) { case _empty_uncommitted: do_commit(); - _state = _empty_committed; + set_state(_empty_committed); return; default: report_illegal_transition("commit bypass"); @@ -678,3 +679,16 @@ } _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; +} --- old/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp 2019-05-02 15:26:57.823431988 -0400 +++ new/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp 2019-05-02 15:26:57.581433466 -0400 @@ -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 * under the terms of the GNU General Public License version 2 only, as @@ -33,9 +33,11 @@ #include "utilities/sizes.hpp" class VMStructs; +class ShenandoahHeapRegionStateConstant; class ShenandoahHeapRegion : public ContiguousSpace { friend class VMStructs; + friend class ShenandoahHeapRegionStateConstant; private: /* Region state is described by a state machine. Transitions are guarded by @@ -116,9 +118,10 @@ _pinned, // region is pinned _pinned_cset, // region is pinned and in cset (evac failure path) _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) { case _empty_uncommitted: return "Empty Uncommitted"; case _empty_committed: return "Empty Committed"; @@ -158,6 +161,10 @@ void report_illegal_transition(const char* method); public: + static const int region_states_num() { + return _REGION_STATES_NUM; + } + // Allowed transitions from the outside code: void make_regular_allocation(); void make_regular_bypass(); @@ -426,6 +433,8 @@ void oop_iterate_humongous(OopIterateClosure* cl); inline void internal_increase_live_data(size_t s); + + void set_state(RegionState to); }; #endif // SHARE_GC_SHENANDOAH_SHENANDOAHHEAPREGION_HPP --- old/src/hotspot/share/jfr/metadata/metadata.xml 2019-05-02 15:26:58.487427933 -0400 +++ new/src/hotspot/share/jfr/metadata/metadata.xml 2019-05-02 15:26:58.244429417 -0400 @@ -925,6 +925,27 @@ + + + + + + + + + + + + + + + + + + + --- old/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp 2019-05-02 15:26:59.165423792 -0400 +++ new/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp 2019-05-02 15:26:58.921425282 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -62,7 +62,9 @@ #include "services/threadService.hpp" #include "utilities/exceptions.hpp" #include "utilities/globalDefinitions.hpp" - +#if INCLUDE_SHENANDOAHGC +#include "gc/shenandoah/shenandoahJfrSupport.hpp" +#endif /** * JfrPeriodic class * Implementation of declarations in @@ -577,3 +579,12 @@ event.set_flushingEnabled(UseCodeCacheFlushing); event.commit(); } + +#if INCLUDE_SHENANDOAHGC +TRACE_REQUEST_FUNC(ShenandoahHeapRegionInformation) { + if (UseShenandoahGC) { + VM_ShenandoahSendHeapRegionInfoEvents op; + VMThread::execute(&op); + } +} +#endif --- /dev/null 2019-04-23 16:30:34.864501003 -0400 +++ new/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.cpp 2019-05-02 15:26:59.513421666 -0400 @@ -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); +} --- /dev/null 2019-04-23 16:30:34.864501003 -0400 +++ new/src/hotspot/share/gc/shenandoah/shenandoahJfrSupport.hpp 2019-05-02 15:27:00.131417892 -0400 @@ -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