oracle/graal · error · GraalError

Emitting code to read the contents of the protection key reg

Error message

Emitting code to read the contents of the protection key register is not currently supported on %s

What it means

Default implementation of emitProtectionKeyRegisterRead() in LIRGeneratorTool; it throws GraalError naming the architecture whenever a backend without protection-key-register read support lowers such a node. The architecture is interpolated via target().arch in the message, telling you exactly which backend lacks the feature.

Source

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

     */
    void emitSpeculationFence();

    /**
     * Write value to the protection key register.
     *
     * @param value to be written
     */
    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

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Avoid emitting protection-key reads on unsupported architectures by gating the frontend node on target().arch
  2. Implement emitProtectionKeyRegisterRead in the target backend's LIRGenerator
  3. Disable the protection-key feature in the guest language/runtime configuration on that platform

Example fix

// before
Value pkru = getLIRGeneratorTool().emitProtectionKeyRegisterRead();

// after: gate on backend support
if (backendSupportsPkeyRead(arch)) {
    Value pkru = getLIRGeneratorTool().emitProtectionKeyRegisterRead();
} else {
    pkru = ConstantNode.forInt(0, graph()); // feature disabled path
}
Defensive patterns

Strategy: validation

Validate before calling

if (backendOverrides(lirGen.getClass(), "emitProtectionKeyRegisterRead")) {
    Value pkru = gen.emitProtectionKeyRegisterRead();
} else {
    throw GraalError.unsupported("pkey read not available on " + arch);
}

Prevention

When it happens

Trigger: A graph node lowers to a protection key register read (e.g., code that samples PKRU state) while compiling on a backend whose LIRGenerator does not override this method (currently all standard backends, since only new/riscv-style pkey work introduces it).

Common situations: Using memory-protection-key language features or intrinsics on a mainstream architecture; experimental branches emitting the read on unported backends; cross-compiling for an arch where pkeys do not exist.

Related errors


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