oracle/graal · error · GraalError

Emitting code to return the current value of the procid is n

Error message

Emitting code to return the current value of the procid is not currently supported on %s

What it means

emitProcid(AllocatableValue) defaults to throwing GraalError in LIRGeneratorTool, listing the architecture in the message. It represents emitting code that returns the processor ID; only backends that implement it can compile nodes lowering to this operation. The @SuppressWarnings("unused") parameter signals this is a pure capability hook.

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/gen/LIRGeneratorTool.java:1042

     * 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));
    }

    @SuppressWarnings("unused")
    default void emitZeroMemory(Value address, Value length, boolean isAligned) {
        throw GraalError.unimplemented("Bulk zeroing is not implemented on this architecture"); // ExcludeFromJacocoGeneratedReport

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Obtain the processor ID through a supported channel (runtime call / OS API) instead of the compiler intrinsic
  2. Guard the lowering of the procid node on target().arch so it is only emitted on backends implementing it
  3. Implement emitProcid in the backend's LIRGenerator if the architecture has such an instruction

Example fix

// before
@NodeIntrinsic public static native long procid();
return procid(); // throws on unported backends

// after
if (supportsProcid(arch)) { return procid(); }
return OsBridge.getThreadId();
Defensive patterns

Strategy: validation

Validate before calling

if (backendOverrides(lirGen.getClass(), "emitProcid")) {
    id = gen.emitProcid(dst);
} else {
    id = callOsThreadSelf(); // portable fallback
}

Prevention

When it happens

Trigger: Lowering a procid node/intrinsic while compiling on any backend whose LIRGenerator does not override emitProcid. The failing architecture appears in the interpolated %s.

Common situations: NUMA-aware or per-CPU affinity code reading processor identifiers; new architecture ports where the intrinsic was not wired up; language runtimes probing hardware topology inside JIT-compiled code.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/f5818d365e64466c. Report an issue: GitHub.