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

Commit 7d1eb8f

Browse files
committed
8246260: JFR: Write event size field without padding
Reviewed-by: jbachorik, mgronlun
1 parent 827c886 commit 7d1eb8f

File tree

13 files changed

+258
-67
lines changed

13 files changed

+258
-67
lines changed

make/src/classes/build/tools/jfr/GenerateJfrFiles.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,7 +404,8 @@ private static void printJfrEventControlHpp(Metadata metadata, TypeCounter typeC
404404
out.write(" jlong cutoff_ticks;");
405405
out.write(" u1 stacktrace;");
406406
out.write(" u1 enabled;");
407-
out.write(" u1 pad[6]; // Because GCC on linux ia32 at least tries to pack this.");
407+
out.write(" u1 large;");
408+
out.write(" u1 pad[5]; // Because GCC on linux ia32 at least tries to pack this.");
408409
out.write("};");
409410
out.write("");
410411
out.write("union JfrNativeSettings {");

src/hotspot/share/jfr/recorder/jfrEventSetting.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ void JfrEventSetting::set_enabled(jlong id, bool enabled) {
5353
setting(event_id).enabled = enabled;
5454
}
5555

56+
void JfrEventSetting::set_large(JfrEventId event_id) {
57+
assert(bounds_check_event(event_id), "invariant");
58+
setting(event_id).large = true;
59+
}
60+
5661
#ifdef ASSERT
5762
bool JfrEventSetting::bounds_check_event(jlong id) {
5863
if ((unsigned)id < FIRST_EVENT_ID) {

src/hotspot/share/jfr/recorder/jfrEventSetting.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 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
@@ -46,6 +46,9 @@ class JfrEventSetting : AllStatic {
4646
static jlong threshold(JfrEventId event_id);
4747
static bool set_cutoff(jlong event_id, jlong cutoff_ticks);
4848
static jlong cutoff(JfrEventId event_id);
49+
static bool is_large(JfrEventId event_id);
50+
static void set_large(JfrEventId event_id);
51+
4952
DEBUG_ONLY(static bool bounds_check_event(jlong id);)
5053
};
5154

src/hotspot/share/jfr/recorder/jfrEventSetting.inline.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 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
@@ -47,4 +47,7 @@ inline jlong JfrEventSetting::cutoff(JfrEventId event_id) {
4747
return setting(event_id).cutoff_ticks;
4848
}
4949

50+
inline bool JfrEventSetting::is_large(JfrEventId event_id) {
51+
return setting(event_id).large != 0;
52+
}
5053
#endif // SHARE_JFR_RECORDER_JFREVENTSETTING_INLINE_HPP

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ class JfrEvent {
119119
return JfrEventSetting::has_stacktrace(T::eventId);
120120
}
121121

122+
static bool is_large() {
123+
return JfrEventSetting::is_large(T::eventId);
124+
}
125+
126+
static void set_large() {
127+
JfrEventSetting::set_large(T::eventId);
128+
}
129+
122130
static JfrEventId id() {
123131
return T::eventId;
124132
}
@@ -160,7 +168,23 @@ class JfrEvent {
160168
// most likely a pending OOM
161169
return;
162170
}
171+
bool large = is_large();
172+
if (write_sized_event(buffer, event_thread, tl, large)) {
173+
// Event written succesfully
174+
return;
175+
}
176+
if (!large) {
177+
// Try large size
178+
if (write_sized_event(buffer, event_thread, tl, true)) {
179+
// Event written succesfully, use large size from now on
180+
set_large();
181+
}
182+
}
183+
}
184+
185+
bool write_sized_event(JfrBuffer* const buffer, Thread* const event_thread, JfrThreadLocal* const tl, bool large_size) {
163186
JfrNativeEventWriter writer(buffer, event_thread);
187+
writer.begin_event_write(large_size);
164188
writer.write<u8>(T::eventId);
165189
assert(_start_time != 0, "invariant");
166190
writer.write(_start_time);
@@ -184,6 +208,7 @@ class JfrEvent {
184208
}
185209
// payload
186210
static_cast<T*>(this)->writeData(writer);
211+
return writer.end_event_write(large_size) > 0;
187212
}
188213

189214
#ifdef ASSERT

src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 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
@@ -224,10 +224,12 @@ static void write_data_loss_event(JfrBuffer* buffer, u8 unflushed_size, Thread*
224224
const u8 total_data_loss = thread->jfr_thread_local()->add_data_lost(unflushed_size);
225225
if (EventDataLoss::is_enabled()) {
226226
JfrNativeEventWriter writer(buffer, thread);
227+
writer.begin_event_write(false);
227228
writer.write<u8>(EventDataLoss::eventId);
228229
writer.write(JfrTicks::now());
229230
writer.write(unflushed_size);
230231
writer.write(total_data_loss);
232+
writer.end_event_write(false);
231233
}
232234
}
233235

src/hotspot/share/jfr/writers/jfrEventWriterHost.hpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 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
@@ -35,17 +35,8 @@ class EventWriterHost : public WriterHost<BE, IE, WriterPolicyImpl> {
3535
EventWriterHost(Thread* thread);
3636
void begin_write();
3737
intptr_t end_write();
38-
void begin_event_write();
39-
intptr_t end_event_write();
40-
};
41-
42-
template <typename BE, typename IE, typename WriterPolicyImpl >
43-
class StackEventWriterHost : public EventWriterHost<BE, IE, WriterPolicyImpl> {
44-
public:
45-
template <typename StorageType>
46-
StackEventWriterHost(StorageType* storage, Thread* thread);
47-
StackEventWriterHost(Thread* thread);
48-
~StackEventWriterHost();
38+
void begin_event_write(bool large);
39+
intptr_t end_event_write(bool large);
4940
};
5041

5142
#endif // SHARE_JFR_WRITERS_JFREVENTWRITERHOST_HPP

src/hotspot/share/jfr/writers/jfrEventWriterHost.inline.hpp

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 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
@@ -33,7 +33,7 @@ inline EventWriterHost<BE, IE, WriterPolicyImpl>::
3333
EventWriterHost(StorageType* storage, Thread* thread) : WriterHost<BE, IE, WriterPolicyImpl>(storage, thread) {}
3434

3535
template <typename BE, typename IE, typename WriterPolicyImpl>
36-
inline EventWriterHost<BE, IE, WriterPolicyImpl>::EventWriterHost(Thread* thread) : WriterHost<BE, IE, WriterPolicyImpl>(thread) {
36+
inline EventWriterHost<BE, IE, WriterPolicyImpl>::EventWriterHost(Thread* thread) : WriterHost<BE, IE, WriterPolicyImpl>(thread) {
3737
}
3838

3939
template <typename BE, typename IE, typename WriterPolicyImpl>
@@ -53,45 +53,47 @@ inline intptr_t EventWriterHost<BE, IE, WriterPolicyImpl>::end_write(void) {
5353
}
5454

5555
template <typename BE, typename IE, typename WriterPolicyImpl>
56-
inline void EventWriterHost<BE, IE, WriterPolicyImpl>::begin_event_write() {
56+
inline void EventWriterHost<BE, IE, WriterPolicyImpl>::begin_event_write(bool large) {
5757
assert(this->is_valid(), "invariant");
5858
assert(!this->is_acquired(), "calling begin with writer already in acquired state!");
5959
this->begin_write();
60-
this->reserve(sizeof(u4)); // reserve the event size slot
60+
// reserve the event size slot
61+
if (large) {
62+
this->reserve(sizeof(u4));
63+
} else {
64+
this->reserve(sizeof(u1));
65+
}
6166
}
6267

6368
template <typename BE, typename IE, typename WriterPolicyImpl>
64-
inline intptr_t EventWriterHost<BE, IE, WriterPolicyImpl>::end_event_write() {
69+
inline intptr_t EventWriterHost<BE, IE, WriterPolicyImpl>::end_event_write(bool large) {
6570
assert(this->is_acquired(), "invariant");
6671
if (!this->is_valid()) {
6772
this->release();
6873
return 0;
6974
}
70-
const u4 written = (u4)end_write();
71-
if (written > sizeof(u4)) { // larger than header reserve
72-
this->write_padded_at_offset(written, 0);
73-
this->commit();
75+
u4 written = (u4)end_write();
76+
if (large) {
77+
// size written is larger than header reserve, so commit
78+
if (written > sizeof(u4)) {
79+
this->write_padded_at_offset(written, 0);
80+
this->commit();
81+
}
82+
} else {
83+
// abort if event size will not fit in one byte (compressed)
84+
if (written > 127) {
85+
this->reset();
86+
written = 0;
87+
} else {
88+
// size written is larger than header reserve, so commit
89+
if (written > sizeof(u1)) {
90+
this->write_at_offset(written, 0);
91+
this->commit();
92+
}
93+
}
7494
}
7595
this->release();
7696
assert(!this->is_acquired(), "invariant");
7797
return written;
7898
}
79-
80-
template <typename BE, typename IE, typename WriterPolicyImpl>
81-
template <typename StorageType>
82-
inline StackEventWriterHost<BE, IE, WriterPolicyImpl>::
83-
StackEventWriterHost(StorageType* storage, Thread* thread) : EventWriterHost<BE, IE, WriterPolicyImpl>(storage, thread) {
84-
this->begin_event_write();
85-
}
86-
87-
template <typename BE, typename IE, typename WriterPolicyImpl>
88-
inline StackEventWriterHost<BE, IE, WriterPolicyImpl>::StackEventWriterHost(Thread* thread) : EventWriterHost<BE, IE, WriterPolicyImpl>(thread) {
89-
this->begin_event_write();
90-
}
91-
92-
template <typename BE, typename IE, typename WriterPolicyImpl>
93-
inline StackEventWriterHost<BE, IE, WriterPolicyImpl>::~StackEventWriterHost() {
94-
this->end_event_write();
95-
}
96-
9799
#endif // SHARE_JFR_WRITERS_JFREVENTWRITERHOST_INLINE_HPP

src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 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
@@ -44,7 +44,6 @@ static int start_pos_offset = invalid_offset;
4444
static int start_pos_address_offset = invalid_offset;
4545
static int current_pos_offset = invalid_offset;
4646
static int max_pos_offset = invalid_offset;
47-
static int max_event_size_offset = invalid_offset;
4847
static int notified_offset = invalid_offset;
4948
static int thread_id_offset = invalid_offset;
5049
static int valid_offset = invalid_offset;
@@ -110,13 +109,6 @@ static bool setup_event_writer_offsets(TRAPS) {
110109
compute_offset(max_pos_offset, klass, max_pos_sym, vmSymbols::long_signature());
111110
assert(max_pos_offset != invalid_offset, "invariant");
112111

113-
const char max_event_size_name[] = "maxEventSize";
114-
Symbol* const max_event_size_sym = SymbolTable::new_symbol(max_event_size_name);
115-
assert (max_event_size_sym != NULL, "invariant");
116-
assert(invalid_offset == max_event_size_offset, "invariant");
117-
compute_offset(max_event_size_offset, klass, max_event_size_sym, vmSymbols::int_signature());
118-
assert(max_event_size_offset != invalid_offset, "invariant");
119-
120112
const char notified_name[] = "notified";
121113
Symbol* const notified_sym = SymbolTable::new_symbol(notified_name);
122114
assert (notified_sym != NULL, "invariant");

src/hotspot/share/jfr/writers/jfrNativeEventWriter.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 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
@@ -33,6 +33,6 @@
3333

3434
typedef Adapter<JfrFlush> JfrNativeEventAdapter;
3535
typedef MemoryWriterHost<JfrNativeEventAdapter, StackObj> JfrNativeEventWriterImpl;
36-
typedef StackEventWriterHost<BigEndianEncoder, CompressedIntegerEncoder, JfrNativeEventWriterImpl> JfrNativeEventWriter;
36+
typedef EventWriterHost<BigEndianEncoder, CompressedIntegerEncoder, JfrNativeEventWriterImpl> JfrNativeEventWriter;
3737

3838
#endif // SHARE_JFR_WRITERS_JFRNATIVEEVENTWRITER_HPP

src/jdk.jfr/share/classes/jdk/jfr/internal/EventWriter.java

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 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
@@ -35,21 +35,25 @@
3535
*
3636
*/
3737
public final class EventWriter {
38+
39+
// Event may not exceed size for a padded integer
40+
private static final long MAX_EVENT_SIZE = (1 << 28) -1;
3841
private static final Unsafe unsafe = Unsafe.getUnsafe();
3942
private final static JVM jvm = JVM.getJVM();
4043

44+
// The JVM needs access to these values. Don't remove
45+
private final long threadID;
4146
private long startPosition;
4247
private long startPositionAddress;
4348
private long currentPosition;
4449
private long maxPosition;
45-
private final long threadID;
50+
private boolean valid;
51+
boolean notified; // Not private to avoid being optimized away
52+
4653
private PlatformEventType eventType;
47-
private int maxEventSize;
4854
private boolean started;
49-
private boolean valid;
5055
private boolean flushOnEnd;
51-
// set by the JVM, not private to avoid being optimized out
52-
boolean notified;
56+
private boolean largeSize = false;
5357

5458
public static EventWriter getEventWriter() {
5559
EventWriter ew = (EventWriter)JVM.getEventWriter();
@@ -175,9 +179,15 @@ public void putStackTrace() {
175179
}
176180

177181
private void reserveEventSizeField() {
178-
// move currentPosition Integer.Bytes offset from start position
179-
if (isValidForSize(Integer.BYTES)) {
180-
currentPosition += Integer.BYTES;
182+
this.largeSize = eventType.isLargeSize();
183+
if (largeSize) {
184+
if (isValidForSize(Integer.BYTES)) {
185+
currentPosition += Integer.BYTES;
186+
}
187+
} else {
188+
if (isValidForSize(1)) {
189+
currentPosition += 1;
190+
}
181191
}
182192
}
183193

@@ -242,11 +252,25 @@ public boolean endEvent() {
242252
return true;
243253
}
244254
final int eventSize = usedSize();
245-
if (eventSize > maxEventSize) {
255+
if (eventSize > MAX_EVENT_SIZE) {
246256
reset();
247257
return true;
248258
}
249-
Bits.putInt(startPosition, makePaddedInt(eventSize));
259+
260+
if (largeSize) {
261+
Bits.putInt(startPosition, makePaddedInt(eventSize));
262+
} else {
263+
if (eventSize < 128) {
264+
Bits.putByte(startPosition, (byte) eventSize);
265+
} else {
266+
eventType.setLargeSize();
267+
reset();
268+
// returning false will trigger restart of the
269+
// event write attempt
270+
return false;
271+
}
272+
}
273+
250274
if (isNotified()) {
251275
resetNotified();
252276
reset();
@@ -273,8 +297,6 @@ private EventWriter(long startPos, long maxPos, long startPosAddress, long threa
273297
flushOnEnd = false;
274298
this.valid = valid;
275299
notified = false;
276-
// event may not exceed size for a padded integer
277-
maxEventSize = (1 << 28) -1;
278300
}
279301

280302
private static int makePaddedInt(int v) {

src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public final class PlatformEventType extends Type {
4646
private final int stackTraceOffset;
4747

4848
// default values
49+
private boolean largeSize = false;
4950
private boolean enabled = false;
5051
private boolean stackTraceEnabled = true;
5152
private long thresholdTicks = 0;
@@ -278,4 +279,12 @@ public boolean isCommittable() {
278279
public int getStackTraceOffset() {
279280
return stackTraceOffset;
280281
}
282+
283+
public boolean isLargeSize() {
284+
return largeSize;
285+
}
286+
287+
public void setLargeSize() {
288+
largeSize = true;
289+
}
281290
}

0 commit comments

Comments
 (0)