Skip to content

Commit 82289f6

Browse files
committed
8365611: Use lookup table for JfrEventThrottler
Reviewed-by: mgronlun
1 parent 1ff73cb commit 82289f6

File tree

2 files changed

+65
-45
lines changed

2 files changed

+65
-45
lines changed

src/hotspot/share/jfr/recorder/service/jfrEventThrottler.cpp

Lines changed: 60 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525

2626
#include "jfr/recorder/service/jfrEventThrottler.hpp"
2727
#include "jfr/utilities/jfrSpinlockHelper.hpp"
28+
#include "jfrfiles/jfrEventIds.hpp"
2829
#include "logging/log.hpp"
30+
#include "utilities/debug.hpp"
31+
#include "utilities/globalDefinitions.hpp"
2932

3033
constexpr static const JfrSamplerParams _disabled_params = {
3134
0, // sample points per window
@@ -34,9 +37,44 @@ constexpr static const JfrSamplerParams _disabled_params = {
3437
false // reconfigure
3538
};
3639

37-
static JfrEventThrottler* _disabled_cpu_time_sample_throttler = nullptr;
38-
static JfrEventThrottler* _object_allocation_throttler = nullptr;
39-
static JfrEventThrottler* _safepoint_latency_throttler = nullptr;
40+
constexpr static const JfrEventId throttleble_events[] = {
41+
JfrCPUTimeSampleEvent, JfrObjectAllocationSampleEvent, JfrSafepointLatencyEvent
42+
};
43+
constexpr static int num_throttled_events = sizeof(throttleble_events) / sizeof(throttleble_events[0]);
44+
45+
// Throttler-by-ID lookup table
46+
class ThrottlerLookupTable {
47+
static constexpr int max = (int)LAST_EVENT_ID;
48+
STATIC_ASSERT(max < 1000); // should this ever get unreasonably large, we rethink this table.
49+
JfrEventThrottler* _table[max];
50+
public:
51+
ThrottlerLookupTable() { memset(_table, 0, sizeof(_table)); }
52+
53+
bool initialize() {
54+
for (int i = 0; i < num_throttled_events; i++) {
55+
const JfrEventId id = throttleble_events[i];
56+
JfrEventThrottler* p = JfrEventThrottler::create_throttler(id);
57+
_table[(int)id] = p;
58+
if (p == nullptr) {
59+
return false;
60+
}
61+
}
62+
return true;
63+
}
64+
65+
void destroy() {
66+
for (int i = 0; i < max; i++) {
67+
delete _table[i];
68+
_table[i] = nullptr;
69+
}
70+
}
71+
72+
JfrEventThrottler* at(JfrEventId id) const {
73+
return _table[(int)id];
74+
}
75+
};
76+
77+
static ThrottlerLookupTable _throttler_table;
4078

4179
JfrEventThrottler::JfrEventThrottler(JfrEventId event_id) :
4280
JfrAdaptiveSampler(),
@@ -49,58 +87,36 @@ JfrEventThrottler::JfrEventThrottler(JfrEventId event_id) :
4987
_update(false) {}
5088

5189
bool JfrEventThrottler::create() {
52-
assert(_disabled_cpu_time_sample_throttler == nullptr, "invariant");
53-
_disabled_cpu_time_sample_throttler = new JfrEventThrottler(JfrCPUTimeSampleEvent);
54-
_disabled_cpu_time_sample_throttler->_disabled = true;
55-
assert(_object_allocation_throttler == nullptr, "invariant");
56-
_object_allocation_throttler = new JfrEventThrottler(JfrObjectAllocationSampleEvent);
57-
if (_object_allocation_throttler == nullptr || !_object_allocation_throttler->initialize()) {
58-
return false;
90+
bool rc = _throttler_table.initialize();
91+
if (rc) {
92+
_throttler_table.at(JfrCPUTimeSampleEvent)->_disabled = true; // CPU time sampler disabled
5993
}
60-
assert(_safepoint_latency_throttler == nullptr, "invariant");
61-
_safepoint_latency_throttler = new JfrEventThrottler(JfrSafepointLatencyEvent);
62-
return _safepoint_latency_throttler != nullptr && _safepoint_latency_throttler->initialize();
94+
return rc;
6395
}
6496

6597
void JfrEventThrottler::destroy() {
66-
delete _disabled_cpu_time_sample_throttler;
67-
_disabled_cpu_time_sample_throttler = nullptr;
68-
delete _object_allocation_throttler;
69-
_object_allocation_throttler = nullptr;
70-
delete _safepoint_latency_throttler;
71-
_safepoint_latency_throttler = nullptr;
98+
_throttler_table.destroy();
7299
}
73100

74-
// There is currently only two throttler instances, one for the jdk.ObjectAllocationSample event
75-
// and another for the SamplingLatency event.
76-
// When introducing many more throttlers, consider adding a lookup map keyed by event id.
77101
JfrEventThrottler* JfrEventThrottler::for_event(JfrEventId event_id) {
78-
assert(_disabled_cpu_time_sample_throttler != nullptr, "Disabled CPU time throttler has not been properly initialized");
79-
assert(_object_allocation_throttler != nullptr, "ObjectAllocation throttler has not been properly initialized");
80-
assert(_safepoint_latency_throttler != nullptr, "SafepointLatency throttler has not been properly initialized");
81-
assert(event_id == JfrObjectAllocationSampleEvent || event_id == JfrSafepointLatencyEvent || event_id == JfrCPUTimeSampleEvent, "Event type has an unconfigured throttler");
82-
if (event_id == JfrObjectAllocationSampleEvent) {
83-
return _object_allocation_throttler;
84-
}
85-
if (event_id == JfrSafepointLatencyEvent) {
86-
return _safepoint_latency_throttler;
87-
}
88-
if (event_id == JfrCPUTimeSampleEvent) {
89-
return _disabled_cpu_time_sample_throttler;
90-
}
91-
return nullptr;
102+
JfrEventThrottler* const throttler = _throttler_table.at(event_id);
103+
assert(throttler != nullptr, "Event type %d has an unconfigured throttler", (int)event_id);
104+
return throttler;
92105
}
93106

94107
void JfrEventThrottler::configure(JfrEventId event_id, int64_t sample_size, int64_t period_ms) {
95-
if (event_id == JfrObjectAllocationSampleEvent) {
96-
assert(_object_allocation_throttler != nullptr, "ObjectAllocation throttler has not been properly initialized");
97-
_object_allocation_throttler->configure(sample_size, period_ms);
98-
return;
99-
}
100-
if (event_id == JfrSafepointLatencyEvent) {
101-
assert(_safepoint_latency_throttler != nullptr, "SafepointLatency throttler has not been properly initialized");
102-
_safepoint_latency_throttler->configure(sample_size, period_ms);
108+
JfrEventThrottler* const throttler = _throttler_table.at(event_id);
109+
assert(throttler != nullptr, "Event type %d has an unconfigured throttler", (int)event_id);
110+
throttler->configure(sample_size, period_ms);
111+
}
112+
113+
JfrEventThrottler* JfrEventThrottler::create_throttler(JfrEventId id) {
114+
JfrEventThrottler* p = new JfrEventThrottler(id);
115+
if (p != nullptr && p->initialize() == false) {
116+
delete p;
117+
p = nullptr;
103118
}
119+
return p;
104120
}
105121

106122
/*

src/hotspot/share/jfr/recorder/service/jfrEventThrottler.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
33
* Copyright (c) 2020, Datadog, Inc. All rights reserved.
44
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
55
*
@@ -29,8 +29,11 @@
2929
#include "jfr/support/jfrAdaptiveSampler.hpp"
3030
#include "jfrfiles/jfrEventIds.hpp"
3131

32+
class ThrottlerLookupTable;
33+
3234
class JfrEventThrottler : public JfrAdaptiveSampler {
3335
friend class JfrRecorder;
36+
friend class ThrottlerLookupTable;
3437
private:
3538
JfrSamplerParams _last_params;
3639
int64_t _sample_size;
@@ -43,6 +46,7 @@ class JfrEventThrottler : public JfrAdaptiveSampler {
4346
static bool create();
4447
static void destroy();
4548
JfrEventThrottler(JfrEventId event_id);
49+
static JfrEventThrottler* create_throttler(JfrEventId event_id);
4650
void configure(int64_t event_sample_size, int64_t period_ms);
4751

4852
const JfrSamplerParams& update_params(const JfrSamplerWindow* expired);

0 commit comments

Comments
 (0)