oracle/graal · error · GraalError
Out of scratch registers: %s
Error message
Out of scratch registers: %s
What it means
Thrown by readPrimitiveArrayUnaligned when the array constant's type is not a primitive array. Buffer-based byte reads are only valid on primitive guest arrays; reference arrays and non-array objects have no byte buffer to decode from.
Source
Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/asm/aarch64/AArch64MacroAssembler.java:97
public ScratchRegister(Register register) {
this.register = register;
}
public Register getRegister() {
return register;
}
@Override
public void close() {
assert nextFreeScratchRegister > 0 : "Close called too often";
nextFreeScratchRegister--;
}
}
public ScratchRegister getScratchRegister() {
if (nextFreeScratchRegister == getScratchRegisters().length) {
throw new GraalError("Out of scratch registers: " + nextFreeScratchRegister);
}
return getScratchRegisters()[nextFreeScratchRegister++];
}
@Override
public void bind(Label l) {
super.bind(l);
// Clear last ldr/str instruction to prevent the labeled ldr/str being merged.
lastImmLoadStoreEncoding = null;
}
/**
* Retrieves pc relative offset between current position and provided bound label.
*/
public int getPCRelativeOffset(Label label) {
assert label.isBound();
registerPatchInCodeSnippetRecord(position(), label);
int offset = label.position() - position();View on GitHub (pinned to a66e9ccd1d)
Solutions
- Verify arrayType.isArray() && getComponentType().isPrimitive() before the read
- Match the kind to the actual component type of the array you pass
- For reference arrays use readArrayElement and handle elements as object constants
Example fix
// before
JavaConstant v = vmAccess.readPrimitiveArrayUnaligned(refArrayConst, JavaKind.Int, offset);
// after
EspressoResolvedObjectType t = ((EspressoExternalObjectConstant) refArrayConst).getType();
JavaConstant v = (t.isArray() && t.getComponentType().isPrimitive())
? vmAccess.readPrimitiveArrayUnaligned(refArrayConst, t.getComponentType().getJavaKind(), offset)
: vmAccess.readArrayElement(refArrayConst, offset / 4); Defensive patterns
Strategy: validation
Validate before calling
EspressoResolvedObjectType t = ((EspressoExternalObjectConstant) array).getType();
if (!(t.isArray() && t.getComponentType().isPrimitive())) {
throw new IllegalArgumentException("unaligned read requires a primitive array, got " + t);
} Type guard
static boolean isPrimitiveArrayConstant(JavaConstant c) {
return c instanceof EspressoExternalObjectConstant o
&& o.getType().isArray()
&& o.getType().getComponentType().isPrimitive();
} Prevention
- Pair the kind argument with the array's actual component kind at the call site
- For reference arrays, use element-wise object reads
When it happens
Trigger: Calling readPrimitiveArrayUnaligned with an Object[] constant, an espresso String, or any non-array object constant while the kind itself is a valid primitive.
Common situations: Reading a field that is a reference array by mistake; kind/array mismatch where the kind came from one field and the array constant from another; refactors mixing up variables.
Related errors
- Cannot bind label to negative position %d
- Branch target %d out of bounds
- Expected a non-void primitive kind, got {}
- Negative array size: {}
- Expected an array constant for src, got
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/47a0a3b390833d76.
Report an issue: GitHub.