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).

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.

Appendix: 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)