oracle/graal · error · UnsupportedOperationException

isEmpty() is not supported for performance reasons

Error message

isEmpty() is not supported for performance reasons

What it means

NodeMap is an array keyed by node id, not a general map: it has no element count and tracking one would add bookkeeping to a hot data structure. isEmpty() therefore throws UnsupportedOperationException instead of giving a wrong or slow answer. Capacity is available via capacity(), and membership semantics differ from java.util.Map (containsKey requires the node to belong to the map's graph).

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/graph/NodeMap.java:87

        return (T) values[getNodeId(node)];
    }

    private void checkAndGrow(Node node) {
        if (isNew(node)) {
            this.values = Arrays.copyOf(values, Math.max(MIN_REALLOC_SIZE, graph.nodeIdCount() * 3 / 2));
        }
        assert check(node);
    }

    public void growToSize(int newSize) {
        if (newSize > this.values.length) {
            this.values = Arrays.copyOf(values, Math.max(MIN_REALLOC_SIZE, newSize));
        }
    }

    @Override
    public boolean isEmpty() {
        throw new UnsupportedOperationException("isEmpty() is not supported for performance reasons");
    }

    @Override
    public boolean containsKey(Node node) {
        if (node.graph() == graph()) {
            return get(node) != null;
        }
        return false;
    }

    public Graph graph() {
        return graph;
    }

    public void set(Node node, T value) {
        assert check(node);
        if (!node.isAlive()) {
            throw new GraalGraphError("this node is not alive: " + node);

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Remove the isEmpty() call; track emptiness with your own counter or boolean alongside the NodeMap.
  2. Use map.get(node) != null for per-node presence checks (with containsKey for membership semantics).
  3. If generic Map compatibility is required, copy into a HashMap at a phase boundary instead of using NodeMap directly in that code.

Example fix

// before
if (map.isEmpty()) { ... } // NodeMap throws

// after
if (populatedCount == 0) { ... } // maintain alongside the NodeMap
Defensive patterns

Strategy: validation

Validate before calling

// never call map.isEmpty(); maintain presence knowledge yourself
boolean nothingSet = entriesSetByCaller == 0;
boolean nodePresent = map.get(node) != null;

Prevention

When it happens

Trigger: Calling nodeMap.isEmpty() directly, or handing a NodeMap to code that treats it as a Map (debuggers, toString helpers, generic Map utilities, assertion libraries) that probes isEmpty().

Common situations: Passing NodeMap into java.util.Map-oriented helper code or test assertion utilities. IDE-generated equals/isEmpty delegation. Refactoring from HashMap<Node,T> to NodeMap and leaving an isEmpty() call behind.

Related errors


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