Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 5 additions & 27 deletions src/hotspot/share/gc/shared/gcTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@
#include "gc/shared/gcId.hpp"
#include "gc/shared/gcTimer.hpp"
#include "gc/shared/gcTrace.hpp"
#include "gc/shared/gcTrace.inline.hpp"
#include "gc/shared/objectCountEventSender.hpp"
#include "gc/shared/referenceProcessorStats.hpp"
#include "jfr/jfrEvents.hpp"
#include "memory/heapInspection.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/os.hpp"
Expand Down Expand Up @@ -74,46 +76,22 @@ void GCTracer::report_gc_reference_stats(const ReferenceProcessorStats& rps) con
}

#if INCLUDE_SERVICES
class ObjectCountEventSenderClosure : public KlassInfoClosure {
const double _size_threshold_percentage;
const size_t _total_size_in_words;
const Ticks _timestamp;

public:
ObjectCountEventSenderClosure(size_t total_size_in_words, const Ticks& timestamp) :
_size_threshold_percentage(ObjectCountCutOffPercent / 100),
_total_size_in_words(total_size_in_words),
_timestamp(timestamp)
{}

virtual void do_cinfo(KlassInfoEntry* entry) {
if (should_send_event(entry)) {
ObjectCountEventSender::send(entry, _timestamp);
}
}

private:
bool should_send_event(const KlassInfoEntry* entry) const {
double percentage_of_heap = ((double) entry->words()) / _total_size_in_words;
return percentage_of_heap >= _size_threshold_percentage;
}
};

