oracle/graal · error · GraalError
Emitting code to return the current value of the timestamp c
Error message
Emitting code to return the current value of the timestamp counter is not currently supported on %s
What it means
emitTimeStamp() is a default LIRGeneratorTool method that throws GraalError for architectures without an instruction to read the timestamp counter. Hitting it means lowering reached a 'read timestamp counter' node (e.g., an rdtsc-style intrinsic) on a backend that has not implemented the operation.
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/gen/LIRGeneratorTool.java:1037
default void emitProtectionKeyRegisterWrite(Value value) {
throw new GraalError("Emitting code to write a value to the protection key register is not currently supported on %s", target().arch);
}
/**
* Read contents of the protection key register.
*
* @return value read from the register
*/
default Value emitProtectionKeyRegisterRead() {
throw new GraalError("Emitting code to read the contents of the protection key register is not currently supported on %s", target().arch);
}
default VirtualStackSlot allocateStackMemory(int sizeInBytes, int alignmentInBytes) {
return getResult().getFrameMapBuilder().allocateStackMemory(sizeInBytes, alignmentInBytes);
}
default Value emitTimeStamp() {
throw new GraalError("Emitting code to return the current value of the timestamp counter is not currently supported on %s", target().arch);
}
@SuppressWarnings("unused")
default void emitProcid(AllocatableValue dst) {
throw new GraalError("Emitting code to return the current value of the procid is not currently supported on %s", target().arch);
}
default Value emitReadCallerStackPointer(Stamp wordStamp) {
/*
* We do not know the frame size yet. So we load the address of the first spill slot
* relative to the beginning of the frame, which is equivalent to the stack pointer of the
* caller.
*/
return emitAddress(StackSlot.get(getLIRKind(wordStamp), 0, true));
}
default Value emitReadReturnAddress(Stamp wordStamp, int returnAddressSize) {
return emitMove(StackSlot.get(getLIRKind(wordStamp), -returnAddressSize, true));View on GitHub (pinned to a66e9ccd1d)
Solutions
- Replace the timestamp intrinsic with a supported mechanism on that platform (e.g., System.nanoTime(), a native call)
- Gate the node's lowering on target().arch so unsupported architectures never emit it
- Implement emitTimeStamp in the relevant backend LIRGenerator
Example fix
// before
@NodeIntrinsic public static native long timeStamp();
... timeStamp() ... // lowers on every arch, throws on unported ones
// after
if (arch instanceof AMD64) { emitTimeStamp(); } else { System.nanoTime(); } Defensive patterns
Strategy: validation
Validate before calling
if (backendOverrides(lirGen.getClass(), "emitTimeStamp")) {
ts = gen.emitTimeStamp();
} else {
ts = emitNativeCallToClockMono(); // supported on every arch
} Prevention
- Prefer portable APIs (System.nanoTime) for timestamps in code compiled across architectures
- Gate hardware-counter intrinsics on arch checks in lowering
- Verify intrinsic support per backend before shipping cross-platform code
When it happens
Trigger: Lowering a timestamp-counter node/intrinsic on a backend whose LIRGenerator does not override emitTimeStamp(). The offending architecture is printed in the message via target().arch.
Common situations: Benchmarks, entropy sources, or profiling code that reads hardware timestamps being JIT-compiled on an architecture without a ported rdtsc equivalent; new intrinsics added to the frontend before backend coverage.
Related errors
- Emitting code to write a value to the protection key registe
- Emitting code to read the contents of the protection key reg
- Emitting code to return the current value of the procid is n
- injectProfiles during replay
- There are no allocatable registers for kind %s, consider ass
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/c78f72e2ef681d41.
Report an issue: GitHub.