Skip to content
This repository was archived by the owner on Aug 27, 2022. It is now read-only.
/ lanai Public archive

Commit f9e00a2

Browse files
committedAug 5, 2020
8235573: Move JFR ObjectSample oop into OopStorage
Reviewed-by: mgronlun, dholmes, kbarrett
1 parent ceb4ae8 commit f9e00a2

19 files changed

+115
-134
lines changed
 

‎src/hotspot/share/gc/shared/oopStorageSet.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class OopStorageSet : public AllStatic {
3838
public:
3939
// Must be updated when new OopStorages are introduced
4040
static const uint strong_count = 2;
41-
static const uint weak_count = 4;
41+
static const uint weak_count = 4 JFR_ONLY(+ 1);
4242
static const uint all_count = strong_count + weak_count;
4343

4444
private:

‎src/hotspot/share/gc/shared/weakProcessorPhases.cpp

+2-8
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,15 @@
2727
#include "utilities/debug.hpp"
2828
#include "utilities/macros.hpp"
2929

30-
#if INCLUDE_JFR
31-
#include "jfr/jfr.hpp"
32-
#endif // INCLUDE_JFR
33-
3430
#if INCLUDE_JVMTI
3531
#include "prims/jvmtiExport.hpp"
3632
#endif // INCLUDE_JVMTI
3733

38-
// serial_phase_count is 0 if JFR and JVMTI are both not built,
34+
// serial_phase_count is 0 if JVMTI is not built,
3935
// requiring some code to be careful to avoid tautological checks
4036
// that some compilers warn about.
4137

42-
#define HAVE_SERIAL_PHASES (INCLUDE_JVMTI || INCLUDE_JFR)
38+
#define HAVE_SERIAL_PHASES INCLUDE_JVMTI
4339

4440
WeakProcessorPhases::Phase WeakProcessorPhases::serial_phase(uint value) {
4541
#if HAVE_SERIAL_PHASES
@@ -109,7 +105,6 @@ void WeakProcessorPhases::Iterator::verify_dereferenceable() const {
109105
const char* WeakProcessorPhases::description(Phase phase) {
110106
switch (phase) {
111107
JVMTI_ONLY(case jvmti: return "JVMTI weak processing";)
112-
JFR_ONLY(case jfr: return "JFR weak processing";)
113108
default:
114109
ShouldNotReachHere();
115110
return "Invalid serial weak processing phase";
@@ -119,7 +114,6 @@ const char* WeakProcessorPhases::description(Phase phase) {
119114
WeakProcessorPhases::Processor WeakProcessorPhases::processor(Phase phase) {
120115
switch (phase) {
121116
JVMTI_ONLY(case jvmti: return &JvmtiExport::weak_oops_do;)
122-
JFR_ONLY(case jfr: return &Jfr::weak_oops_do;)
123117
default:
124118
ShouldNotReachHere();
125119
return NULL;

‎src/hotspot/share/gc/shared/weakProcessorPhases.hpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,14 @@ class WeakProcessorPhases : AllStatic {
4141
typedef void (*Processor)(BoolObjectClosure*, OopClosure*);
4242

4343
enum Phase {
44-
// Serial phases.
45-
JVMTI_ONLY(jvmti JFR_ONLY(COMMA))
46-
JFR_ONLY(jfr)
44+
// Serial phase.
45+
JVMTI_ONLY(jvmti)
4746

4847
// Additional implicit phase values follow for oopstorages.
4948
};
5049

5150
static const uint serial_phase_start = 0;
52-
static const uint serial_phase_count = 0 JVMTI_ONLY(+ 1) JFR_ONLY(+ 1);
51+
static const uint serial_phase_count = 0 JVMTI_ONLY(+ 1);
5352
static const uint oopstorage_phase_start = serial_phase_count;
5453
static const uint oopstorage_phase_count = OopStorageSet::weak_count;
5554
static const uint phase_count = serial_phase_count + oopstorage_phase_count;

‎src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.hpp

-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP
2626
#define SHARE_GC_SHENANDOAH_SHENANDOAHPHASETIMINGS_HPP
2727

28-
#include "jfr/jfrEvents.hpp"
2928
#include "gc/shenandoah/shenandoahNumberSeq.hpp"
3029
#include "gc/shared/workerDataArray.hpp"
3130
#include "memory/allocation.hpp"
@@ -43,7 +42,6 @@ class outputStream;
4342
f(CNT_PREFIX ## ObjectSynchronizerRoots, DESC_PREFIX "Synchronizer Roots") \
4443
f(CNT_PREFIX ## CLDGRoots, DESC_PREFIX "CLDG Roots") \
4544
f(CNT_PREFIX ## JVMTIWeakRoots, DESC_PREFIX "JVMTI Weak Roots") \
46-
f(CNT_PREFIX ## JFRWeakRoots, DESC_PREFIX "JFR Weak Roots") \
4745
f(CNT_PREFIX ## StringDedupTableRoots, DESC_PREFIX "Dedup Table Roots") \
4846
f(CNT_PREFIX ## StringDedupQueueRoots, DESC_PREFIX "Dedup Queue Roots") \
4947
f(CNT_PREFIX ## FinishQueues, DESC_PREFIX "Finish Queues") \

‎src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
#include "gc/shenandoah/shenandoahPhaseTimings.hpp"
3636
#include "gc/shenandoah/shenandoahStringDedup.hpp"
3737
#include "gc/shenandoah/shenandoahVMOperations.hpp"
38-
#include "jfr/jfr.hpp"
3938
#include "memory/iterator.hpp"
4039
#include "memory/resourceArea.hpp"
4140
#include "memory/universe.hpp"
@@ -81,15 +80,8 @@ ShenandoahJVMTIWeakRoot::ShenandoahJVMTIWeakRoot(ShenandoahPhaseTimings::Phase p
8180
}
8281
#endif // INCLUDE_JVMTI
8382

84-
#if INCLUDE_JFR
85-
ShenandoahJFRWeakRoot::ShenandoahJFRWeakRoot(ShenandoahPhaseTimings::Phase phase) :
86-
ShenandoahWeakSerialRoot(&Jfr::weak_oops_do, phase, ShenandoahPhaseTimings::JFRWeakRoots) {
87-
}
88-
#endif // INCLUDE_JFR
89-
9083
void ShenandoahSerialWeakRoots::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id) {
9184
JVMTI_ONLY(_jvmti_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);)
92-
JFR_ONLY(_jfr_weak_roots.weak_oops_do(is_alive, keep_alive, worker_id);)
9385
}
9486

9587
void ShenandoahSerialWeakRoots::weak_oops_do(OopClosure* cl, uint worker_id) {

‎src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.hpp

-9
Original file line numberDiff line numberDiff line change
@@ -79,21 +79,12 @@ class ShenandoahJVMTIWeakRoot : public ShenandoahWeakSerialRoot {
7979
};
8080
#endif // INCLUDE_JVMTI
8181

82-
#if INCLUDE_JFR
83-
class ShenandoahJFRWeakRoot : public ShenandoahWeakSerialRoot {
84-
public:
85-
ShenandoahJFRWeakRoot(ShenandoahPhaseTimings::Phase phase);
86-
};
87-
#endif // INCLUDE_JFR
88-
8982
class ShenandoahSerialWeakRoots {
9083
private:
9184
JVMTI_ONLY(ShenandoahJVMTIWeakRoot _jvmti_weak_roots;)
92-
JFR_ONLY(ShenandoahJFRWeakRoot _jfr_weak_roots;)
9385
public:
9486
ShenandoahSerialWeakRoots(ShenandoahPhaseTimings::Phase phase)
9587
JVMTI_ONLY(: _jvmti_weak_roots(phase))
96-
JFR_ONLY(NOT_JVMTI(:) JVMTI_ONLY(COMMA) _jfr_weak_roots(phase))
9788
{};
9889

9990
void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, uint worker_id);

‎src/hotspot/share/gc/z/zRootsIterator.cpp

+1-14
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,6 @@
5050
#include "runtime/thread.hpp"
5151
#include "runtime/vmThread.hpp"
5252
#include "utilities/debug.hpp"
53-
#if INCLUDE_JFR
54-
#include "jfr/jfr.hpp"
55-
#endif
5653

5754
static const ZStatSubPhase ZSubPhasePauseRootsSetup("Pause Roots Setup");
5855
static const ZStatSubPhase ZSubPhasePauseRoots("Pause Roots");
@@ -74,7 +71,6 @@ static const ZStatSubPhase ZSubPhasePauseWeakRootsSetup("Pause Weak Roots Setup"
7471
static const ZStatSubPhase ZSubPhasePauseWeakRoots("Pause Weak Roots");
7572
static const ZStatSubPhase ZSubPhasePauseWeakRootsTeardown("Pause Weak Roots Teardown");
7673
static const ZStatSubPhase ZSubPhasePauseWeakRootsJVMTIWeakExport("Pause Weak Roots JVMTIWeakExport");
77-
static const ZStatSubPhase ZSubPhasePauseWeakRootsJFRWeak("Pause Weak Roots JFRWeak");
7874

7975
static const ZStatSubPhase ZSubPhaseConcurrentWeakRoots("Concurrent Weak Roots");
8076
static const ZStatSubPhase ZSubPhaseConcurrentWeakRootsOopStorageSet("Concurrent Weak Roots OopStorageSet");
@@ -295,8 +291,7 @@ void ZConcurrentRootsIterator::oops_do(ZRootsIteratorClosure* cl) {
295291
}
296292

297293
ZWeakRootsIterator::ZWeakRootsIterator() :
298-
_jvmti_weak_export(this),
299-
_jfr_weak(this) {
294+
_jvmti_weak_export(this) {
300295
assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
301296
ZStatTimer timer(ZSubPhasePauseWeakRootsSetup);
302297
}
@@ -310,17 +305,9 @@ void ZWeakRootsIterator::do_jvmti_weak_export(BoolObjectClosure* is_alive, ZRoot
310305
JvmtiExport::weak_oops_do(is_alive, cl);
311306
}
312307

313-
void ZWeakRootsIterator::do_jfr_weak(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) {
314-
#if INCLUDE_JFR
315-
ZStatTimer timer(ZSubPhasePauseWeakRootsJFRWeak);
316-
Jfr::weak_oops_do(is_alive, cl);
317-
#endif
318-
}
319-
320308
void ZWeakRootsIterator::weak_oops_do(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl) {
321309
ZStatTimer timer(ZSubPhasePauseWeakRoots);
322310
_jvmti_weak_export.weak_oops_do(is_alive, cl);
323-
_jfr_weak.weak_oops_do(is_alive, cl);
324311
}
325312

326313
void ZWeakRootsIterator::oops_do(ZRootsIteratorClosure* cl) {

‎src/hotspot/share/gc/z/zRootsIterator.hpp

-2
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,8 @@ class ZConcurrentRootsIteratorClaimNone : public ZConcurrentRootsIterator {
170170
class ZWeakRootsIterator {
171171
private:
172172
void do_jvmti_weak_export(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl);
173-
void do_jfr_weak(BoolObjectClosure* is_alive, ZRootsIteratorClosure* cl);
174173

175174
ZSerialWeakOopsDo<ZWeakRootsIterator, &ZWeakRootsIterator::do_jvmti_weak_export> _jvmti_weak_export;
176-
ZSerialWeakOopsDo<ZWeakRootsIterator, &ZWeakRootsIterator::do_jfr_weak> _jfr_weak;
177175

178176
public:
179177
ZWeakRootsIterator();

‎src/hotspot/share/jfr/jfr.cpp

-6
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,6 @@ void Jfr::on_vm_error_report(outputStream* st) {
102102
}
103103
}
104104

105-
void Jfr::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
106-
if (LeakProfiler::is_running()) {
107-
LeakProfiler::weak_oops_do(is_alive, f);
108-
}
109-
}
110-
111105
bool Jfr::on_flight_recorder_option(const JavaVMOption** option, char* delimiter) {
112106
return JfrOptionSet::parse_flight_recorder_option(option, delimiter);
113107
}

‎src/hotspot/share/jfr/jfr.hpp

-3
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@
2828
#include "jni.h"
2929
#include "memory/allocation.hpp"
3030

31-
class BoolObjectClosure;
3231
class JavaThread;
33-
class OopClosure;
3432
class Thread;
3533

3634
extern "C" void JNICALL jfr_register_natives(JNIEnv*, jclass);
@@ -53,7 +51,6 @@ class Jfr : AllStatic {
5351
static bool on_flight_recorder_option(const JavaVMOption** option, char* delimiter);
5452
static bool on_start_flight_recording_option(const JavaVMOption** option, char* delimiter);
5553
static void on_vm_error_report(outputStream* st);
56-
static void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f);
5754
static void exclude_thread(Thread* thread);
5855
static bool is_excluded(Thread* thread);
5956
static void include_thread(Thread* thread);

‎src/hotspot/share/jfr/leakprofiler/leakProfiler.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,6 @@ void LeakProfiler::emit_events(int64_t cutoff_ticks, bool emit_all, bool skip_bf
8989
ObjectSampler::release();
9090
}
9191

92-
void LeakProfiler::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
93-
assert(SafepointSynchronize::is_at_safepoint(),
94-
"Leak Profiler::oops_do(...) may only be called during safepoint");
95-
if (is_running()) {
96-
ObjectSampler::weak_oops_do(is_alive, f);
97-
}
98-
}
99-
10092
void LeakProfiler::sample(HeapWord* object, size_t size, JavaThread* thread) {
10193
assert(is_running(), "invariant");
10294
assert(thread != NULL, "invariant");

‎src/hotspot/share/jfr/leakprofiler/leakProfiler.hpp

-5
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727

2828
#include "memory/allocation.hpp"
2929

30-
class BoolObjectClosure;
31-
class OopClosure;
3230
class JavaThread;
3331

3432
class LeakProfiler : public AllStatic {
@@ -39,9 +37,6 @@ class LeakProfiler : public AllStatic {
3937

4038
static void emit_events(int64_t cutoff_ticks, bool emit_all, bool skip_bfs);
4139
static void sample(HeapWord* object, size_t size, JavaThread* thread);
42-
43-
// Called by GC
44-
static void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f);
4540
};
4641

4742
#endif // SHARE_JFR_LEAKPROFILER_LEAKPROFILER_HPP

‎src/hotspot/share/jfr/leakprofiler/sampling/objectSample.cpp

+25-5
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,36 @@
2323
*/
2424
#include "precompiled.hpp"
2525
#include "jfr/leakprofiler/sampling/objectSample.hpp"
26-
#include "oops/access.inline.hpp"
26+
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
27+
#include "oops/weakHandle.inline.hpp"
28+
#include "runtime/handles.inline.hpp"
29+
30+
void ObjectSample::reset() {
31+
release();
32+
set_stack_trace_id(0);
33+
set_stack_trace_hash(0);
34+
release_references();
35+
}
2736

2837
const oop ObjectSample::object() const {
29-
return NativeAccess<ON_PHANTOM_OOP_REF | AS_NO_KEEPALIVE>::oop_load(&_object);
38+
return _object.resolve();
39+
}
40+
41+
bool ObjectSample::is_dead() const {
42+
return _object.peek() == NULL;
3043
}
3144

32-
const oop ObjectSample::object_raw() const {
33-
return RawAccess<>::oop_load(&_object);
45+
const oop* ObjectSample::object_addr() const {
46+
return _object.ptr_raw();
3447
}
3548

3649
void ObjectSample::set_object(oop object) {
37-
NativeAccess<ON_PHANTOM_OOP_REF>::oop_store(&_object, object);
50+
assert(_object.is_empty(), "should be empty");
51+
Handle h(Thread::current(), object);
52+
_object = WeakHandle(ObjectSampler::oop_storage(), h);
53+
}
54+
55+
void ObjectSample::release() {
56+
_object.release(ObjectSampler::oop_storage());
57+
_object = WeakHandle();
3858
}

‎src/hotspot/share/jfr/leakprofiler/sampling/objectSample.hpp

+7-15
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "jfr/utilities/jfrTypes.hpp"
3232
#include "memory/allocation.hpp"
3333
#include "oops/oop.hpp"
34+
#include "oops/weakHandle.hpp"
3435
#include "utilities/ticks.hpp"
3536

3637
/*
@@ -48,7 +49,7 @@ class ObjectSample : public JfrCHeapObj {
4849
JfrBlobHandle _stacktrace;
4950
JfrBlobHandle _thread;
5051
JfrBlobHandle _type_set;
51-
oop _object;
52+
WeakHandle _object;
5253
Ticks _allocation_time;
5354
traceid _stack_trace_id;
5455
traceid _thread_id;
@@ -64,20 +65,14 @@ class ObjectSample : public JfrCHeapObj {
6465
_type_set.~JfrBlobHandle();
6566
}
6667

67-
void reset() {
68-
_object = NULL;
69-
set_stack_trace_id(0);
70-
set_stack_trace_hash(0);
71-
release_references();
72-
}
68+
void reset();
7369

7470
public:
7571
ObjectSample() : _next(NULL),
7672
_previous(NULL),
7773
_stacktrace(),
7874
_thread(),
7975
_type_set(),
80-
_object(NULL),
8176
_allocation_time(),
8277
_stack_trace_id(0),
8378
_thread_id(0),
@@ -103,17 +98,14 @@ class ObjectSample : public JfrCHeapObj {
10398
_previous = prev;
10499
}
105100

106-
bool is_dead() const {
107-
return object() == NULL;
108-
}
101+
bool is_dead() const;
109102

110103
const oop object() const;
111-
const oop object_raw() const;
112104
void set_object(oop object);
113105

114-
const oop* object_addr() const {
115-
return &_object;
116-
}
106+
const oop* object_addr() const;
107+
108+
void release();
117109

118110
int index() const {
119111
return _index;

‎src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp

+52-34
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
*/
2424

2525
#include "precompiled.hpp"
26+
#include "gc/shared/oopStorage.hpp"
27+
#include "gc/shared/oopStorageSet.hpp"
2628
#include "jfr/jfrEvents.hpp"
2729
#include "jfr/leakprofiler/sampling/objectSample.hpp"
2830
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
@@ -41,6 +43,40 @@
4143
#include "runtime/safepoint.hpp"
4244
#include "runtime/thread.hpp"
4345

46+
// Timestamp of when the gc last processed the set of sampled objects.
47+
static JfrTicks _last_sweep;
48+
49+
// Condition variable to communicate that some sampled objects have been cleared by the gc
50+
// and can therefore be removed from the sample priority queue.
51+
static bool volatile _dead_samples = false;
52+
53+
// The OopStorage instance is used to hold weak references to sampled objects.
54+
// It is constructed and registered during VM initialization. This is a singleton
55+
// that persist independent of the state of the ObjectSampler.
56+
static OopStorage* _oop_storage = NULL;
57+
58+
OopStorage* ObjectSampler::oop_storage() { return _oop_storage; }
59+
60+
// Callback invoked by the GC after an iteration over the oop storage
61+
// that may have cleared dead referents. num_dead is the number of entries
62+
// already NULL or cleared by the iteration.
63+
void ObjectSampler::oop_storage_gc_notification(size_t num_dead) {
64+
if (num_dead != 0) {
65+
// The ObjectSampler instance may have already been cleaned or a new
66+
// instance was created concurrently. This allows for a small race where cleaning
67+
// could be done again.
68+
Atomic::store(&_dead_samples, true);
69+
_last_sweep = JfrTicks::now();
70+
}
71+
}
72+
73+
bool ObjectSampler::create_oop_storage() {
74+
_oop_storage = OopStorageSet::create_weak("Weak JFR Old Object Samples");
75+
assert(_oop_storage != NULL, "invariant");
76+
_oop_storage->register_num_dead_callback(&oop_storage_gc_notification);
77+
return true;
78+
}
79+
4480
static ObjectSampler* _instance = NULL;
4581

4682
static ObjectSampler& instance() {
@@ -49,13 +85,14 @@ static ObjectSampler& instance() {
4985
}
5086

5187
ObjectSampler::ObjectSampler(size_t size) :
52-
_priority_queue(new SamplePriorityQueue(size)),
53-
_list(new SampleList(size)),
54-
_last_sweep(JfrTicks::now()),
55-
_total_allocated(0),
56-
_threshold(0),
57-
_size(size),
58-
_dead_samples(false) {}
88+
_priority_queue(new SamplePriorityQueue(size)),
89+
_list(new SampleList(size)),
90+
_total_allocated(0),
91+
_threshold(0),
92+
_size(size) {
93+
_last_sweep = JfrTicks::now();
94+
Atomic::store(&_dead_samples, false);
95+
}
5996

6097
ObjectSampler::~ObjectSampler() {
6198
delete _priority_queue;
@@ -66,6 +103,7 @@ ObjectSampler::~ObjectSampler() {
66103

67104
bool ObjectSampler::create(size_t size) {
68105
assert(SafepointSynchronize::is_at_safepoint(), "invariant");
106+
assert(_oop_storage != NULL, "should be already created");
69107
assert(_instance == NULL, "invariant");
70108
_instance = new ObjectSampler(size);
71109
return _instance != NULL;
@@ -92,13 +130,11 @@ void ObjectSampler::destroy() {
92130
static volatile int _lock = 0;
93131

94132
ObjectSampler* ObjectSampler::acquire() {
95-
assert(is_created(), "invariant");
96133
while (Atomic::cmpxchg(&_lock, 0, 1) == 1) {}
97134
return _instance;
98135
}
99136

100137
void ObjectSampler::release() {
101-
assert(is_created(), "invariant");
102138
OrderAccess::fence();
103139
_lock = 0;
104140
}
@@ -150,9 +186,11 @@ void ObjectSampler::add(HeapWord* obj, size_t allocated, traceid thread_id, Java
150186
assert(thread != NULL, "invariant");
151187
assert(thread->jfr_thread_local()->has_thread_blob(), "invariant");
152188

153-
if (_dead_samples) {
189+
if (Atomic::load(&_dead_samples)) {
190+
// There's a small race where a GC scan might reset this to true, potentially
191+
// causing a back-to-back scavenge.
192+
Atomic::store(&_dead_samples, false);
154193
scavenge();
155-
assert(!_dead_samples, "invariant");
156194
}
157195

158196
_total_allocated += allocated;
@@ -199,12 +237,13 @@ void ObjectSampler::scavenge() {
199237
}
200238
current = next;
201239
}
202-
_dead_samples = false;
203240
}
204241

205242
void ObjectSampler::remove_dead(ObjectSample* sample) {
206243
assert(sample != NULL, "invariant");
207244
assert(sample->is_dead(), "invariant");
245+
sample->release();
246+
208247
ObjectSample* const previous = sample->prev();
209248
// push span onto previous
210249
if (previous != NULL) {
@@ -216,27 +255,6 @@ void ObjectSampler::remove_dead(ObjectSample* sample) {
216255
_list->release(sample);
217256
}
218257

219-
void ObjectSampler::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
220-
assert(is_created(), "invariant");
221-
assert(SafepointSynchronize::is_at_safepoint(), "invariant");
222-
ObjectSampler& sampler = instance();
223-
ObjectSample* current = sampler._list->last();
224-
while (current != NULL) {
225-
if (current->_object != NULL) {
226-
if (is_alive->do_object_b(current->object_raw())) {
227-
// The weakly referenced object is alive, update pointer
228-
f->do_oop(const_cast<oop*>(current->object_addr()));
229-
} else {
230-
// clear existing field to assist GC barriers
231-
current->_object = NULL;
232-
sampler._dead_samples = true;
233-
}
234-
}
235-
current = current->next();
236-
}
237-
sampler._last_sweep = JfrTicks::now();
238-
}
239-
240258
ObjectSample* ObjectSampler::last() const {
241259
return _list->last();
242260
}
@@ -267,6 +285,6 @@ ObjectSample* ObjectSampler::item_at(int index) {
267285
);
268286
}
269287

270-
const JfrTicks& ObjectSampler::last_sweep() const {
288+
const JfrTicks& ObjectSampler::last_sweep() {
271289
return _last_sweep;
272290
}

‎src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.hpp

+10-9
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@
3030

3131
typedef u8 traceid;
3232

33-
class BoolObjectClosure;
3433
class JavaThread;
35-
class OopClosure;
34+
class OopStorage;
3635
class ObjectSample;
3736
class SampleList;
3837
class SamplePriorityQueue;
@@ -41,17 +40,17 @@ class SamplePriorityQueue;
4140
// making sure the samples are evenly distributed as
4241
// new entries are added and removed.
4342
class ObjectSampler : public CHeapObj<mtTracing> {
43+
friend class JfrRecorder;
4444
friend class LeakProfiler;
45+
friend class ObjectSample;
4546
friend class StartOperation;
4647
friend class StopOperation;
4748
private:
4849
SamplePriorityQueue* _priority_queue;
4950
SampleList* _list;
50-
JfrTicks _last_sweep;
5151
size_t _total_allocated;
5252
size_t _threshold;
5353
size_t _size;
54-
bool _dead_samples;
5554

5655
// Lifecycle
5756
explicit ObjectSampler(size_t size);
@@ -66,24 +65,26 @@ class ObjectSampler : public CHeapObj<mtTracing> {
6665
void scavenge();
6766
void remove_dead(ObjectSample* sample);
6867

69-
// Called by GC
70-
static void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f);
71-
7268
const ObjectSample* item_at(int index) const;
7369
ObjectSample* item_at(int index);
7470
int item_count() const;
7571

72+
// OopStorage
73+
static bool create_oop_storage();
74+
static OopStorage* oop_storage();
75+
// Invoked by the GC post oop storage processing.
76+
static void oop_storage_gc_notification(size_t num_dead);
77+
7678
public:
7779
static ObjectSampler* sampler();
7880
// For operations that require exclusive access (non-safepoint)
7981
static ObjectSampler* acquire();
8082
static void release();
81-
83+
static const JfrTicks& last_sweep();
8284
const ObjectSample* first() const;
8385
ObjectSample* last() const;
8486
const ObjectSample* last_resolved() const;
8587
void set_last_resolved(const ObjectSample* sample);
86-
const JfrTicks& last_sweep() const;
8788
};
8889

8990
#endif // SHARE_JFR_LEAKPROFILER_SAMPLING_OBJECTSAMPLER_HPP

‎src/hotspot/share/jfr/recorder/jfrRecorder.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "jfr/dcmd/jfrDcmds.hpp"
2828
#include "jfr/instrumentation/jfrJvmtiAgent.hpp"
2929
#include "jfr/jni/jfrJavaSupport.hpp"
30+
#include "jfr/leakprofiler/sampling/objectSampler.hpp"
3031
#include "jfr/periodic/jfrOSInterface.hpp"
3132
#include "jfr/periodic/sampling/jfrThreadSampler.hpp"
3233
#include "jfr/recorder/jfrRecorder.hpp"
@@ -73,12 +74,20 @@ bool JfrRecorder::is_enabled() {
7374
return _enabled;
7475
}
7576

77+
bool JfrRecorder::create_oop_storages() {
78+
// currently only a single weak oop storage for Leak Profiler
79+
return ObjectSampler::create_oop_storage();
80+
}
81+
7682
bool JfrRecorder::on_create_vm_1() {
7783
if (!is_disabled()) {
7884
if (FlightRecorder || StartFlightRecording != NULL) {
7985
enable();
8086
}
8187
}
88+
if (!create_oop_storages()) {
89+
return false;
90+
}
8291
// fast time initialization
8392
return JfrTime::initialize();
8493
}

‎src/hotspot/share/jfr/recorder/jfrRecorder.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class JfrRecorder : public JfrCHeapObj {
4545
static bool create_chunk_repository();
4646
static bool create_java_event_writer();
4747
static bool create_jvmti_agent();
48+
static bool create_oop_storages();
4849
static bool create_os_interface();
4950
static bool create_post_box();
5051
static bool create_recorder_thread();

‎src/hotspot/share/oops/weakHandle.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -58,6 +58,9 @@ class WeakHandle {
5858

5959
void print() const;
6060
void print_on(outputStream* st) const;
61+
62+
bool is_empty() const { return _obj == NULL; }
63+
oop* ptr_raw() const { return _obj; }
6164
};
6265

6366
#endif // SHARE_OOPS_WEAKHANDLE_HPP

0 commit comments

Comments
 (0)
This repository has been archived.