"JFR: Remove event handlers" (https://bugs.openjdk.java.net/browse/JDK-8282420) adds support for static commit methods for event classes defined in the boot class loader. This is used when adding instrumentation for the exception and I/O events, for example:
EventConfiguration ec = EventConfigurations.ERROR_THROWN;
if (ec.isEnabled()) {
long timestamp = EventConfiguration.timestamp();
ErrorThrownEvent.commit(timestamp, 0L, message, e.getClass());
}
JFR will on class load (typically) add the necessary bytecode to the commit-method. This is a useful workaround in hot paths in the JDK (not outside) where the JIT is not able to remove object allocation. Long term plan is to use value types or some other mechanism to guarantee there is never any allocation.
It would be desirable if the same mechanism could be used in java.base at compile time (for events that aren't added by instrumentation). One idea is to add support for a static shouldCommit-method and a method for taking a timestamp:
public class OpenSocketEvent extends Event {
long address;
public long timestamp() {
return 0L; // Generated by JFR
}
public boolean enabled() {
return false; // Generated by JFR
}
pubic static boolean shouldCommit(long duration) {
// Generated by JFR
}
pubic void commit(long start, long duration, String message) {
// Generated by JFR
}
}
void openSocket(String address) {
if (OpenSocketEvent.enabled()) {
long start = OpenSocketEvent.timestamp();
...
long duration = OpenSocketEvent.timestamp() - start;
if (OpenSocketEvent.shouldCommit(duration)) {
OpenSocketEvent.commit(start, duration, address);
}
} else {
openSocket(...);
}
}
Obviously the above is much more cumbersome than today's:
public class OpenSocketEvent extends Event {
String address,
}
void openSocket(String address) {
OpenSocketEvent e = new OpenSocketEvent();
e.begin();
...
e.address = address
e.commit();
}
so it should only be used where it can be proven there is an issue.
If there is a static void commit(), the instance version doesn't need to be generated. This reduces overhead at startup, but could potentially be an issue if both ways are needed.
EventConfiguration ec = EventConfigurations.ERROR_THROWN;
if (ec.isEnabled()) {
long timestamp = EventConfiguration.timestamp();
ErrorThrownEvent.commit(timestamp, 0L, message, e.getClass());
}
JFR will on class load (typically) add the necessary bytecode to the commit-method. This is a useful workaround in hot paths in the JDK (not outside) where the JIT is not able to remove object allocation. Long term plan is to use value types or some other mechanism to guarantee there is never any allocation.
It would be desirable if the same mechanism could be used in java.base at compile time (for events that aren't added by instrumentation). One idea is to add support for a static shouldCommit-method and a method for taking a timestamp:
public class OpenSocketEvent extends Event {
long address;
public long timestamp() {
return 0L; // Generated by JFR
}
public boolean enabled() {
return false; // Generated by JFR
}
pubic static boolean shouldCommit(long duration) {
// Generated by JFR
}
pubic void commit(long start, long duration, String message) {
// Generated by JFR
}
}
void openSocket(String address) {
if (OpenSocketEvent.enabled()) {
long start = OpenSocketEvent.timestamp();
...
long duration = OpenSocketEvent.timestamp() - start;
if (OpenSocketEvent.shouldCommit(duration)) {
OpenSocketEvent.commit(start, duration, address);
}
} else {
openSocket(...);
}
}
Obviously the above is much more cumbersome than today's:
public class OpenSocketEvent extends Event {
String address,
}
void openSocket(String address) {
OpenSocketEvent e = new OpenSocketEvent();
e.begin();
...
e.address = address
e.commit();
}
so it should only be used where it can be proven there is an issue.
If there is a static void commit(), the instance version doesn't need to be generated. This reduces overhead at startup, but could potentially be an issue if both ways are needed.