8358750: JFR: EventInstrumentation MASK_THROTTLE* constants should be computed in longs

Reviewed-by: mgronlun
This commit is contained in:
Erik Gahlin 2025-07-03 20:01:33 +00:00
parent dcc7254a38
commit 77e69e02eb
2 changed files with 59 additions and 33 deletions

View File

@ -61,8 +61,8 @@ import jdk.jfr.internal.util.ImplicitFields;
*
*/
public final class EventInstrumentation {
public static final long MASK_THROTTLE = 1 << 62;
public static final long MASK_THROTTLE_CHECK = 1 << 63;
public static final long MASK_THROTTLE = 1L << 62;
public static final long MASK_THROTTLE_CHECK = 1L << 63;
public static final long MASK_THROTTLE_BITS = MASK_THROTTLE | MASK_THROTTLE_CHECK;
public static final long MASK_THROTTLE_CHECK_SUCCESS = MASK_THROTTLE_CHECK | MASK_THROTTLE;
public static final long MASK_THROTTLE_CHECK_FAIL = MASK_THROTTLE_CHECK | 0;
@ -482,6 +482,11 @@ public final class EventInstrumentation {
blockCodeBuilder.ifne(durationEvent);
invokestatic(blockCodeBuilder, TYPE_EVENT_CONFIGURATION, METHOD_TIME_STAMP);
blockCodeBuilder.lstore(1);
if (throttled) {
blockCodeBuilder.aload(0);
blockCodeBuilder.lload(1);
putfield(blockCodeBuilder, eventClassDesc, ImplicitFields.FIELD_START_TIME);
}
Label commit = blockCodeBuilder.newLabel();
blockCodeBuilder.goto_(commit);
// if (duration == 0) {
@ -491,7 +496,7 @@ public final class EventInstrumentation {
blockCodeBuilder.labelBinding(durationEvent);
blockCodeBuilder.aload(0);
getfield(blockCodeBuilder, eventClassDesc, ImplicitFields.FIELD_DURATION);
blockCodeBuilder.lconst_0();
blockCodeBuilder.lconst_0(); // also blocks throttled event
blockCodeBuilder.lcmp();
blockCodeBuilder.ifne(commit);
blockCodeBuilder.aload(0);
@ -527,9 +532,7 @@ public final class EventInstrumentation {
// write duration
blockCodeBuilder.dup();
// stack: [EW] [EW]
blockCodeBuilder.aload(0);
// stack: [EW] [EW] [this]
getfield(blockCodeBuilder, eventClassDesc, ImplicitFields.FIELD_DURATION);
getDuration(blockCodeBuilder);
// stack: [EW] [EW] [long]
invokevirtual(blockCodeBuilder, TYPE_EVENT_WRITER, EventWriterMethod.PUT_LONG.method());
fieldIndex++;

View File

@ -23,38 +23,25 @@
package jdk.jfr.api.metadata.annotations;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.time.Instant;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import jdk.jfr.AnnotationElement;
import jdk.jfr.Event;
import jdk.jfr.EventType;
import jdk.jfr.MetadataDefinition;
import jdk.jfr.Name;
import jdk.jfr.Threshold;
import jdk.jfr.Enabled;
import jdk.jfr.Event;
import jdk.jfr.Recording;
import jdk.jfr.SettingDefinition;
import jdk.jfr.SettingDescriptor;
import jdk.jfr.Throttle;
import jdk.jfr.ValueDescriptor;
import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordingStream;
import jdk.test.lib.Asserts;
import jdk.test.lib.jfr.Events;
import jdk.jfr.SettingControl;
import jdk.jfr.SettingDefinition;
import jdk.jfr.Threshold;
import jdk.jfr.Throttle;
import jdk.jfr.consumer.RecordedEvent;
import jdk.jfr.consumer.RecordingFile;
import jdk.jfr.consumer.RecordingStream;
/**
* @test
@ -65,6 +52,9 @@ import jdk.jfr.SettingControl;
*/
public class TestThrottle {
public static class UnthrottledEvent extends Event {
}
@Throttle("off")
@Enabled(false)
public static class ThrottledDisabledEvent extends Event {
@ -130,7 +120,11 @@ public class TestThrottle {
public int index;
}
private static Instant startTime;
public static void main(String[] args) throws Exception {
startTime = determineMinimumTime();
testUnthrottled(); // To ensure problem is specific to throttled events
testThrottleDisabled();
testThrottledOff();
testThottleZeroRate();
@ -140,6 +134,20 @@ public class TestThrottle {
testThrottleUserdefined();
}
private static void testUnthrottled() throws Exception {
testEvent(UnthrottledEvent.class, true);
}
private static Instant determineMinimumTime() throws IOException {
try (Recording r = new Recording()) {
r.enable("jdk.JVMInformation");
r.start();
Path p = Path.of("start.jfr");
r.dump(p);
return RecordingFile.readAllEvents(p).get(0).getStartTime();
}
}
private static void testThrottleDisabled() throws Exception {
testEvent(ThrottledDisabledEvent.class, false);
}
@ -220,8 +228,6 @@ public class TestThrottle {
if (e5.shouldCommit()) {
e5.commit();
}
r.stop();
assertEvents(r, eventName, emit ? 5 : 0);
}
}
@ -272,14 +278,31 @@ public class TestThrottle {
private static void assertEvents(Recording r, String name, int expected) throws Exception {
int count = 0;
for (RecordedEvent event : Events.fromRecording(r)) {
r.stop();
Duration d = Duration.between(r.getStartTime(), r.getStopTime());
Path file = Path.of("dump.jfr");
r.dump(file);
for (RecordedEvent event : RecordingFile.readAllEvents(file)) {
if (event.getEventType().getName().equals(name)) {
count++;
}
if (event.getDuration().isNegative()) {
System.out.println(event);
throw new Exception("Unexpected negative duration");
}
if (event.getStartTime().isBefore(startTime)) {
System.out.println(event);
throw new Exception("Unexpected early start time");
}
if (event.getDuration().toMillis() > 2 * d.toMillis()) {
System.out.println(event);
throw new Exception("Duration exceed twice the length of the recording");
}
}
if (count != expected) {
throw new Exception("Expected " + expected + " " + name + " events, but found " + count);
}
Files.delete(file);
}
private static void assertShouldCommit(Event e, boolean expected) throws Exception {