--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java 2017-03-20 17:38:01.000000000 -0700 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java 2017-03-20 17:38:00.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,12 +22,14 @@ */ package org.graalvm.compiler.graph; -import java.util.AbstractMap.SimpleEntry; import java.util.Arrays; import java.util.Iterator; -import java.util.Map.Entry; +import java.util.function.BiFunction; -public class NodeMap extends NodeIdAccessor { +import org.graalvm.util.EconomicMap; +import org.graalvm.util.MapCursor; + +public class NodeMap extends NodeIdAccessor implements EconomicMap { private static final int MIN_REALLOC_SIZE = 16; @@ -43,6 +45,7 @@ this.values = Arrays.copyOf(copyFrom.values, copyFrom.values.length); } + @Override @SuppressWarnings("unchecked") public T get(Node node) { assert check(node); @@ -62,16 +65,15 @@ assert check(node); } + @Override public boolean isEmpty() { - return !entries().iterator().hasNext(); + throw new UnsupportedOperationException("isEmpty() is not supported for performance reasons"); } - public boolean containsKey(Object key) { - if (key instanceof Node) { - Node node = (Node) key; - if (node.graph() == graph()) { - return get(node) != null; - } + @Override + public boolean containsKey(Node node) { + if (node.graph() == graph()) { + return get(node) != null; } return false; } @@ -96,7 +98,7 @@ public void setAndGrow(Node node, T value) { checkAndGrow(node); - values[getNodeId(node)] = value; + set(node, value); } /** @@ -107,12 +109,17 @@ return graph.getNode(i); } + @Override public int size() { + throw new UnsupportedOperationException("size() is not supported for performance reasons"); + } + + public int capacity() { return values.length; } public boolean isNew(Node node) { - return getNodeId(node) >= size(); + return getNodeId(node) >= capacity(); } private boolean check(Node node) { @@ -121,16 +128,18 @@ return true; } + @Override public void clear() { Arrays.fill(values, null); } - public Iterable> entries() { - return new Iterable>() { + @Override + public Iterable getKeys() { + return new Iterable() { @Override - public Iterator> iterator() { - return new Iterator>() { + public Iterator iterator() { + return new Iterator() { int i = 0; @@ -140,25 +149,88 @@ return i < NodeMap.this.values.length; } - @SuppressWarnings("unchecked") @Override - public Entry next() { + public Node next() { final int pos = i; - Node key = NodeMap.this.getKey(pos); - T value = (T) NodeMap.this.values[pos]; + final Node key = NodeMap.this.getKey(pos); i++; forward(); - return new SimpleEntry(key, value) { + return key; + } - private static final long serialVersionUID = 7813842391085737738L; + @Override + public void remove() { + throw new UnsupportedOperationException(); + } - @Override - public T setValue(T v) { - T oldv = super.setValue(v); - NodeMap.this.values[pos] = v; - return oldv; - } - }; + private void forward() { + while (i < NodeMap.this.values.length && (NodeMap.this.getKey(i) == null || NodeMap.this.values[i] == null)) { + i++; + } + } + }; + } + }; + } + + @Override + public MapCursor getEntries() { + return new MapCursor() { + + int current = -1; + + @Override + public boolean advance() { + current++; + while (current < NodeMap.this.values.length && (NodeMap.this.values[current] == null || NodeMap.this.getKey(current) == null)) { + current++; + } + return current < NodeMap.this.values.length; + } + + @Override + public Node getKey() { + return NodeMap.this.getKey(current); + } + + @SuppressWarnings("unchecked") + @Override + public T getValue() { + return (T) NodeMap.this.values[current]; + } + + @Override + public void remove() { + assert NodeMap.this.values[current] != null; + NodeMap.this.values[current] = null; + } + }; + } + + @Override + public Iterable getValues() { + return new Iterable() { + + @Override + public Iterator iterator() { + return new Iterator() { + + int i = 0; + + @Override + public boolean hasNext() { + forward(); + return i < NodeMap.this.values.length; + } + + @SuppressWarnings("unchecked") + @Override + public T next() { + final int pos = i; + final T value = (T) NodeMap.this.values[pos]; + i++; + forward(); + return value; } @Override @@ -178,24 +250,42 @@ @Override public String toString() { - Iterator> i = entries().iterator(); - if (!i.hasNext()) { + MapCursor i = getEntries(); + if (!i.advance()) { return "{}"; } StringBuilder sb = new StringBuilder(); sb.append('{'); while (true) { - Entry e = i.next(); - Node key = e.getKey(); - T value = e.getValue(); + Node key = i.getKey(); + T value = i.getValue(); sb.append(key); sb.append('='); sb.append(value); - if (!i.hasNext()) { + if (!i.advance()) { return sb.append('}').toString(); } sb.append(',').append(' '); } } + + @Override + public T put(Node key, T value) { + T result = get(key); + set(key, value); + return result; + } + + @Override + public T removeKey(Node key) { + return put(key, null); + } + + @Override + public void replaceAll(BiFunction function) { + for (Node n : getKeys()) { + put(n, function.apply(n, get(n))); + } + } }