void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl, WorkerThreads* workers) {
assert(is_alive_cl != nullptr, "Must supply function to check liveness");

if (ObjectCountEventSender::should_send_event()) {
if (ObjectCountEventSender::should_send_event<EventObjectCountAfterGC>()) {
ResourceMark rm;

KlassInfoTable cit(false);
if (!cit.allocation_failed()) {
HeapInspection hi;
hi.populate_table(&cit, is_alive_cl, workers);
ObjectCountEventSenderClosure event_sender(cit.size_of_instances_in_words(), Ticks::now());
ObjectCountEventSenderClosure<EventObjectCountAfterGC> event_sender(cit.size_of_instances_in_words(), Ticks::now(), &cit);
cit.iterate(&event_sender);
}
}
}

#endif // INCLUDE_SERVICES

void GCTracer::report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary) const {
Expand Down
5 changes: 5 additions & 0 deletions src/hotspot/share/gc/shared/gcTrace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ class GCTracer {
void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary) const;
void report_metaspace_summary(GCWhen::Type when, const MetaspaceSummary& metaspace_summary) const;
void report_gc_reference_stats(const ReferenceProcessorStats& rp) const;

// Sends event data to the ObjectCount and/or ObjectCountAfterGC event
template <typename T>
void report_object_count(T* heap) NOT_SERVICES_RETURN;

void report_object_count_after_gc(BoolObjectClosure* object_filter, WorkerThreads* workers) NOT_SERVICES_RETURN;
void report_cpu_time_event(double user_time, double system_time, double real_time) const;

Expand Down
54 changes: 54 additions & 0 deletions src/hotspot/share/gc/shared/gcTrace.inline.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef SHARE_GC_SHARED_GCTRACE_INLINE_HPP
#define SHARE_GC_SHARED_GCTRACE_INLINE_HPP

#include "gc/shared/gcTrace.hpp"
#include "gc/shared/objectCountEventSender.inline.hpp"
#include "jfr/jfrEvents.hpp"
#include "memory/heapInspection.hpp"
#include "utilities/macros.hpp"

#if INCLUDE_SERVICES

template <typename Event>
class ObjectCountEventSenderClosure : public KlassInfoClosure {
const double _size_threshold_percentage;
size_t _total_size_in_words;
const Ticks _timestamp;
KlassInfoTable* _cit;

public:
ObjectCountEventSenderClosure(size_t total_size_in_words, const Ticks& timestamp, KlassInfoTable* cit) :
_size_threshold_percentage(ObjectCountCutOffPercent / 100),
_total_size_in_words(total_size_in_words),
_timestamp(timestamp),
_cit(cit)
{}

virtual void do_cinfo(KlassInfoEntry* entry) {
if (should_send_event(entry)) {
ObjectCountEventSender::send<Event>(entry, _timestamp);
_cit->delete_entry(entry, &_total_size_in_words);
}
}

private:
bool should_send_event(const KlassInfoEntry* entry) const {
double percentage_of_heap = ((double) entry->words()) / _total_size_in_words;
return percentage_of_heap >= _size_threshold_percentage;
}
};

template <typename T>
void GCTracer::report_object_count(T* heap) {
KlassInfoTable* cit = heap->get_cit();

if (cit == nullptr || !ObjectCountEventSender::should_send_event<EventObjectCountAfterGC>()) {
return;
}
ObjectCountEventSenderClosure<EventObjectCountAfterGC> event_sender(cit->size_of_instances_in_words(), Ticks::now(), cit);
cit->iterate(&event_sender);
}

#endif // INCLUDE_SERVICES

#endif // SHARE_GC_SHARED_GCTRACE_INLINE_HPP
46 changes: 1 addition & 45 deletions src/hotspot/share/gc/shared/objectCountEventSender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,54 +22,10 @@
*
*/


#include "gc/shared/gcId.hpp"
#include "gc/shared/objectCountEventSender.hpp"
#include "jfr/jfrEvents.hpp"
#include "memory/heapInspection.hpp"
#include "utilities/macros.hpp"
#include "utilities/ticks.hpp"
#if INCLUDE_SERVICES

bool ObjectCountEventSender::should_send_event() {
#if INCLUDE_JFR
return _should_send_requestable_event || EventObjectCountAfterGC::is_enabled();
#else
return false;
#endif // INCLUDE_JFR
}
#if INCLUDE_SERVICES

bool ObjectCountEventSender::_should_send_requestable_event = false;

void ObjectCountEventSender::enable_requestable_event() {
_should_send_requestable_event = true;
}

void ObjectCountEventSender::disable_requestable_event() {
_should_send_requestable_event = false;
}

template <typename T>
void ObjectCountEventSender::send_event_if_enabled(Klass* klass, jlong count, julong size, const Ticks& timestamp) {
T event(UNTIMED);
if (event.should_commit()) {
event.set_starttime(timestamp);
event.set_endtime(timestamp);
event.set_gcId(GCId::current());
event.set_objectClass(klass);
event.set_count(count);
event.set_totalSize(size);
event.commit();
}
}

void ObjectCountEventSender::send(const KlassInfoEntry* entry, const Ticks& timestamp) {
Klass* klass = entry->klass();
jlong count = entry->count();
julong total_size = entry->words() * BytesPerWord;

send_event_if_enabled<EventObjectCount>(klass, count, total_size, timestamp);
send_event_if_enabled<EventObjectCountAfterGC>(klass, count, total_size, timestamp);
}

#endif // INCLUDE_SERVICES
14 changes: 9 additions & 5 deletions src/hotspot/share/gc/shared/objectCountEventSender.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@
#ifndef SHARE_GC_SHARED_OBJECTCOUNTEVENTSENDER_HPP
#define SHARE_GC_SHARED_OBJECTCOUNTEVENTSENDER_HPP

#include "gc/shared/gcTrace.hpp"
#include "jfr/jfrEvents.hpp"
#include "memory/allStatic.hpp"
#include "memory/heapInspection.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/macros.hpp"
#include "utilities/ticks.hpp"

#if INCLUDE_SERVICES

class KlassInfoEntry;
Expand All @@ -39,17 +39,21 @@ class Klass;
class ObjectCountEventSender : public AllStatic {
static bool _should_send_requestable_event;

template <typename T>
template <typename Event>
static void send_event_if_enabled(Klass* klass, jlong count, julong size, const Ticks& timestamp);

public:
static void enable_requestable_event();
static void disable_requestable_event();
static inline void enable_requestable_event();
static inline void disable_requestable_event();

template <class Event>
static void send(const KlassInfoEntry* entry, const Ticks& timestamp);

template <class Event>
static bool should_send_event();
};


#endif // INCLUDE_SERVICES

#endif // SHARE_GC_SHARED_OBJECTCOUNTEVENTSENDER_HPP
55 changes: 55 additions & 0 deletions src/hotspot/share/gc/shared/objectCountEventSender.inline.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef SHARE_GC_SHARED_OBJECTCOUNTEVENTSENDER_INLINE_HPP
#define SHARE_GC_SHARED_OBJECTCOUNTEVENTSENDER_INLINE_HPP

#include "gc/shared/objectCountEventSender.hpp"

#if INCLUDE_SERVICES

inline void ObjectCountEventSender::enable_requestable_event() {
ObjectCountEventSender::_should_send_requestable_event = true;
}

inline void ObjectCountEventSender::disable_requestable_event() {
ObjectCountEventSender::_should_send_requestable_event = false;
}

template <class Event>
bool ObjectCountEventSender::should_send_event() {
#if INCLUDE_JFR
return _should_send_requestable_event || Event::is_enabled();
#else
return false;
#endif // INCLUDE_JFR
}

template <typename T>
void ObjectCountEventSender::send_event_if_enabled(Klass* klass, jlong count, julong size, const Ticks& timestamp) {
T event(UNTIMED);
if (event.should_commit()) {
event.set_starttime(timestamp);
event.set_endtime(timestamp);
event.set_gcId(GCId::current());
event.set_objectClass(klass);
event.set_count(count);
event.set_totalSize(size);
event.commit();
}
}

template <class Event>
void ObjectCountEventSender::send(const KlassInfoEntry* entry, const Ticks& timestamp) {
Klass* klass = entry->klass();
jlong count = entry->count();
julong total_size = entry->words() * BytesPerWord;

send_event_if_enabled<Event>(klass, count, total_size, timestamp);
// If sending ObjectCountAfterGCEvent, check if ObjectCount is enabled and send event data to ObjectCount
// If sending ObjectCountEvent, do not send send ObjectCountAfterGCEvent
if (std::is_same<Event, EventObjectCountAfterGC>::value && ObjectCountEventSender::should_send_event<EventObjectCount>()) {
send_event_if_enabled<EventObjectCount>(klass, count, total_size, timestamp);
}
}

#endif // INCLUDE_SERVICES

#endif // SHARE_GC_SHARED_OBJECTCOUNTEVENTSENDER_INLINE_HPP
26 changes: 25 additions & 1 deletion src/hotspot/share/gc/shenandoah/shenandoahClosures.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "code/nmethod.hpp"
#include "gc/shared/stringdedup/stringDedup.hpp"
#include "gc/shenandoah/shenandoahGenerationType.hpp"
#include "gc/shenandoah/shenandoahObjectCountClosure.hpp"
#include "gc/shenandoah/shenandoahTaskqueue.hpp"
#include "memory/iterator.hpp"
#include "runtime/javaThread.hpp"
Expand Down Expand Up @@ -73,7 +74,8 @@ class ShenandoahMarkRefsSuperClosure : public ShenandoahSuperClosure {

protected:
template <class T, ShenandoahGenerationType GENERATION>
void work(T *p);
// Return true if object was not previously marked by another thread
bool work(T *p);

public:
inline ShenandoahMarkRefsSuperClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old_q);
Expand Down Expand Up @@ -106,6 +108,28 @@ class ShenandoahMarkRefsClosure : public ShenandoahMarkRefsSuperClosure {
virtual void do_oop(oop* p) { do_oop_work(p); }
};

template <ShenandoahGenerationType GENERATION>
class ShenandoahMarkRefsAndCountClosure : public ShenandoahMarkRefsSuperClosure {
private:
ShenandoahObjectCountClosure* _count;

template <class T>
inline void do_oop_work(T* p) {
// Count newly marked strong references to avoid double counting
bool newly_marked = work<T, GENERATION>(p);
if (newly_marked) {
_count->do_oop(p);
}
}

public:
ShenandoahMarkRefsAndCountClosure(ShenandoahObjToScanQueue* q, ShenandoahReferenceProcessor* rp, ShenandoahObjToScanQueue* old_q, ShenandoahObjectCountClosure* count) :
ShenandoahMarkRefsSuperClosure(q, rp, old_q), _count(count) {};

virtual void do_oop(narrowOop* p) { do_oop_work(p); }
virtual void do_oop(oop* p) { do_oop_work(p); }
};

class ShenandoahForwardedIsAliveClosure : public BoolObjectClosure {
private:
ShenandoahMarkingContext* const _mark_context;
Expand Down
4 changes: 2 additions & 2 deletions src/hotspot/share/gc/shenandoah/shenandoahClosures.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ ShenandoahMarkRefsSuperClosure::ShenandoahMarkRefsSuperClosure(ShenandoahObjToSc
_weak(false) {}

template<class T, ShenandoahGenerationType GENERATION>
inline void ShenandoahMarkRefsSuperClosure::work(T* p) {
ShenandoahMark::mark_through_ref<T, GENERATION>(p, _queue, _old_queue, _mark_context, _weak);
inline bool ShenandoahMarkRefsSuperClosure::work(T* p) {
return ShenandoahMark::mark_through_ref<T, GENERATION>(p, _queue, _old_queue, _mark_context, _weak);
}

ShenandoahForwardedIsAliveClosure::ShenandoahForwardedIsAliveClosure() :
Expand Down
5 changes: 5 additions & 0 deletions src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "gc/shared/barrierSetNMethod.hpp"
#include "gc/shared/collectorCounters.hpp"
#include "gc/shared/continuationGCSupport.inline.hpp"
#include "gc/shared/gcTrace.inline.hpp"
#include "gc/shenandoah/shenandoahBreakpoint.hpp"
#include "gc/shenandoah/shenandoahClosures.inline.hpp"
#include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
Expand Down Expand Up @@ -314,6 +315,10 @@ void ShenandoahConcurrentGC::vmop_entry_final_mark() {
heap->try_inject_alloc_failure();
VM_ShenandoahFinalMarkStartEvac op(this);
VMThread::execute(&op); // jump to entry_final_mark under safepoint

// Do not report object count during a safepoint
assert(!ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should not be at safepoint");
heap->tracer()->report_object_count(heap);
}

void ShenandoahConcurrentGC::vmop_entry_init_update_refs() {
Expand Down
Loading
Loading