8194819: Update Graal

Reviewed-by: kvn
This commit is contained in:
Igor Veresov 2018-02-02 17:28:17 -08:00
parent 83bb2205e8
commit 333333a507
298 changed files with 4754 additions and 2849 deletions

View File

@ -493,6 +493,7 @@ jdk.internal.vm.compiler_ADD_JAVAC_FLAGS += -parameters -XDstringConcat=inline \
# #
jdk.internal.vm.compiler_EXCLUDES += \ jdk.internal.vm.compiler_EXCLUDES += \
org.graalvm.collections.test \
org.graalvm.compiler.core.match.processor \ org.graalvm.compiler.core.match.processor \
org.graalvm.compiler.nodeinfo.processor \ org.graalvm.compiler.nodeinfo.processor \
org.graalvm.compiler.options.processor \ org.graalvm.compiler.options.processor \
@ -511,6 +512,7 @@ jdk.internal.vm.compiler_EXCLUDES += \
org.graalvm.compiler.graph.test \ org.graalvm.compiler.graph.test \
org.graalvm.compiler.hotspot.amd64.test \ org.graalvm.compiler.hotspot.amd64.test \
org.graalvm.compiler.hotspot.lir.test \ org.graalvm.compiler.hotspot.lir.test \
org.graalvm.compiler.hotspot.sparc.test \
org.graalvm.compiler.hotspot.test \ org.graalvm.compiler.hotspot.test \
org.graalvm.compiler.jtt \ org.graalvm.compiler.jtt \
org.graalvm.compiler.lir.jtt \ org.graalvm.compiler.lir.jtt \

View File

@ -48,6 +48,7 @@ ifeq ($(INCLUDE_GRAAL), true)
SETUP := GENERATE_OLDBYTECODE, \ SETUP := GENERATE_OLDBYTECODE, \
SRC := \ SRC := \
$(SRC_DIR)/org.graalvm.word/src \ $(SRC_DIR)/org.graalvm.word/src \
$(SRC_DIR)/org.graalvm.collections/src \
$(SRC_DIR)/org.graalvm.compiler.core/src \ $(SRC_DIR)/org.graalvm.compiler.core/src \
$(SRC_DIR)/org.graalvm.compiler.core.common/src \ $(SRC_DIR)/org.graalvm.compiler.core.common/src \
$(SRC_DIR)/org.graalvm.compiler.core.match.processor/src \ $(SRC_DIR)/org.graalvm.compiler.core.match.processor/src \
@ -101,6 +102,7 @@ ifeq ($(INCLUDE_GRAAL), true)
$(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_OPTIONS_PROCESSOR, \ $(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_OPTIONS_PROCESSOR, \
SETUP := GENERATE_OLDBYTECODE, \ SETUP := GENERATE_OLDBYTECODE, \
SRC := \ SRC := \
$(SRC_DIR)/org.graalvm.collections/src \
$(SRC_DIR)/org.graalvm.compiler.options/src \ $(SRC_DIR)/org.graalvm.compiler.options/src \
$(SRC_DIR)/org.graalvm.compiler.options.processor/src \ $(SRC_DIR)/org.graalvm.compiler.options.processor/src \
$(SRC_DIR)/org.graalvm.util/src \ $(SRC_DIR)/org.graalvm.util/src \
@ -117,6 +119,7 @@ ifeq ($(INCLUDE_GRAAL), true)
SETUP := GENERATE_OLDBYTECODE, \ SETUP := GENERATE_OLDBYTECODE, \
SRC := \ SRC := \
$(SRC_DIR)/org.graalvm.word/src \ $(SRC_DIR)/org.graalvm.word/src \
$(SRC_DIR)/org.graalvm.collections/src \
$(SRC_DIR)/org.graalvm.compiler.replacements.verifier/src \ $(SRC_DIR)/org.graalvm.compiler.replacements.verifier/src \
$(SRC_DIR)/org.graalvm.compiler.api.replacements/src \ $(SRC_DIR)/org.graalvm.compiler.api.replacements/src \
$(SRC_DIR)/org.graalvm.compiler.code/src \ $(SRC_DIR)/org.graalvm.compiler.code/src \

View File

@ -143,7 +143,7 @@ final class DataPatchProcessor {
int alignment = data.getAlignment(); int alignment = data.getAlignment();
byte[] value = new byte[size]; byte[] value = new byte[size];
ByteBuffer buffer = ByteBuffer.wrap(value).order(ByteOrder.nativeOrder()); ByteBuffer buffer = ByteBuffer.wrap(value).order(ByteOrder.nativeOrder());
DataSection.emit(buffer, data, p -> { DataSection.emit(buffer, data, (p, c) -> {
}); });
String targetSymbol = "data.M" + methodInfo.getCodeId() + "." + dataOffset; String targetSymbol = "data.M" + methodInfo.getCodeId() + "." + dataOffset;
Symbol relocationSymbol = binaryContainer.getSymbol(targetSymbol); Symbol relocationSymbol = binaryContainer.getSymbol(targetSymbol);

View File

@ -82,6 +82,24 @@ suite = {
"javaCompliance" : "1.8", "javaCompliance" : "1.8",
"workingSets" : "API,SDK", "workingSets" : "API,SDK",
}, },
"org.graalvm.collections" : {
"subDir" : "share/classes",
"sourceDirs" : ["src"],
"checkstyle" : "org.graalvm.word",
"javaCompliance" : "1.8",
"workingSets" : "API,SDK",
},
"org.graalvm.collections.test" : {
"subDir" : "share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
"mx:JUNIT",
"org.graalvm.collections",
],
"checkstyle" : "org.graalvm.word",
"javaCompliance" : "1.8",
"workingSets" : "API,SDK,Test",
},
# ------------- Graal ------------- # ------------- Graal -------------
@ -190,6 +208,9 @@ suite = {
"org.graalvm.util" : { "org.graalvm.util" : {
"subDir" : "share/classes", "subDir" : "share/classes",
"sourceDirs" : ["src"], "sourceDirs" : ["src"],
"dependencies" : [
"org.graalvm.collections",
],
"checkstyle" : "org.graalvm.compiler.graph", "checkstyle" : "org.graalvm.compiler.graph",
"javaCompliance" : "1.8", "javaCompliance" : "1.8",
"workingSets" : "API,Graal", "workingSets" : "API,Graal",
@ -201,6 +222,7 @@ suite = {
"dependencies" : [ "dependencies" : [
"mx:JUNIT", "mx:JUNIT",
"org.graalvm.util", "org.graalvm.util",
"org.graalvm.compiler.core.test",
], ],
"checkstyle" : "org.graalvm.compiler.graph", "checkstyle" : "org.graalvm.compiler.graph",
"javaCompliance" : "1.8", "javaCompliance" : "1.8",
@ -970,10 +992,11 @@ suite = {
"workingSets" : "Graal,SPARC", "workingSets" : "Graal,SPARC",
}, },
"org.graalvm.compiler.core.sparc.test" : { "org.graalvm.compiler.hotspot.sparc.test" : {
"subDir" : "share/classes", "subDir" : "share/classes",
"sourceDirs" : ["src"], "sourceDirs" : ["src"],
"dependencies" : [ "dependencies" : [
"org.graalvm.compiler.hotspot",
"org.graalvm.compiler.lir.jtt", "org.graalvm.compiler.lir.jtt",
"JVMCI_HOTSPOT" "JVMCI_HOTSPOT"
], ],
@ -1007,6 +1030,7 @@ suite = {
"subDir" : "share/classes", "subDir" : "share/classes",
"sourceDirs" : ["src"], "sourceDirs" : ["src"],
"dependencies" : [ "dependencies" : [
"org.graalvm.collections",
"org.graalvm.compiler.debug", "org.graalvm.compiler.debug",
"org.graalvm.word", "org.graalvm.word",
], ],
@ -1037,7 +1061,6 @@ suite = {
"sourceDirs" : ["src"], "sourceDirs" : ["src"],
"dependencies" : [ "dependencies" : [
"org.graalvm.compiler.debug", "org.graalvm.compiler.debug",
"org.graalvm.util",
"mx:JUNIT", "mx:JUNIT",
], ],
"checkstyle" : "org.graalvm.compiler.graph", "checkstyle" : "org.graalvm.compiler.graph",
@ -1225,11 +1248,11 @@ suite = {
"org.graalvm.compiler.asm.amd64.test", "org.graalvm.compiler.asm.amd64.test",
"org.graalvm.compiler.core.aarch64.test", "org.graalvm.compiler.core.aarch64.test",
"org.graalvm.compiler.core.amd64.test", "org.graalvm.compiler.core.amd64.test",
"org.graalvm.compiler.core.sparc.test",
"org.graalvm.compiler.debug.test", "org.graalvm.compiler.debug.test",
"org.graalvm.compiler.hotspot.aarch64.test", "org.graalvm.compiler.hotspot.aarch64.test",
"org.graalvm.compiler.hotspot.amd64.test", "org.graalvm.compiler.hotspot.amd64.test",
"org.graalvm.compiler.hotspot.lir.test", "org.graalvm.compiler.hotspot.lir.test",
"org.graalvm.compiler.hotspot.sparc.test",
"org.graalvm.compiler.options.test", "org.graalvm.compiler.options.test",
"org.graalvm.compiler.jtt", "org.graalvm.compiler.jtt",
"org.graalvm.compiler.lir.jtt", "org.graalvm.compiler.lir.jtt",

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.collections.test;
import java.util.Arrays;
import java.util.Iterator;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Equivalence;
import org.graalvm.collections.UnmodifiableEconomicSet;
import org.junit.Assert;
import org.junit.Test;
public class EconomicMapImplTest {
@Test(expected = UnsupportedOperationException.class)
public void testRemoveNull() {
EconomicMap<Integer, Integer> map = EconomicMap.create(10);
map.removeKey(null);
}
@Test
public void testInitFromHashSet() {
UnmodifiableEconomicSet<Integer> set = new UnmodifiableEconomicSet<Integer>() {
@Override
public boolean contains(Integer element) {
return element == 0;
}
@Override
public int size() {
return 1;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
private boolean visited = false;
@Override
public boolean hasNext() {
return !visited;
}
@Override
public Integer next() {
if (visited) {
return null;
} else {
visited = true;
return 1;
}
}
};
}
};
EconomicSet<Integer> newSet = EconomicSet.create(Equivalence.DEFAULT, set);
Assert.assertEquals(newSet.size(), 1);
}
@Test
public void testCopyHash() {
EconomicSet<Integer> set = EconomicSet.create(Equivalence.IDENTITY);
set.addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
EconomicSet<Integer> newSet = EconomicSet.create(Equivalence.IDENTITY, set);
Assert.assertEquals(newSet.size(), 10);
newSet.remove(8);
newSet.remove(9);
Assert.assertEquals(newSet.size(), 8);
}
@Test
public void testNewEquivalence() {
EconomicSet<Integer> set = EconomicSet.create(new Equivalence() {
@Override
public boolean equals(Object a, Object b) {
return false;
}
@Override
public int hashCode(Object o) {
return 0;
}
});
set.addAll(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9));
Assert.assertTrue(set.add(new Integer(0)));
}
@Test(expected = UnsupportedOperationException.class)
public void testMapPutNull() {
EconomicMap<Integer, Integer> map = EconomicMap.create();
map.put(null, null);
}
}

View File

@ -0,0 +1,231 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.collections.test;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Objects;
import java.util.Random;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.Equivalence;
import org.graalvm.collections.MapCursor;
import org.graalvm.collections.UnmodifiableMapCursor;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class EconomicMapLargeTest {
@Parameter(value = 0) public EconomicMap<Object, Object> testMap;
@Parameter(value = 1) public EconomicMap<Object, Object> referenceMap;
@Parameter(value = 2) public String name;
@Parameters(name = "{2}")
public static Collection<Object[]> data() {
return Arrays.asList(new Object[]{EconomicMap.create(Equivalence.DEFAULT), EconomicMap.create(Equivalence.DEFAULT), "EconomicMap"},
new Object[]{EconomicMap.create(Equivalence.IDENTITY), EconomicMap.create(Equivalence.IDENTITY), "EconomicMap(IDENTITY)"},
new Object[]{EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE), EconomicMap.create(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE),
"EconomicMap(IDENTITY_WITH_SYSTEM_HASHCODE)"},
new Object[]{EconomicMap.create(Equivalence.DEFAULT), EconomicMap.wrapMap(new LinkedHashMap<>()), "EconomicMap<->wrapMap"},
new Object[]{EconomicMap.wrapMap(new LinkedHashMap<>()), EconomicMap.wrapMap(new LinkedHashMap<>()), "wrapMap"});
}
private static int[] createRandomRange(Random random, int count) {
int[] result = new int[count];
for (int i = 0; i < count; ++i) {
int range = random.nextInt(14);
if (range == 0 || range > 10) {
range = Integer.MAX_VALUE;
} else if (range == 10) {
range = 100;
}
result[i] = range;
}
return result;
}
private static final class BadHashClass {
private int value;
BadHashClass(int randomInt) {
this.value = randomInt;
}
@Override
public int hashCode() {
return 0;
}
@Override
public boolean equals(Object other) {
if (other instanceof BadHashClass) {
BadHashClass badHashClass = (BadHashClass) other;
return badHashClass.value == value;
}
return false;
}
}
interface MapAction {
Object perform(EconomicMap<Object, Object> map, int randomInt);
}
static final Object EXISTING_VALUE = new Object();
static final MapAction[] INCREASE_ACTIONS = new MapAction[]{
(map, randomInt) -> map.put(randomInt, "value"),
(map, randomInt) -> map.get(randomInt)
};
static final MapAction[] ACTIONS = new MapAction[]{
(map, randomInt) -> map.removeKey(randomInt),
(map, randomInt) -> map.put(randomInt, "value"),
(map, randomInt) -> map.put(randomInt, null),
(map, randomInt) -> map.put(EXISTING_VALUE, randomInt),
(map, randomInt) -> {
if (randomInt == 0) {
map.clear();
}
return map.isEmpty();
},
(map, randomInt) -> map.containsKey(randomInt),
(map, randomInt) -> map.get(randomInt),
(map, randomInt) -> map.put(new BadHashClass(randomInt), "unique"),
(map, randomInt) -> {
if (randomInt == 0) {
map.replaceAll((key, value) -> Objects.toString(value) + "!");
}
return map.isEmpty();
}
};
@Test
public void testVeryLarge() {
testMap.clear();
referenceMap.clear();
Random random = new Random(0);
for (int i = 0; i < 200000; ++i) {
for (int j = 0; j < INCREASE_ACTIONS.length; ++j) {
int nextInt = random.nextInt(10000000);
MapAction action = INCREASE_ACTIONS[j];
Object result = action.perform(testMap, nextInt);
Object referenceResult = action.perform(referenceMap, nextInt);
Assert.assertEquals(result, referenceResult);
}
}
}
/**
* Tests a sequence of random operations on the map.
*/
@Test
public void testAddRemove() {
testMap.clear();
referenceMap.clear();
for (int seed = 0; seed < 10; ++seed) {
Random random = new Random(seed);
int[] ranges = createRandomRange(random, ACTIONS.length);
int value = random.nextInt(10000);
for (int i = 0; i < value; ++i) {
for (int j = 0; j < ACTIONS.length; ++j) {
if (random.nextInt(ranges[j]) == 0) {
int nextInt = random.nextInt(100);
MapAction action = ACTIONS[j];
Object result = action.perform(testMap, nextInt);
Object referenceResult = action.perform(referenceMap, nextInt);
Assert.assertEquals(result, referenceResult);
if (j % 100 == 0) {
checkEquality(testMap, referenceMap);
}
}
}
if (random.nextInt(20) == 0) {
removeElement(random.nextInt(100), testMap, referenceMap);
}
}
}
}
private static void removeElement(int index, EconomicMap<?, ?> map, EconomicMap<?, ?> referenceMap) {
Assert.assertEquals(referenceMap.size(), map.size());
MapCursor<?, ?> cursor = map.getEntries();
MapCursor<?, ?> referenceCursor = referenceMap.getEntries();
int z = 0;
while (cursor.advance()) {
Assert.assertTrue(referenceCursor.advance());
Assert.assertEquals(referenceCursor.getKey(), cursor.getKey());
Assert.assertEquals(referenceCursor.getValue(), cursor.getValue());
if (index == z) {
cursor.remove();
referenceCursor.remove();
}
++z;
}
Assert.assertFalse(referenceCursor.advance());
}
private static void checkEquality(EconomicMap<?, ?> map, EconomicMap<?, ?> referenceMap) {
Assert.assertEquals(referenceMap.size(), map.size());
// Check entries.
UnmodifiableMapCursor<?, ?> cursor = map.getEntries();
UnmodifiableMapCursor<?, ?> referenceCursor = referenceMap.getEntries();
while (cursor.advance()) {
Assert.assertTrue(referenceCursor.advance());
Assert.assertEquals(referenceCursor.getKey(), cursor.getKey());
Assert.assertEquals(referenceCursor.getValue(), cursor.getValue());
}
// Check keys.
Iterator<?> iterator = map.getKeys().iterator();
Iterator<?> referenceIterator = referenceMap.getKeys().iterator();
while (iterator.hasNext()) {
Assert.assertTrue(referenceIterator.hasNext());
Assert.assertEquals(iterator.next(), referenceIterator.next());
}
// Check values.
iterator = map.getValues().iterator();
referenceIterator = referenceMap.getValues().iterator();
while (iterator.hasNext()) {
Assert.assertTrue(referenceIterator.hasNext());
Assert.assertEquals(iterator.next(), referenceIterator.next());
}
Assert.assertFalse(referenceIterator.hasNext());
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.collections.test;
import java.util.LinkedHashMap;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.UnmodifiableEconomicMap;
import org.junit.Assert;
import org.junit.Test;
public class EconomicMapTest {
@Test
public void testMapGetDefault() {
EconomicMap<Integer, Integer> map = EconomicMap.create();
map.put(0, 1);
Assert.assertEquals(map.get(0, 2), Integer.valueOf(1));
Assert.assertEquals(map.get(1, 2), Integer.valueOf(2));
}
@Test
public void testMapPutAll() {
EconomicMap<Integer, Integer> map = EconomicMap.create();
EconomicMap<Integer, Integer> newMap = EconomicMap.wrapMap(new LinkedHashMap<>());
newMap.put(1, 1);
newMap.put(2, 4);
map.putAll(newMap);
Assert.assertEquals(map.size(), 2);
UnmodifiableEconomicMap<Integer, Integer> unmodifiableEconomicMap = EconomicMap.create(newMap);
map.removeKey(1);
map.put(2, 2);
map.put(3, 9);
map.putAll(unmodifiableEconomicMap);
Assert.assertEquals(map.size(), 3);
Assert.assertEquals(map.get(2), Integer.valueOf(4));
}
@Test
public void testToString() {
EconomicMap<Integer, Integer> map = EconomicMap.create();
map.put(0, 0);
map.put(1, 1);
Assert.assertEquals(map.toString(), "map(size=2, {(0,0),(1,1)})");
}
}

View File

@ -0,0 +1,148 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.collections.test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Equivalence;
import org.junit.Assert;
import org.junit.Test;
public class EconomicSetTest {
@Test
public void testUtilities() {
EconomicSet<Integer> set = EconomicSet.create(0);
set.add(0);
Assert.assertTrue(set.add(1));
Assert.assertEquals(set.size(), 2);
Assert.assertFalse(set.add(1));
Assert.assertEquals(set.size(), 2);
set.remove(1);
Assert.assertEquals(set.size(), 1);
set.remove(2);
Assert.assertEquals(set.size(), 1);
Assert.assertTrue(set.add(1));
set.clear();
Assert.assertEquals(set.size(), 0);
}
@Test
public void testAddAll() {
EconomicSet<Integer> set = EconomicSet.create();
set.addAll(Arrays.asList(0, 1, 0));
Assert.assertEquals(set.size(), 2);
EconomicSet<Integer> newSet = EconomicSet.create();
newSet.addAll(Arrays.asList(1, 2));
Assert.assertEquals(newSet.size(), 2);
newSet.addAll(set);
Assert.assertEquals(newSet.size(), 3);
}
@Test
public void testRemoveAll() {
EconomicSet<Integer> set = EconomicSet.create();
set.addAll(Arrays.asList(0, 1));
set.removeAll(Arrays.asList(1, 2));
Assert.assertEquals(set.size(), 1);
set.removeAll(EconomicSet.create(set));
Assert.assertEquals(set.size(), 0);
}
@Test
public void testRetainAll() {
EconomicSet<Integer> set = EconomicSet.create();
set.addAll(Arrays.asList(0, 1, 2));
EconomicSet<Integer> newSet = EconomicSet.create();
newSet.addAll(Arrays.asList(2, 3));
set.retainAll(newSet);
Assert.assertEquals(set.size(), 1);
}
@Test
public void testToArray() {
EconomicSet<Integer> set = EconomicSet.create();
set.addAll(Arrays.asList(0, 1));
Assert.assertArrayEquals(set.toArray(new Integer[2]), new Integer[]{0, 1});
}
@Test
public void testToString() {
EconomicSet<Integer> set = EconomicSet.create();
set.addAll(Arrays.asList(0, 1));
Assert.assertEquals(set.toString(), "set(size=2, {0,1})");
}
@Test(expected = UnsupportedOperationException.class)
public void testToUnalignedArray() {
Assert.assertArrayEquals(EconomicSet.create().toArray(new Integer[2]), new Integer[0]);
}
@Test
public void testSetRemoval() {
ArrayList<Integer> initialList = new ArrayList<>();
ArrayList<Integer> removalList = new ArrayList<>();
ArrayList<Integer> finalList = new ArrayList<>();
EconomicSet<Integer> set = EconomicSet.create(Equivalence.IDENTITY);
set.add(1);
set.add(2);
set.add(3);
set.add(4);
set.add(5);
set.add(6);
set.add(7);
set.add(8);
set.add(9);
Iterator<Integer> i1 = set.iterator();
while (i1.hasNext()) {
initialList.add(i1.next());
}
int size = 0;
Iterator<Integer> i2 = set.iterator();
while (i2.hasNext()) {
Integer elem = i2.next();
if (size++ < 8) {
i2.remove();
}
removalList.add(elem);
}
Iterator<Integer> i3 = set.iterator();
while (i3.hasNext()) {
finalList.add(i3.next());
}
Assert.assertEquals(initialList, removalList);
Assert.assertEquals(1, finalList.size());
Assert.assertEquals(new Integer(9), finalList.get(0));
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.collections.test;
import org.graalvm.collections.Equivalence;
import org.junit.Assert;
import org.junit.Test;
public class EquivalenceTest {
private static final String TEST_STRING = "Graal";
private static final String TEST_STRING2 = "Graal2";
@Test
public void testDEFAULT() {
Assert.assertTrue(Equivalence.DEFAULT.equals(TEST_STRING, new String(TEST_STRING)));
Assert.assertEquals(Equivalence.DEFAULT.hashCode(TEST_STRING), Equivalence.DEFAULT.hashCode(new String(TEST_STRING)));
Assert.assertFalse(Equivalence.DEFAULT.equals(TEST_STRING, TEST_STRING2));
Assert.assertNotEquals(Equivalence.DEFAULT.hashCode(TEST_STRING), Equivalence.DEFAULT.hashCode(TEST_STRING2));
}
@Test
public void testIDENTITY() {
Assert.assertFalse(Equivalence.IDENTITY.equals(TEST_STRING, new String(TEST_STRING)));
Assert.assertEquals(Equivalence.IDENTITY.hashCode(TEST_STRING), Equivalence.IDENTITY.hashCode(new String(TEST_STRING)));
Assert.assertFalse(Equivalence.IDENTITY.equals(TEST_STRING, TEST_STRING2));
Assert.assertNotEquals(Equivalence.IDENTITY.hashCode(TEST_STRING), Equivalence.IDENTITY.hashCode(TEST_STRING2));
}
@Test
public void testIDENTITYWITHSYSTEMHASHCODE() {
Assert.assertFalse(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.equals(TEST_STRING, new String(TEST_STRING)));
Assert.assertNotEquals(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(TEST_STRING), Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(new String(TEST_STRING)));
Assert.assertFalse(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.equals(TEST_STRING, TEST_STRING2));
Assert.assertNotEquals(Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(TEST_STRING), Equivalence.IDENTITY_WITH_SYSTEM_HASHCODE.hashCode(TEST_STRING2));
}
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,34 +22,31 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.options; package org.graalvm.collections.test;
/** import org.graalvm.collections.Pair;
* Categorizes options according to user relevance. import org.junit.Assert;
* import org.junit.Test;
* @since 1.0
*/
public enum OptionCategory {
/** public class PairTest {
* An option common for users to apply.
*
* @since 1.0
*/
USER,
/** @Test
* An option only relevant in corner cases and for fine-tuning. public void testCreate() {
* Assert.assertEquals(Pair.create(null, null), Pair.empty());
* @since 1.0 Assert.assertNotEquals(Pair.create(null, null), null);
*/ Assert.assertEquals(Pair.createLeft(null), Pair.empty());
EXPERT, Assert.assertEquals(Pair.createRight(null), Pair.empty());
Assert.assertEquals(Pair.create(1, null), Pair.createLeft(1));
Assert.assertEquals(Pair.create(null, 1), Pair.createRight(1));
}
/** @Test
* An option only relevant when debugging language or instrument implementations. public void testUtilities() {
* Pair<Integer, Integer> pair = Pair.create(1, null);
* @since 1.0 Assert.assertEquals(pair.getLeft(), Integer.valueOf(1));
*/ Assert.assertEquals(pair.getRight(), null);
DEBUG Assert.assertEquals(pair.toString(), "(1, null)");
Assert.assertEquals(pair.hashCode(), Pair.createLeft(1).hashCode());
}
} }

View File

@ -4,7 +4,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -20,21 +22,34 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.util; package org.graalvm.collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import org.graalvm.util.impl.EconomicMapImpl;
/** /**
* Memory efficient map data structure. * Memory efficient map data structure.
*
* @since 1.0
*/ */
public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> { public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
/**
* Associates {@code value} with {@code key} in this map. If the map previously contained a
* mapping for {@code key}, the old value is replaced by {@code value}.
*
* @return the previous value associated with {@code key}, or {@code null} if there was no
* mapping for {@code key}.
* @since 1.0
*/
V put(K key, V value); V put(K key, V value);
/**
* Copies all of the mappings from {@code other} to this map.
*
* @since 1.0
*/
default void putAll(EconomicMap<K, V> other) { default void putAll(EconomicMap<K, V> other) {
MapCursor<K, V> e = other.getEntries(); MapCursor<K, V> e = other.getEntries();
while (e.advance()) { while (e.advance()) {
@ -42,15 +57,11 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
} }
} }
void clear(); /**
* Copies all of the mappings from {@code other} to this map.
V removeKey(K key); *
* @since 1.0
@Override */
MapCursor<K, V> getEntries();
void replaceAll(BiFunction<? super K, ? super V, ? extends V> function);
default void putAll(UnmodifiableEconomicMap<? extends K, ? extends V> other) { default void putAll(UnmodifiableEconomicMap<? extends K, ? extends V> other) {
UnmodifiableMapCursor<? extends K, ? extends V> entry = other.getEntries(); UnmodifiableMapCursor<? extends K, ? extends V> entry = other.getEntries();
while (entry.advance()) { while (entry.advance()) {
@ -58,9 +69,45 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
} }
} }
/**
* Removes all of the mappings from this map. The map will be empty after this call returns.
*
* @since 1.0
*/
void clear();
/**
* Removes the mapping for {@code key} from this map if it is present. The map will not contain
* a mapping for {@code key} once the call returns.
*
* @return the previous value associated with {@code key}, or {@code null} if there was no
* mapping for {@code key}.
* @since 1.0
*/
V removeKey(K key);
/**
* Returns a {@link MapCursor} view of the mappings contained in this map.
*
* @since 1.0
*/
@Override
MapCursor<K, V> getEntries();
/**
* Replaces each entry's value with the result of invoking {@code function} on that entry until
* all entries have been processed or the function throws an exception. Exceptions thrown by the
* function are relayed to the caller.
*
* @since 1.0
*/
void replaceAll(BiFunction<? super K, ? super V, ? extends V> function);
/** /**
* Creates a new map that guarantees insertion order on the key set with the default * Creates a new map that guarantees insertion order on the key set with the default
* {@link Equivalence#DEFAULT} comparison strategy for keys. * {@link Equivalence#DEFAULT} comparison strategy for keys.
*
* @since 1.0
*/ */
static <K, V> EconomicMap<K, V> create() { static <K, V> EconomicMap<K, V> create() {
return EconomicMap.create(Equivalence.DEFAULT); return EconomicMap.create(Equivalence.DEFAULT);
@ -70,6 +117,8 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
* Creates a new map that guarantees insertion order on the key set with the default * Creates a new map that guarantees insertion order on the key set with the default
* {@link Equivalence#DEFAULT} comparison strategy for keys and initializes with a specified * {@link Equivalence#DEFAULT} comparison strategy for keys and initializes with a specified
* capacity. * capacity.
*
* @since 1.0
*/ */
static <K, V> EconomicMap<K, V> create(int initialCapacity) { static <K, V> EconomicMap<K, V> create(int initialCapacity) {
return EconomicMap.create(Equivalence.DEFAULT, initialCapacity); return EconomicMap.create(Equivalence.DEFAULT, initialCapacity);
@ -78,15 +127,19 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
/** /**
* Creates a new map that guarantees insertion order on the key set with the given comparison * Creates a new map that guarantees insertion order on the key set with the given comparison
* strategy for keys. * strategy for keys.
*
* @since 1.0
*/ */
static <K, V> EconomicMap<K, V> create(Equivalence strategy) { static <K, V> EconomicMap<K, V> create(Equivalence strategy) {
return EconomicMapImpl.create(strategy); return EconomicMapImpl.create(strategy, false);
} }
/** /**
* Creates a new map that guarantees insertion order on the key set with the default * Creates a new map that guarantees insertion order on the key set with the default
* {@link Equivalence#DEFAULT} comparison strategy for keys and copies all elements from the * {@link Equivalence#DEFAULT} comparison strategy for keys and copies all elements from the
* specified existing map. * specified existing map.
*
* @since 1.0
*/ */
static <K, V> EconomicMap<K, V> create(UnmodifiableEconomicMap<K, V> m) { static <K, V> EconomicMap<K, V> create(UnmodifiableEconomicMap<K, V> m) {
return EconomicMap.create(Equivalence.DEFAULT, m); return EconomicMap.create(Equivalence.DEFAULT, m);
@ -95,21 +148,27 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
/** /**
* Creates a new map that guarantees insertion order on the key set and copies all elements from * Creates a new map that guarantees insertion order on the key set and copies all elements from
* the specified existing map. * the specified existing map.
*
* @since 1.0
*/ */
static <K, V> EconomicMap<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> m) { static <K, V> EconomicMap<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> m) {
return EconomicMapImpl.create(strategy, m); return EconomicMapImpl.create(strategy, m, false);
} }
/** /**
* Creates a new map that guarantees insertion order on the key set and initializes with a * Creates a new map that guarantees insertion order on the key set and initializes with a
* specified capacity. * specified capacity.
*
* @since 1.0
*/ */
static <K, V> EconomicMap<K, V> create(Equivalence strategy, int initialCapacity) { static <K, V> EconomicMap<K, V> create(Equivalence strategy, int initialCapacity) {
return EconomicMapImpl.create(strategy, initialCapacity); return EconomicMapImpl.create(strategy, initialCapacity, false);
} }
/** /**
* Wraps an existing {@link java.util.Map} as an {@link org.graalvm.util.EconomicMap}. * Wraps an existing {@link Map} as an {@link EconomicMap}.
*
* @since 1.0
*/ */
static <K, V> EconomicMap<K, V> wrapMap(Map<K, V> map) { static <K, V> EconomicMap<K, V> wrapMap(Map<K, V> map) {
return new EconomicMap<K, V>() { return new EconomicMap<K, V>() {

View File

@ -4,7 +4,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -20,19 +22,12 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.util.impl; package org.graalvm.collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.Objects; import java.util.Objects;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import org.graalvm.util.Equivalence;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.EconomicSet;
import org.graalvm.util.UnmodifiableEconomicMap;
import org.graalvm.util.UnmodifiableEconomicSet;
import org.graalvm.util.MapCursor;
/** /**
* Implementation of a map with a memory-efficient structure that always preserves insertion order * Implementation of a map with a memory-efficient structure that always preserves insertion order
* when iterating over keys. Particularly efficient when number of entries is 0 or smaller equal * when iterating over keys. Particularly efficient when number of entries is 0 or smaller equal
@ -58,7 +53,7 @@ import org.graalvm.util.MapCursor;
* map falls below a specific threshold, the map will be compressed via the * map falls below a specific threshold, the map will be compressed via the
* {@link #maybeCompress(int)} method. * {@link #maybeCompress(int)} method.
*/ */
public final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicSet<K> { final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicSet<K> {
/** /**
* Initial number of key/value pair entries that is allocated in the first entries array. * Initial number of key/value pair entries that is allocated in the first entries array.
@ -135,45 +130,46 @@ public final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicS
return map; return map;
} }
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy) { public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, boolean isSet) {
return intercept(new EconomicMapImpl<>(strategy)); return intercept(new EconomicMapImpl<>(strategy, isSet));
} }
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, int initialCapacity) { public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, int initialCapacity, boolean isSet) {
return intercept(new EconomicMapImpl<>(strategy, initialCapacity)); return intercept(new EconomicMapImpl<>(strategy, initialCapacity, isSet));
} }
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> other) { public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> other, boolean isSet) {
return intercept(new EconomicMapImpl<>(strategy, other)); return intercept(new EconomicMapImpl<>(strategy, other, isSet));
} }
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicSet<K> other) { public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicSet<K> other, boolean isSet) {
return intercept(new EconomicMapImpl<>(strategy, other)); return intercept(new EconomicMapImpl<>(strategy, other, isSet));
} }
private EconomicMapImpl(Equivalence strategy) { private EconomicMapImpl(Equivalence strategy, boolean isSet) {
if (strategy == Equivalence.IDENTITY) { if (strategy == Equivalence.IDENTITY) {
this.strategy = null; this.strategy = null;
} else { } else {
this.strategy = strategy; this.strategy = strategy;
} }
this.isSet = isSet;
} }
private EconomicMapImpl(Equivalence strategy, int initialCapacity) { private EconomicMapImpl(Equivalence strategy, int initialCapacity, boolean isSet) {
this(strategy); this(strategy, isSet);
init(initialCapacity); init(initialCapacity);
} }
private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicMap<K, V> other) { private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicMap<K, V> other, boolean isSet) {
this(strategy); this(strategy, isSet);
if (!initFrom(other)) { if (!initFrom(other)) {
init(other.size()); init(other.size());
putAll(other); putAll(other);
} }
} }
private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicSet<K> other) { private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicSet<K> other, boolean isSet) {
this(strategy); this(strategy, isSet);
if (!initFrom(other)) { if (!initFrom(other)) {
init(other.size()); init(other.size());
addAll(other); addAll(other);
@ -807,13 +803,22 @@ public final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicS
return object; return object;
} }
private final boolean isSet;
@Override @Override
public String toString() { public String toString() {
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
builder.append("map(size=").append(size()).append(", {"); builder.append(isSet ? "set(size=" : "map(size=").append(size()).append(", {");
String sep = "";
MapCursor<K, V> cursor = getEntries(); MapCursor<K, V> cursor = getEntries();
while (cursor.advance()) { while (cursor.advance()) {
builder.append("(").append(cursor.getKey()).append(",").append(cursor.getValue()).append("),"); builder.append(sep);
if (isSet) {
builder.append(cursor.getKey());
} else {
builder.append("(").append(cursor.getKey()).append(",").append(cursor.getValue()).append(")");
}
sep = ",";
} }
builder.append("})"); builder.append("})");
return builder.toString(); return builder.toString();

View File

@ -4,7 +4,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -20,56 +22,109 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.util; package org.graalvm.collections;
import java.util.Iterator; import java.util.Iterator;
import org.graalvm.util.impl.EconomicMapImpl;
/** /**
* Memory efficient set data structure. * Memory efficient set data structure.
*
* @since 1.0
*/ */
public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> { public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
/**
* Adds {@code element} to this set if it is not already present.
*
* @return {@code true} if this set did not already contain {@code element}.
* @since 1.0
*/
boolean add(E element); boolean add(E element);
/**
* Removes {@code element} from this set if it is present. This set will not contain
* {@code element} once the call returns.
*
* @since 1.0
*/
void remove(E element); void remove(E element);
/**
* Removes all of the elements from this set. The set will be empty after this call returns.
*
* @since 1.0
*/
void clear(); void clear();
default void addAll(EconomicSet<E> values) { /**
addAll(values.iterator()); * Adds all of the elements in {@code other} to this set if they're not already present.
*
* @since 1.0
*/
default void addAll(EconomicSet<E> other) {
addAll(other.iterator());
} }
/**
* Adds all of the elements in {@code values} to this set if they're not already present.
*
* @since 1.0
*/
default void addAll(Iterable<E> values) { default void addAll(Iterable<E> values) {
addAll(values.iterator()); addAll(values.iterator());
} }
default void addAll(Iterator<E> values) { /**
while (values.hasNext()) { * Adds all of the elements enumerated by {@code iterator} to this set if they're not already
add(values.next()); * present.
*
* @since 1.0
*/
default void addAll(Iterator<E> iterator) {
while (iterator.hasNext()) {
add(iterator.next());
} }
} }
default void removeAll(EconomicSet<E> values) { /**
removeAll(values.iterator()); * Removes from this set all of its elements that are contained in {@code other}.
*
* @since 1.0
*/
default void removeAll(EconomicSet<E> other) {
removeAll(other.iterator());
} }
/**
* Removes from this set all of its elements that are contained in {@code values}.
*
* @since 1.0
*/
default void removeAll(Iterable<E> values) { default void removeAll(Iterable<E> values) {
removeAll(values.iterator()); removeAll(values.iterator());
} }
default void removeAll(Iterator<E> values) { /**
while (values.hasNext()) { * Removes from this set all of its elements that are enumerated by {@code iterator}.
remove(values.next()); *
* @since 1.0
*/
default void removeAll(Iterator<E> iterator) {
while (iterator.hasNext()) {
remove(iterator.next());
} }
} }
default void retainAll(EconomicSet<E> values) { /**
* Removes from this set all of its elements that are not contained in {@code other}.
*
* @since 1.0
*/
default void retainAll(EconomicSet<E> other) {
Iterator<E> iterator = iterator(); Iterator<E> iterator = iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
E key = iterator.next(); E key = iterator.next();
if (!values.contains(key)) { if (!other.contains(key)) {
iterator.remove(); iterator.remove();
} }
} }
@ -78,6 +133,8 @@ public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
/** /**
* Creates a new set guaranteeing insertion order when iterating over its elements with the * Creates a new set guaranteeing insertion order when iterating over its elements with the
* default {@link Equivalence#DEFAULT} comparison strategy. * default {@link Equivalence#DEFAULT} comparison strategy.
*
* @since 1.0
*/ */
static <E> EconomicSet<E> create() { static <E> EconomicSet<E> create() {
return EconomicSet.create(Equivalence.DEFAULT); return EconomicSet.create(Equivalence.DEFAULT);
@ -85,15 +142,19 @@ public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
/** /**
* Creates a new set guaranteeing insertion order when iterating over its elements. * Creates a new set guaranteeing insertion order when iterating over its elements.
*
* @since 1.0
*/ */
static <E> EconomicSet<E> create(Equivalence strategy) { static <E> EconomicSet<E> create(Equivalence strategy) {
return EconomicMapImpl.create(strategy); return EconomicMapImpl.create(strategy, true);
} }
/** /**
* Creates a new set guaranteeing insertion order when iterating over its elements with the * Creates a new set guaranteeing insertion order when iterating over its elements with the
* default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the * default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
* specified collection. * specified collection.
*
* @since 1.0
*/ */
static <E> EconomicSet<E> create(int initialCapacity) { static <E> EconomicSet<E> create(int initialCapacity) {
return EconomicSet.create(Equivalence.DEFAULT, initialCapacity); return EconomicSet.create(Equivalence.DEFAULT, initialCapacity);
@ -103,6 +164,8 @@ public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
* Creates a new set guaranteeing insertion order when iterating over its elements with the * Creates a new set guaranteeing insertion order when iterating over its elements with the
* default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the * default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
* specified collection. * specified collection.
*
* @since 1.0
*/ */
static <E> EconomicSet<E> create(UnmodifiableEconomicSet<E> c) { static <E> EconomicSet<E> create(UnmodifiableEconomicSet<E> c) {
return EconomicSet.create(Equivalence.DEFAULT, c); return EconomicSet.create(Equivalence.DEFAULT, c);
@ -111,16 +174,20 @@ public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
/** /**
* Creates a new set guaranteeing insertion order when iterating over its elements and * Creates a new set guaranteeing insertion order when iterating over its elements and
* initializes with the given capacity. * initializes with the given capacity.
*
* @since 1.0
*/ */
static <E> EconomicSet<E> create(Equivalence strategy, int initialCapacity) { static <E> EconomicSet<E> create(Equivalence strategy, int initialCapacity) {
return EconomicMapImpl.create(strategy, initialCapacity); return EconomicMapImpl.create(strategy, initialCapacity, true);
} }
/** /**
* Creates a new set guaranteeing insertion order when iterating over its elements and inserts * Creates a new set guaranteeing insertion order when iterating over its elements and inserts
* all elements of the specified collection. * all elements of the specified collection.
*
* @since 1.0
*/ */
static <E> EconomicSet<E> create(Equivalence strategy, UnmodifiableEconomicSet<E> c) { static <E> EconomicSet<E> create(Equivalence strategy, UnmodifiableEconomicSet<E> c) {
return EconomicMapImpl.create(strategy, c); return EconomicMapImpl.create(strategy, c, true);
} }
} }

View File

@ -4,7 +4,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -20,11 +22,13 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.util; package org.graalvm.collections;
/** /**
* Strategy for comparing two objects. Default predefined strategies are {@link #DEFAULT}, * Strategy for comparing two objects. Default predefined strategies are {@link #DEFAULT},
* {@link #IDENTITY}, and {@link #IDENTITY_WITH_SYSTEM_HASHCODE}. * {@link #IDENTITY}, and {@link #IDENTITY_WITH_SYSTEM_HASHCODE}.
*
* @since 1.0
*/ */
public abstract class Equivalence { public abstract class Equivalence {
@ -32,6 +36,8 @@ public abstract class Equivalence {
* Default equivalence calling {@link #equals(Object)} to check equality and {@link #hashCode()} * Default equivalence calling {@link #equals(Object)} to check equality and {@link #hashCode()}
* for obtaining hash values. Do not change the logic of this class as it may be inlined in * for obtaining hash values. Do not change the logic of this class as it may be inlined in
* other places. * other places.
*
* @since 1.0
*/ */
public static final Equivalence DEFAULT = new Equivalence() { public static final Equivalence DEFAULT = new Equivalence() {
@ -49,6 +55,8 @@ public abstract class Equivalence {
/** /**
* Identity equivalence using {@code ==} to check equality and {@link #hashCode()} for obtaining * Identity equivalence using {@code ==} to check equality and {@link #hashCode()} for obtaining
* hash values. Do not change the logic of this class as it may be inlined in other places. * hash values. Do not change the logic of this class as it may be inlined in other places.
*
* @since 1.0
*/ */
public static final Equivalence IDENTITY = new Equivalence() { public static final Equivalence IDENTITY = new Equivalence() {
@ -67,6 +75,8 @@ public abstract class Equivalence {
* Identity equivalence using {@code ==} to check equality and * Identity equivalence using {@code ==} to check equality and
* {@link System#identityHashCode(Object)} for obtaining hash values. Do not change the logic of * {@link System#identityHashCode(Object)} for obtaining hash values. Do not change the logic of
* this class as it may be inlined in other places. * this class as it may be inlined in other places.
*
* @since 1.0
*/ */
public static final Equivalence IDENTITY_WITH_SYSTEM_HASHCODE = new Equivalence() { public static final Equivalence IDENTITY_WITH_SYSTEM_HASHCODE = new Equivalence() {
@ -83,11 +93,24 @@ public abstract class Equivalence {
/** /**
* Subclass for creating custom equivalence definitions. * Subclass for creating custom equivalence definitions.
*
* @since 1.0
*/ */
protected Equivalence() { protected Equivalence() {
} }
/**
* Returns {@code true} if the non-{@code null} arguments are equal to each other and
* {@code false} otherwise.
*
* @since 1.0
*/
public abstract boolean equals(Object a, Object b); public abstract boolean equals(Object a, Object b);
/**
* Returns the hash code of a non-{@code null} argument {@code o}.
*
* @since 1.0
*/
public abstract int hashCode(Object o); public abstract int hashCode(Object o);
} }

View File

@ -4,7 +4,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -20,16 +22,20 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.util; package org.graalvm.collections;
/** /**
* Cursor to iterate over a mutable map. * Cursor to iterate over a mutable map.
*
* @since 1.0
*/ */
public interface MapCursor<K, V> extends UnmodifiableMapCursor<K, V> { public interface MapCursor<K, V> extends UnmodifiableMapCursor<K, V> {
/** /**
* Remove the current entry from the map. May only be called once. After calling * Remove the current entry from the map. May only be called once. After calling
* {@link #remove()}, it is no longer valid to call {@link #getKey()} or {@link #getValue()} on * {@link #remove()}, it is no longer valid to call {@link #getKey()} or {@link #getValue()} on
* the current entry. * the current entry.
*
* @since 1.0
*/ */
void remove(); void remove();
} }

View File

@ -4,7 +4,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -20,24 +22,39 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.util; package org.graalvm.collections;
import java.util.Objects; import java.util.Objects;
/** /**
* Utility class representing a pair of values. * Utility class representing a pair of values.
*
* @since 1.0
*/ */
public final class Pair<L, R> { public final class Pair<L, R> {
private static final Pair<Object, Object> EMPTY = new Pair<>(null, null); private static final Pair<Object, Object> EMPTY = new Pair<>(null, null);
private final L left; private final L left;
private final R right; private final R right;
/**
* Returns an empty pair.
*
* @since 1.0
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <L, R> Pair<L, R> empty() { public static <L, R> Pair<L, R> empty() {
return (Pair<L, R>) EMPTY; return (Pair<L, R>) EMPTY;
} }
/**
* Constructs a pair with its left value being {@code left}, or returns an empty pair if
* {@code left} is null.
*
* @return the constructed pair or an empty pair if {@code left} is null.
* @since 1.0
*/
public static <L, R> Pair<L, R> createLeft(L left) { public static <L, R> Pair<L, R> createLeft(L left) {
if (left == null) { if (left == null) {
return empty(); return empty();
@ -46,6 +63,13 @@ public final class Pair<L, R> {
} }
} }
/**
* Constructs a pair with its right value being {@code right}, or returns an empty pair if
* {@code right} is null.
*
* @return the constructed pair or an empty pair if {@code right} is null.
* @since 1.0
*/
public static <L, R> Pair<L, R> createRight(R right) { public static <L, R> Pair<L, R> createRight(R right) {
if (right == null) { if (right == null) {
return empty(); return empty();
@ -54,6 +78,13 @@ public final class Pair<L, R> {
} }
} }
/**
* Constructs a pair with its left value being {@code left}, and its right value being
* {@code right}, or returns an empty pair if both inputs are null.
*
* @return the constructed pair or an empty pair if both inputs are null.
* @since 1.0
*/
public static <L, R> Pair<L, R> create(L left, R right) { public static <L, R> Pair<L, R> create(L left, R right) {
if (right == null && left == null) { if (right == null && left == null) {
return empty(); return empty();
@ -67,19 +98,39 @@ public final class Pair<L, R> {
this.right = right; this.right = right;
} }
/**
* Returns the left value of this pair.
*
* @since 1.0
*/
public L getLeft() { public L getLeft() {
return left; return left;
} }
/**
* Returns the right value of this pair.
*
* @since 1.0
*/
public R getRight() { public R getRight() {
return right; return right;
} }
/**
* {@inheritDoc}
*
* @since 1.0
*/
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hashCode(left) + 31 * Objects.hashCode(right); return Objects.hashCode(left) + 31 * Objects.hashCode(right);
} }
/**
* {@inheritDoc}
*
* @since 1.0
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object obj) {
@ -95,6 +146,11 @@ public final class Pair<L, R> {
return false; return false;
} }
/**
* {@inheritDoc}
*
* @since 1.0
*/
@Override @Override
public String toString() { public String toString() {
return String.format("(%s, %s)", left, right); return String.format("(%s, %s)", left, right);

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2017, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.collections;
/**
* Unmodifiable memory efficient map data structure.
*
* @since 1.0
*/
public interface UnmodifiableEconomicMap<K, V> {
/**
* Returns the value to which {@code key} is mapped, or {@code null} if this map contains no
* mapping for {@code key}.
*
* @since 1.0
*/
V get(K key);
/**
* Returns the value to which {@code key} is mapped, or {@code defaultValue} if this map
* contains no mapping for {@code key}.
*
* @since 1.0
*/
default V get(K key, V defaultValue) {
V v = get(key);
if (v == null) {
return defaultValue;
}
return v;
}
/**
* Returns {@code true} if this map contains a mapping for {@code key}.
*
* @since 1.0
*/
boolean containsKey(K key);
/**
* Returns the number of key-value mappings in this map.
*
* @since 1.0
*/
int size();
/**
* Returns {@code true} if this map contains no key-value mappings.
*
* @since 1.0
*/
boolean isEmpty();
/**
* Returns a {@link Iterable} view of the values contained in this map.
*
* @since 1.0
*/
Iterable<V> getValues();
/**
* Returns a {@link Iterable} view of the keys contained in this map.
*
* @since 1.0
*/
Iterable<K> getKeys();
/**
* Returns a {@link UnmodifiableMapCursor} view of the mappings contained in this map.
*
* @since 1.0
*/
UnmodifiableMapCursor<K, V> getEntries();
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -22,49 +22,56 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.options; package org.graalvm.collections;
/** /**
* Represents a set of option values based on an {@link OptionDescriptor}. * Unmodifiable memory efficient set data structure.
* *
* @since 1.0 * @since 1.0
*/ */
public interface OptionValues { public interface UnmodifiableEconomicSet<E> extends Iterable<E> {
/** /**
* Returns all available options. * Returns {@code true} if this set contains a mapping for the {@code element}.
* *
* @since 1.0 * @since 1.0
*/ */
OptionDescriptors getDescriptors(); boolean contains(E element);
/** /**
* Sets the value of {@code optionKey} to {@code value}. * Returns the number of elements in this set.
*
* @throws IllegalArgumentException if the given value is not {@link OptionType#validate(Object)
* validated} by the {@link OptionKey#getType() option type} of the key. Note that
* the operation succeeds if the option key is not described by any of the
* associated {@link #getDescriptors() descriptors}.
* *
* @since 1.0 * @since 1.0
*/ */
<T> void set(OptionKey<T> optionKey, T value); int size();
/** /**
* Returns the value of a given option. If no value is set or the key is not described by any * Returns {@code true} if this set contains no elements.
* {@link #getDescriptors() descriptors} the {@link OptionType#getDefaultValue() default value}
* of the given key is returned.
* *
* @since 1.0 * @since 1.0
*/ */
<T> T get(OptionKey<T> optionKey); boolean isEmpty();
/** /**
* Determines if a value for {@code optionKey} has been {@link #set} in this set of option * Stores all of the elements in this set into {@code target}. An
* values. * {@link UnsupportedOperationException} will be thrown if the length of {@code target} does not
* match the size of this set.
* *
* @return an array containing all the elements in this set.
* @throws UnsupportedOperationException if the length of {@code target} does not equal the size
* of this set.
* @since 1.0 * @since 1.0
*/ */
boolean hasBeenSet(OptionKey<?> optionKey); default E[] toArray(E[] target) {
if (target.length != size()) {
throw new UnsupportedOperationException("Length of target array must equal the size of the set.");
}
int index = 0;
for (E element : this) {
target[index++] = element;
}
return target;
}
} }

View File

@ -4,7 +4,9 @@
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as * under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. * published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* *
* This code is distributed in the hope that it will be useful, but WITHOUT * This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@ -20,26 +22,33 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.util; package org.graalvm.collections;
/** /**
* Cursor to iterate over a map without changing its contents. * Cursor to iterate over a map without changing its contents.
*
* @since 1.0
*/ */
public interface UnmodifiableMapCursor<K, V> { public interface UnmodifiableMapCursor<K, V> {
/** /**
* Advances to the next entry. * Advances to the next entry.
* *
* @return {@code true} if a next entry exists, {@code false} if there is no next entry. * @return {@code true} if a next entry exists, {@code false} if there is no next entry.
* @since 1.0
*/ */
boolean advance(); boolean advance();
/** /**
* The key of the current entry. * The key of the current entry.
*
* @since 1.0
*/ */
K getKey(); K getKey();
/** /**
* The value of the current entry. * The value of the current entry.
*
* @since 1.0
*/ */
V getValue(); V getValue();
} }

View File

@ -23,11 +23,11 @@
* questions. * questions.
*/ */
/** /**
* The Graal-SDK options package contains reusable collection classes for options. * The Graal-SDK collections package contains memory efficient data structures.
* *
* @see org.graalvm.options.OptionDescriptor * @see org.graalvm.collections.EconomicMap
* @see org.graalvm.options.OptionValues * @see org.graalvm.collections.EconomicSet
* *
* @since 1.0 * @since 1.0
*/ */
package org.graalvm.options; package org.graalvm.collections;

View File

@ -50,6 +50,21 @@ public class ProbabilityDirectiveTest extends GraalCompilerTest {
test("branchProbabilitySnippet", 5); test("branchProbabilitySnippet", 5);
} }
public static int branchProbabilitySnippet2(int arg) {
if (!GraalDirectives.injectBranchProbability(0.125, arg <= 0)) {
GraalDirectives.controlFlowAnchor(); // prevent removal of the if
return 2;
} else {
GraalDirectives.controlFlowAnchor(); // prevent removal of the if
return 1;
}
}
@Test
public void testBranchProbability2() {
test("branchProbabilitySnippet2", 5);
}
@Override @Override
protected boolean checkLowTierGraph(StructuredGraph graph) { protected boolean checkLowTierGraph(StructuredGraph graph) {
NodeIterable<IfNode> ifNodes = graph.getNodes(IfNode.TYPE); NodeIterable<IfNode> ifNodes = graph.getNodes(IfNode.TYPE);

View File

@ -49,6 +49,13 @@ public final class GraalDirectives {
public static void deoptimizeAndInvalidate() { public static void deoptimizeAndInvalidate() {
} }
/**
* Directive for the compiler to fall back to the bytecode interpreter at this point, invalidate
* the compiled code, record a speculation and reprofile the method.
*/
public static void deoptimizeAndInvalidateWithSpeculation() {
}
/** /**
* Returns a boolean value indicating whether the method is executed in Graal-compiled code. * Returns a boolean value indicating whether the method is executed in Graal-compiled code.
*/ */

View File

@ -26,15 +26,52 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.lang.reflect.Array;
import jdk.vm.ci.meta.Signature; import jdk.vm.ci.meta.Signature;
/** /**
* Denotes a method whose body is used by a compiler as the substitute (or intrinsification) of * Denotes a method whose body is used by a compiler as the substitute (or intrinsification) of
* another method. The exact method used to do the substitution is compiler dependent but every * another method. The exact mechanism used to do the substitution is compiler dependent but every
* compiler should require substitute methods to be annotated with {@link MethodSubstitution}. In * compiler should require substitute methods to be annotated with {@link MethodSubstitution}. In
* addition, a compiler is recommended to implement {@link MethodSubstitutionRegistry} to advertise * addition, a compiler is recommended to implement {@link MethodSubstitutionRegistry} to advertise
* the mechanism by which it supports registration of method substitutes. * the mechanism by which it supports registration of method substitutes.
*
* A compiler may support partial intrinsification where only a part of a method is implemented by
* the compiler. The unsupported path is expressed by a call to either the original or substitute
* method from within the substitute method. Such as call is a <i>partial intrinsic exit</i>.
*
* For example, here's a HotSpot specific intrinsic for {@link Array#newInstance(Class, int)} that
* only handles the case where the VM representation of the array class to be instantiated already
* exists:
*
* <pre>
* &#64;MethodSubstitution
* public static Object newInstance(Class<?> componentType, int length) {
* if (componentType == null || loadKlassFromObject(componentType, arrayKlassOffset(INJECTED_VMCONFIG), CLASS_ARRAY_KLASS_LOCATION).isNull()) {
* // Array class not yet created - exit the intrinsic and call the original method
* return newInstance(componentType, length);
* }
* return DynamicNewArrayNode.newArray(GraalDirectives.guardingNonNull(componentType), length, JavaKind.Object);
* }
* </pre>
*
* Here's the same intrinsification where the exit is expressed as a call to the original method:
*
* <pre>
* &#64;MethodSubstitution
* public static Object newInstance(Class<?> componentType, int length) {
* if (componentType == null || loadKlassFromObject(componentType, arrayKlassOffset(INJECTED_VMCONFIG), CLASS_ARRAY_KLASS_LOCATION).isNull()) {
* // Array class not yet created - exit the intrinsic and call the original method
* return java.lang.reflect.newInstance(componentType, length);
* }
* return DynamicNewArrayNode.newArray(GraalDirectives.guardingNonNull(componentType), length, JavaKind.Object);
* }
* </pre>
*
* A condition for a partial intrinsic exit is that it is uses the unmodified parameters of the
* substitute as arguments to the partial intrinsic exit call. There must also be no side effecting
* instruction between the start of the substitute method and the partial intrinsic exit.
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)

View File

@ -90,4 +90,12 @@ public interface SnippetReflectionProvider {
* if this provider cannot provide a value of the requested type * if this provider cannot provide a value of the requested type
*/ */
<T> T getInjectedNodeIntrinsicParameter(Class<T> type); <T> T getInjectedNodeIntrinsicParameter(Class<T> type);
/**
* Get the original Java class corresponding to a {@link ResolvedJavaType}.
*
* @param type the type for which the original Java class is requested
* @return the original Java class corresponding to the {@code type} parameter
*/
Class<?> originalClass(ResolvedJavaType type);
} }

View File

@ -22,9 +22,19 @@
*/ */
package org.graalvm.compiler.api.runtime; package org.graalvm.compiler.api.runtime;
import jdk.vm.ci.common.JVMCIError;
public interface GraalRuntime { public interface GraalRuntime {
String getName(); String getName();
<T> T getCapability(Class<T> clazz); <T> T getCapability(Class<T> clazz);
default <T> T getRequiredCapability(Class<T> clazz) {
T ret = getCapability(clazz);
if (ret == null) {
throw new JVMCIError("The VM does not expose the required Graal capability %s.", clazz.getName());
}
return ret;
}
} }

View File

@ -208,7 +208,6 @@ public class AMD64Assembler extends Assembler {
} }
private static class VexOpcode { private static class VexOpcode {
private static final int VEX_OPCODE_NONE = 0x0;
private static final int VEX_OPCODE_0F = 0x1; private static final int VEX_OPCODE_0F = 0x1;
private static final int VEX_OPCODE_0F_38 = 0x2; private static final int VEX_OPCODE_0F_38 = 0x2;
private static final int VEX_OPCODE_0F_3A = 0x3; private static final int VEX_OPCODE_0F_3A = 0x3;
@ -861,9 +860,26 @@ public class AMD64Assembler extends Assembler {
break; break;
} }
int opc = 0;
if (isSimd) {
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
isSimd = false;
break;
}
}
if (isSimd) { if (isSimd) {
int pre; int pre;
int opc;
boolean rexVexW = (size == QWORD) ? true : false; boolean rexVexW = (size == QWORD) ? true : false;
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
int curPrefix = size.sizePrefix | prefix1; int curPrefix = size.sizePrefix | prefix1;
@ -881,20 +897,6 @@ public class AMD64Assembler extends Assembler {
pre = VexSimdPrefix.VEX_SIMD_NONE; pre = VexSimdPrefix.VEX_SIMD_NONE;
break; break;
} }
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
opc = VexOpcode.VEX_OPCODE_NONE;
break;
}
int encode; int encode;
if (noNds) { if (noNds) {
encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes); encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes);
@ -938,9 +940,26 @@ public class AMD64Assembler extends Assembler {
break; break;
} }
int opc = 0;
if (isSimd) {
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
isSimd = false;
break;
}
}
if (isSimd) { if (isSimd) {
int pre; int pre;
int opc;
boolean rexVexW = (size == QWORD) ? true : false; boolean rexVexW = (size == QWORD) ? true : false;
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
int curPrefix = size.sizePrefix | prefix1; int curPrefix = size.sizePrefix | prefix1;
@ -958,20 +977,6 @@ public class AMD64Assembler extends Assembler {
pre = VexSimdPrefix.VEX_SIMD_NONE; pre = VexSimdPrefix.VEX_SIMD_NONE;
break; break;
} }
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
opc = VexOpcode.VEX_OPCODE_NONE;
break;
}
if (noNds) { if (noNds) {
asm.simdPrefix(dst, Register.None, src, pre, opc, attributes); asm.simdPrefix(dst, Register.None, src, pre, opc, attributes);
} else { } else {
@ -1055,8 +1060,7 @@ public class AMD64Assembler extends Assembler {
opc = VexOpcode.VEX_OPCODE_0F_3A; opc = VexOpcode.VEX_OPCODE_0F_3A;
break; break;
default: default:
opc = VexOpcode.VEX_OPCODE_NONE; throw GraalError.shouldNotReachHere("invalid VEX instruction prefix");
break;
} }
int encode; int encode;
encode = asm.simdPrefixAndEncode(dst, nds, src, pre, opc, attributes); encode = asm.simdPrefixAndEncode(dst, nds, src, pre, opc, attributes);
@ -1096,8 +1100,7 @@ public class AMD64Assembler extends Assembler {
opc = VexOpcode.VEX_OPCODE_0F_3A; opc = VexOpcode.VEX_OPCODE_0F_3A;
break; break;
default: default:
opc = VexOpcode.VEX_OPCODE_NONE; throw GraalError.shouldNotReachHere("invalid VEX instruction prefix");
break;
} }
asm.simdPrefix(dst, nds, src, pre, opc, attributes); asm.simdPrefix(dst, nds, src, pre, opc, attributes);
asm.emitByte(op); asm.emitByte(op);
@ -1163,9 +1166,26 @@ public class AMD64Assembler extends Assembler {
break; break;
} }
int opc = 0;
if (isSimd) {
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
isSimd = false;
break;
}
}
if (isSimd) { if (isSimd) {
int pre; int pre;
int opc;
boolean rexVexW = (size == QWORD) ? true : false; boolean rexVexW = (size == QWORD) ? true : false;
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
int curPrefix = size.sizePrefix | prefix1; int curPrefix = size.sizePrefix | prefix1;
@ -1183,20 +1203,6 @@ public class AMD64Assembler extends Assembler {
pre = VexSimdPrefix.VEX_SIMD_NONE; pre = VexSimdPrefix.VEX_SIMD_NONE;
break; break;
} }
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
opc = VexOpcode.VEX_OPCODE_NONE;
break;
}
int encode; int encode;
if (noNds) { if (noNds) {
encode = asm.simdPrefixAndEncode(src, Register.None, dst, pre, opc, attributes); encode = asm.simdPrefixAndEncode(src, Register.None, dst, pre, opc, attributes);
@ -1222,9 +1228,26 @@ public class AMD64Assembler extends Assembler {
break; break;
} }
int opc = 0;
if (isSimd) {
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
isSimd = false;
break;
}
}
if (isSimd) { if (isSimd) {
int pre; int pre;
int opc;
boolean rexVexW = (size == QWORD) ? true : false; boolean rexVexW = (size == QWORD) ? true : false;
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
int curPrefix = size.sizePrefix | prefix1; int curPrefix = size.sizePrefix | prefix1;
@ -1242,20 +1265,6 @@ public class AMD64Assembler extends Assembler {
pre = VexSimdPrefix.VEX_SIMD_NONE; pre = VexSimdPrefix.VEX_SIMD_NONE;
break; break;
} }
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
opc = VexOpcode.VEX_OPCODE_NONE;
break;
}
asm.simdPrefix(src, Register.None, dst, pre, opc, attributes); asm.simdPrefix(src, Register.None, dst, pre, opc, attributes);
asm.emitByte(op); asm.emitByte(op);
asm.emitOperandHelper(src, dst, 0); asm.emitOperandHelper(src, dst, 0);
@ -1390,9 +1399,26 @@ public class AMD64Assembler extends Assembler {
break; break;
} }
int opc = 0;
if (isSimd) {
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
isSimd = false;
break;
}
}
if (isSimd) { if (isSimd) {
int pre; int pre;
int opc;
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
int curPrefix = size.sizePrefix | prefix1; int curPrefix = size.sizePrefix | prefix1;
switch (curPrefix) { switch (curPrefix) {
@ -1409,20 +1435,6 @@ public class AMD64Assembler extends Assembler {
pre = VexSimdPrefix.VEX_SIMD_NONE; pre = VexSimdPrefix.VEX_SIMD_NONE;
break; break;
} }
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
opc = VexOpcode.VEX_OPCODE_NONE;
break;
}
int encode; int encode;
if (noNds) { if (noNds) {
encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes); encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes);
@ -1453,9 +1465,26 @@ public class AMD64Assembler extends Assembler {
break; break;
} }
int opc = 0;
if (isSimd) {
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
isSimd = false;
break;
}
}
if (isSimd) { if (isSimd) {
int pre; int pre;
int opc;
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target); AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
int curPrefix = size.sizePrefix | prefix1; int curPrefix = size.sizePrefix | prefix1;
switch (curPrefix) { switch (curPrefix) {
@ -1472,21 +1501,6 @@ public class AMD64Assembler extends Assembler {
pre = VexSimdPrefix.VEX_SIMD_NONE; pre = VexSimdPrefix.VEX_SIMD_NONE;
break; break;
} }
switch (prefix2) {
case P_0F:
opc = VexOpcode.VEX_OPCODE_0F;
break;
case P_0F38:
opc = VexOpcode.VEX_OPCODE_0F_38;
break;
case P_0F3A:
opc = VexOpcode.VEX_OPCODE_0F_3A;
break;
default:
opc = VexOpcode.VEX_OPCODE_NONE;
break;
}
if (noNds) { if (noNds) {
asm.simdPrefix(dst, Register.None, src, pre, opc, attributes); asm.simdPrefix(dst, Register.None, src, pre, opc, attributes);
} else { } else {

View File

@ -33,9 +33,9 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.graalvm.collections.EconomicSet;
import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.graph.NodeSourcePosition; import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.util.EconomicSet;
import jdk.vm.ci.code.DebugInfo; import jdk.vm.ci.code.DebugInfo;
import jdk.vm.ci.code.StackSlot; import jdk.vm.ci.code.StackSlot;

View File

@ -40,7 +40,7 @@ public final class DataSection implements Iterable<Data> {
public interface Patches { public interface Patches {
void registerPatch(VMConstant c); void registerPatch(int position, VMConstant c);
} }
public abstract static class Data { public abstract static class Data {

View File

@ -27,7 +27,6 @@ import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.type.AbstractPointerStamp; import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
import org.graalvm.compiler.core.common.type.IntegerStamp; import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.PrimitiveStamp;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph;
@ -107,7 +106,9 @@ public class AMD64AddressLowering extends AddressLowering {
ret.setBase(add.getX()); ret.setBase(add.getX());
ret.setIndex(considerNegation(graph, add.getY(), isBaseNegated)); ret.setIndex(considerNegation(graph, add.getY(), isBaseNegated));
return true; return true;
} else if (ret.getBase() == null && ret.getIndex() instanceof AddNode) { }
if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
AddNode add = (AddNode) ret.getIndex(); AddNode add = (AddNode) ret.getIndex();
ret.setBase(considerNegation(graph, add.getX(), isIndexNegated)); ret.setBase(considerNegation(graph, add.getX(), isIndexNegated));
ret.setIndex(add.getY()); ret.setIndex(add.getY());
@ -188,7 +189,7 @@ public class AMD64AddressLowering extends AddressLowering {
return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement); return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
} else { } else {
if (node.stamp(NodeView.DEFAULT) instanceof IntegerStamp) { if (node.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
assert PrimitiveStamp.getBits(node.stamp(NodeView.DEFAULT)) == ADDRESS_BITS; assert IntegerStamp.getBits(node.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
/* /*
* we can't swallow zero-extends because of multiple reasons: * we can't swallow zero-extends because of multiple reasons:

View File

@ -0,0 +1,98 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.amd64;
import jdk.vm.ci.code.Register;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.type.StampFactory;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.CompressionNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
public abstract class AMD64CompressAddressLowering extends AMD64AddressLowering {
private static final CounterKey counterFoldedUncompressDuringAddressLowering = DebugContext.counter("FoldedUncompressDuringAddressLowering");
@Override
protected final boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated) {
if (super.improve(graph, debug, addr, isBaseNegated, isIndexNegated)) {
return true;
}
if (!isBaseNegated && !isIndexNegated && addr.getScale() == AMD64Address.Scale.Times1) {
ValueNode base = addr.getBase();
ValueNode index = addr.getIndex();
if (tryToImproveUncompression(addr, index, base) || tryToImproveUncompression(addr, base, index)) {
counterFoldedUncompressDuringAddressLowering.increment(debug);
return true;
}
}
return false;
}
private boolean tryToImproveUncompression(AMD64AddressNode addr, ValueNode value, ValueNode other) {
if (value instanceof CompressionNode) {
CompressionNode compression = (CompressionNode) value;
if (compression.getOp() == CompressionNode.CompressionOp.Uncompress && improveUncompression(addr, compression, other)) {
return true;
}
}
return false;
}
protected abstract boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other);
@NodeInfo(cycles = CYCLES_0, size = SIZE_0)
public static class HeapBaseNode extends FloatingNode implements LIRLowerable {
public static final NodeClass<HeapBaseNode> TYPE = NodeClass.create(HeapBaseNode.class);
private final Register heapBaseRegister;
public HeapBaseNode(Register heapBaseRegister) {
super(TYPE, StampFactory.pointer());
this.heapBaseRegister = heapBaseRegister;
}
@Override
public void generate(NodeLIRBuilderTool generator) {
LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
generator.setResult(this, heapBaseRegister.asValue(kind));
}
}
}

View File

@ -26,14 +26,14 @@ package org.graalvm.compiler.core.amd64;
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.QWORD;
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD; import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.Equivalence;
import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.lir.VirtualStackSlot; import org.graalvm.compiler.lir.VirtualStackSlot;
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction; import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
import org.graalvm.compiler.lir.amd64.AMD64Move.AMD64PushPopStackMove; import org.graalvm.compiler.lir.amd64.AMD64Move.AMD64PushPopStackMove;
import org.graalvm.compiler.lir.framemap.FrameMapBuilder; import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory;
import org.graalvm.util.Equivalence;
import org.graalvm.util.EconomicMap;
import jdk.vm.ci.amd64.AMD64Kind; import jdk.vm.ci.amd64.AMD64Kind;
import jdk.vm.ci.code.Architecture; import jdk.vm.ci.code.Architecture;

View File

@ -44,6 +44,7 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp; import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.NumUtil; import org.graalvm.compiler.core.common.NumUtil;
import org.graalvm.compiler.core.common.calc.CanonicalCondition;
import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.gen.NodeLIRBuilder; import org.graalvm.compiler.core.gen.NodeLIRBuilder;
import org.graalvm.compiler.core.gen.NodeMatchRules; import org.graalvm.compiler.core.gen.NodeMatchRules;
@ -128,7 +129,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
} }
protected ComplexMatchResult emitCompareBranchMemory(IfNode ifNode, CompareNode compare, ValueNode value, LIRLowerableAccess access) { protected ComplexMatchResult emitCompareBranchMemory(IfNode ifNode, CompareNode compare, ValueNode value, LIRLowerableAccess access) {
Condition cond = compare.condition(); Condition cond = compare.condition().asCondition();
AMD64Kind kind = getMemoryKind(access); AMD64Kind kind = getMemoryKind(access);
boolean matchedAsConstant = false; // For assertion checking boolean matchedAsConstant = false; // For assertion checking
@ -303,7 +304,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
@MatchRule("(If (FloatEquals=compare value ValueCompareAndSwap=cas))") @MatchRule("(If (FloatEquals=compare value ValueCompareAndSwap=cas))")
@MatchRule("(If (IntegerEquals=compare value ValueCompareAndSwap=cas))") @MatchRule("(If (IntegerEquals=compare value ValueCompareAndSwap=cas))")
public ComplexMatchResult ifCompareValueCas(IfNode root, CompareNode compare, ValueNode value, ValueCompareAndSwapNode cas) { public ComplexMatchResult ifCompareValueCas(IfNode root, CompareNode compare, ValueNode value, ValueCompareAndSwapNode cas) {
assert compare.condition() == Condition.EQ; assert compare.condition() == CanonicalCondition.EQ;
if (value == cas.getExpectedValue() && cas.usages().count() == 1) { if (value == cas.getExpectedValue() && cas.usages().count() == 1) {
return builder -> { return builder -> {
LIRKind kind = getLirKind(cas); LIRKind kind = getLirKind(cas);
@ -326,7 +327,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
@MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))") @MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) { public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
JavaConstant constant = value.asJavaConstant(); JavaConstant constant = value.asJavaConstant();
assert compare.condition() == Condition.EQ; assert compare.condition() == CanonicalCondition.EQ;
if (constant != null && cas.usages().count() == 1) { if (constant != null && cas.usages().count() == 1) {
long constantValue = constant.asLong(); long constantValue = constant.asLong();
boolean successIsTrue; boolean successIsTrue;

View File

@ -232,6 +232,9 @@ public final class GraalOptions {
@Option(help = "", type = OptionType.Debug) @Option(help = "", type = OptionType.Debug)
public static final OptionKey<Boolean> OptScheduleOutOfLoops = new OptionKey<>(true); public static final OptionKey<Boolean> OptScheduleOutOfLoops = new OptionKey<>(true);
@Option(help = "", type = OptionType.Debug)
public static final OptionKey<Boolean> GuardPriorities = new OptionKey<>(true);
@Option(help = "", type = OptionType.Debug) @Option(help = "", type = OptionType.Debug)
public static final OptionKey<Boolean> OptEliminateGuards = new OptionKey<>(true); public static final OptionKey<Boolean> OptEliminateGuards = new OptionKey<>(true);
@ -271,4 +274,7 @@ public final class GraalOptions {
@Option(help = "Enable experimental Trace Register Allocation.", type = OptionType.Debug) @Option(help = "Enable experimental Trace Register Allocation.", type = OptionType.Debug)
public static final OptionKey<Boolean> TraceRA = new OptionKey<>(false); public static final OptionKey<Boolean> TraceRA = new OptionKey<>(false);
@Option(help = "How to trace inlining decisions, one of: None, Linear, Tree", type = OptionType.Debug)
public static final OptionKey<TraceInliningMode> TraceInlining = new OptionKey<>(TraceInliningMode.None);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -20,29 +20,20 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.util; package org.graalvm.compiler.core.common;
/** public enum TraceInliningMode {
* Unmodifiable memory efficient set data structure. None(false),
*/ Linear(true),
public interface UnmodifiableEconomicSet<E> extends Iterable<E> { Tree(true);
boolean contains(E element); private final boolean tracing;
int size(); TraceInliningMode(boolean tracing) {
this.tracing = tracing;
}
boolean isEmpty(); public boolean isTracing() {
return tracing;
default E[] toArray(E[] target) {
if (target.length != size()) {
throw new UnsupportedOperationException("Length of target array must equal the size of the set.");
}
int index = 0;
for (E element : this) {
target[index++] = element;
}
return target;
} }
} }

View File

@ -22,9 +22,9 @@
*/ */
package org.graalvm.compiler.core.common.alloc; package org.graalvm.compiler.core.common.alloc;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.Equivalence;
import org.graalvm.compiler.core.common.GraalOptions; import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.Equivalence;
import jdk.vm.ci.code.Register; import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory; import jdk.vm.ci.code.Register.RegisterCategory;

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2009, 2015, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.common.calc;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.PrimitiveConstant;
public enum CanonicalCondition {
EQ(Condition.EQ),
LT(Condition.LT),
BT(Condition.BT);
private final Condition condition;
CanonicalCondition(Condition condition) {
assert condition.isCanonical();
this.condition = condition;
}
public Condition asCondition() {
return condition;
}
public boolean foldCondition(Constant lt, Constant rt, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) {
return asCondition().foldCondition(lt, rt, constantReflection, unorderedIsTrue);
}
public boolean foldCondition(PrimitiveConstant lp, PrimitiveConstant rp, boolean unorderedIsTrue) {
return asCondition().foldCondition(lp, rp, unorderedIsTrue);
}
}

View File

@ -115,6 +115,55 @@ public enum Condition {
throw new IllegalArgumentException(this.toString()); throw new IllegalArgumentException(this.toString());
} }
public static final class CanonicalizedCondition {
private final CanonicalCondition canonicalCondition;
private final boolean mirror;
private final boolean negate;
private CanonicalizedCondition(CanonicalCondition canonicalCondition, boolean mirror, boolean negate) {
this.canonicalCondition = canonicalCondition;
this.mirror = mirror;
this.negate = negate;
}
public CanonicalCondition getCanonicalCondition() {
return canonicalCondition;
}
public boolean mustMirror() {
return mirror;
}
public boolean mustNegate() {
return negate;
}
}
public CanonicalizedCondition canonicalize() {
CanonicalCondition canonicalCondition;
switch (this) {
case EQ:
case NE:
canonicalCondition = CanonicalCondition.EQ;
break;
case LT:
case LE:
case GT:
case GE:
canonicalCondition = CanonicalCondition.LT;
break;
case BT:
case BE:
case AT:
case AE:
canonicalCondition = CanonicalCondition.BT;
break;
default:
throw new IllegalArgumentException(this.toString());
}
return new CanonicalizedCondition(canonicalCondition, canonicalMirror(), canonicalNegate());
}
/** /**
* Given a condition and its negation, this method returns true for one of the two and false for * Given a condition and its negation, this method returns true for one of the two and false for
* the other one. This can be used to keep comparisons in a canonical form. * the other one. This can be used to keep comparisons in a canonical form.
@ -151,7 +200,7 @@ public enum Condition {
* Returns true if the condition needs to be mirrored to get to a canonical condition. The * Returns true if the condition needs to be mirrored to get to a canonical condition. The
* result of the mirroring operation might still need to be negated to achieve a canonical form. * result of the mirroring operation might still need to be negated to achieve a canonical form.
*/ */
public boolean canonicalMirror() { private boolean canonicalMirror() {
switch (this) { switch (this) {
case EQ: case EQ:
return false; return false;
@ -181,7 +230,7 @@ public enum Condition {
* Returns true if the condition needs to be negated to get to a canonical condition. The result * Returns true if the condition needs to be negated to get to a canonical condition. The result
* of the negation might still need to be mirrored to achieve a canonical form. * of the negation might still need to be mirrored to achieve a canonical form.
*/ */
public boolean canonicalNegate() { private boolean canonicalNegate() {
switch (this) { switch (this) {
case EQ: case EQ:
return false; return false;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -20,32 +20,13 @@
* or visit www.oracle.com if you need additional information or have any * or visit www.oracle.com if you need additional information or have any
* questions. * questions.
*/ */
package org.graalvm.util; package org.graalvm.compiler.core.common.spi;
/** import jdk.vm.ci.meta.JavaKind;
* Unmodifiable memory efficient map data structure.
*/
public interface UnmodifiableEconomicMap<K, V> {
V get(K key); public interface ArrayOffsetProvider {
default V get(K key, V defaultValue) { int arrayBaseOffset(JavaKind elementKind);
V v = get(key);
if (v == null) {
return defaultValue;
}
return v;
}
boolean containsKey(K key); int arrayScalingFactor(JavaKind elementKind);
int size();
boolean isEmpty();
Iterable<V> getValues();
Iterable<K> getKeys();
UnmodifiableMapCursor<K, V> getEntries();
} }

View File

@ -40,4 +40,5 @@ public interface CodeGenProviders {
ConstantReflectionProvider getConstantReflection(); ConstantReflectionProvider getConstantReflection();
ArrayOffsetProvider getArrayOffsetProvider();
} }

View File

@ -28,6 +28,9 @@ import java.util.Arrays;
import java.util.Objects; import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaKind;
import org.graalvm.compiler.core.common.calc.FloatConvert; import org.graalvm.compiler.core.common.calc.FloatConvert;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Add; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Add;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.And; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.And;
@ -51,9 +54,6 @@ import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Not;
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Sqrt; import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Sqrt;
import org.graalvm.util.CollectionsUtil; import org.graalvm.util.CollectionsUtil;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaKind;
/** /**
* Information about arithmetic operations. * Information about arithmetic operations.
*/ */

View File

@ -25,8 +25,8 @@ package org.graalvm.compiler.core.common.util;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.graalvm.util.EconomicMap; import org.graalvm.collections.EconomicMap;
import org.graalvm.util.Equivalence; import org.graalvm.collections.Equivalence;
/** /**
* Creates an array of T objects order by the occurrence frequency of each object. The most * Creates an array of T objects order by the occurrence frequency of each object. The most

View File

@ -58,6 +58,9 @@ import javax.tools.FileObject;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.StandardLocation; import javax.tools.StandardLocation;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Equivalence;
import org.graalvm.compiler.core.gen.NodeMatchRules; import org.graalvm.compiler.core.gen.NodeMatchRules;
import org.graalvm.compiler.core.match.ComplexMatchResult; import org.graalvm.compiler.core.match.ComplexMatchResult;
import org.graalvm.compiler.core.match.MatchRule; import org.graalvm.compiler.core.match.MatchRule;
@ -70,9 +73,6 @@ import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Position; import org.graalvm.compiler.graph.Position;
import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.serviceprovider.ServiceProvider; import org.graalvm.compiler.serviceprovider.ServiceProvider;
import org.graalvm.util.Equivalence;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.EconomicSet;
/** /**
* Processes classes annotated with {@link MatchRule}. A {@link MatchStatementSet} service is * Processes classes annotated with {@link MatchRule}. A {@link MatchStatementSet} service is

View File

@ -29,6 +29,7 @@ import static jdk.vm.ci.sparc.SPARCKind.WORD;
import static jdk.vm.ci.sparc.SPARCKind.XWORD; import static jdk.vm.ci.sparc.SPARCKind.XWORD;
import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.calc.CanonicalCondition;
import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.gen.NodeMatchRules; import org.graalvm.compiler.core.gen.NodeMatchRules;
import org.graalvm.compiler.core.match.ComplexMatchResult; import org.graalvm.compiler.core.match.ComplexMatchResult;
@ -147,7 +148,7 @@ public class SPARCNodeMatchRules extends NodeMatchRules {
@MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))") @MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) { public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
JavaConstant constant = value.asJavaConstant(); JavaConstant constant = value.asJavaConstant();
assert compare.condition() == Condition.EQ; assert compare.condition() == CanonicalCondition.EQ;
if (constant != null && cas.usages().count() == 1) { if (constant != null && cas.usages().count() == 1) {
long constantValue = constant.asLong(); long constantValue = constant.asLong();
boolean successIsTrue; boolean successIsTrue;

View File

@ -123,19 +123,19 @@ public class ConditionalEliminationTest11 extends ConditionalEliminationTestBase
public static int test6Snippet(int a) { public static int test6Snippet(int a) {
if ((a & 8) != 0) { if ((a & 8) != 0) {
GraalDirectives.deoptimizeAndInvalidate(); GraalDirectives.deoptimize();
} }
if ((a & 15) != 15) { if ((a & 15) != 15) {
GraalDirectives.deoptimizeAndInvalidate(); GraalDirectives.deoptimize();
} }
return 0; return 0;
} }
public static int reference6Snippet(int a) { public static int reference6Snippet(int a) {
if ((a & 8) != 0) { if ((a & 8) != 0) {
GraalDirectives.deoptimizeAndInvalidate(); GraalDirectives.deoptimize();
} }
GraalDirectives.deoptimizeAndInvalidate(); GraalDirectives.deoptimize();
return 0; return 0;
} }

View File

@ -74,7 +74,6 @@ public class ConditionalEliminationTestBase extends GraalCompilerTest {
new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context); new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
canonicalizer.apply(graph, context); canonicalizer.apply(graph, context);
canonicalizer.apply(graph, context); canonicalizer.apply(graph, context);
new ConvertDeoptimizeToGuardPhase().apply(graph, context);
} catch (Throwable t) { } catch (Throwable t) {
debug.handle(t); debug.handle(t);
} }
@ -86,7 +85,6 @@ public class ConditionalEliminationTestBase extends GraalCompilerTest {
} }
canonicalizer.apply(referenceGraph, context); canonicalizer.apply(referenceGraph, context);
canonicalizer.apply(referenceGraph, context); canonicalizer.apply(referenceGraph, context);
new ConvertDeoptimizeToGuardPhase().apply(graph, context);
} catch (Throwable t) { } catch (Throwable t) {
debug.handle(t); debug.handle(t);
} }

View File

@ -25,14 +25,12 @@ package org.graalvm.compiler.core.test;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED; import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED; import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
import org.graalvm.compiler.nodes.NodeView;
import org.junit.Test;
import org.graalvm.compiler.api.directives.GraalDirectives; import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.graph.NodeClass; import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.loop.InductionVariable; import org.graalvm.compiler.loop.InductionVariable;
import org.graalvm.compiler.loop.LoopsData; import org.graalvm.compiler.loop.LoopsData;
import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode; import org.graalvm.compiler.nodes.calc.FloatingNode;
@ -42,6 +40,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.spi.LIRLowerable;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.junit.Test;
import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaMethod;
@ -117,6 +116,21 @@ public class CountedLoopTest extends GraalCompilerTest {
test("incrementSnippet", 0, 256, 3); test("incrementSnippet", 0, 256, 3);
} }
@Test
public void increment4() {
test("incrementSnippet", -10, Integer.MAX_VALUE, 1);
}
@Test
public void increment5() {
test("incrementSnippet", 256, 256, 1);
}
@Test
public void increment6() {
test("incrementSnippet", 257, 256, 1);
}
public static Result incrementEqSnippet(int start, int limit, int step) { public static Result incrementEqSnippet(int start, int limit, int step) {
int i; int i;
int inc = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive int inc = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive
@ -144,6 +158,21 @@ public class CountedLoopTest extends GraalCompilerTest {
test("incrementEqSnippet", 0, 256, 3); test("incrementEqSnippet", 0, 256, 3);
} }
@Test
public void incrementEq4() {
test("incrementEqSnippet", -10, 0, Integer.MAX_VALUE);
}
@Test
public void incrementEq5() {
test("incrementEqSnippet", 256, 256, 1);
}
@Test
public void incrementEq6() {
test("incrementEqSnippet", 257, 256, 1);
}
public static Result decrementSnippet(int start, int limit, int step) { public static Result decrementSnippet(int start, int limit, int step) {
int i; int i;
int dec = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive int dec = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive
@ -198,6 +227,11 @@ public class CountedLoopTest extends GraalCompilerTest {
test("decrementEqSnippet", 256, 0, 3); test("decrementEqSnippet", 256, 0, 3);
} }
@Test
public void decrementEq4() {
test("decrementEqSnippet", -10, 0, Integer.MAX_VALUE);
}
public static Result twoVariablesSnippet() { public static Result twoVariablesSnippet() {
Result ret = new Result(); Result ret = new Result();
int j = 0; int j = 0;

View File

@ -27,10 +27,10 @@ import java.nio.file.DirectoryStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.debug.DebugOptions; import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.junit.Test; import org.junit.Test;
/** /**

View File

@ -561,7 +561,7 @@ public abstract class GraalCompilerTest extends GraalTest {
* @return a scheduled textual dump of {@code graph} . * @return a scheduled textual dump of {@code graph} .
*/ */
protected static String getScheduledGraphString(StructuredGraph graph) { protected static String getScheduledGraphString(StructuredGraph graph) {
SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST); SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER);
schedule.apply(graph); schedule.apply(graph);
ScheduleResult scheduleResult = graph.getLastSchedule(); ScheduleResult scheduleResult = graph.getLastSchedule();

View File

@ -22,14 +22,14 @@
*/ */
package org.graalvm.compiler.core.test; package org.graalvm.compiler.core.test;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.debug.DebugContext.Scope; import org.graalvm.compiler.debug.DebugContext.Scope;
import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions; import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;

View File

@ -24,20 +24,29 @@ package org.graalvm.compiler.core.test;
import java.util.List; import java.util.List;
import org.junit.Assert;
import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeMap; import org.graalvm.compiler.graph.NodeMap;
import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult; import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
import org.graalvm.compiler.nodes.cfg.Block; import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.phases.schedule.SchedulePhase; import org.graalvm.compiler.phases.schedule.SchedulePhase;
import org.junit.Assert;
import jdk.vm.ci.meta.SpeculationLog;
public class GraphScheduleTest extends GraalCompilerTest { public class GraphScheduleTest extends GraalCompilerTest {
protected void assertOrderedAfterSchedule(StructuredGraph graph, Node a, Node b) { protected void assertOrderedAfterSchedule(StructuredGraph graph, Node a, Node b) {
SchedulePhase ibp = new SchedulePhase(SchedulePhase.SchedulingStrategy.LATEST); assertOrderedAfterSchedule(graph, SchedulePhase.SchedulingStrategy.LATEST, a, b);
}
protected void assertOrderedAfterSchedule(StructuredGraph graph, SchedulePhase.SchedulingStrategy strategy, Node a, Node b) {
SchedulePhase ibp = new SchedulePhase(strategy);
ibp.apply(graph); ibp.apply(graph);
assertOrderedAfterLastSchedule(graph, a, b);
}
protected void assertOrderedAfterLastSchedule(StructuredGraph graph, Node a, Node b) {
assertOrderedAfterSchedule(graph.getLastSchedule(), a, b); assertOrderedAfterSchedule(graph.getLastSchedule(), a, b);
} }
@ -48,7 +57,7 @@ public class GraphScheduleTest extends GraalCompilerTest {
if (bBlock == aBlock) { if (bBlock == aBlock) {
List<Node> instructions = ibp.nodesFor(bBlock); List<Node> instructions = ibp.nodesFor(bBlock);
Assert.assertTrue(instructions.indexOf(b) > instructions.indexOf(a)); Assert.assertTrue(a + " should be before " + b, instructions.indexOf(b) > instructions.indexOf(a));
} else { } else {
Block block = bBlock; Block block = bBlock;
while (block != null) { while (block != null) {
@ -60,4 +69,9 @@ public class GraphScheduleTest extends GraalCompilerTest {
Assert.fail("block of A doesn't dominate the block of B"); Assert.fail("block of A doesn't dominate the block of B");
} }
} }
@Override
protected SpeculationLog getSpeculationLog() {
return getCodeCache().createSpeculationLog();
}
} }

View File

@ -0,0 +1,131 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.test;
import static org.graalvm.compiler.graph.test.matchers.NodeIterableCount.hasCount;
import static org.graalvm.compiler.graph.test.matchers.NodeIterableIsEmpty.isNotEmpty;
import static org.junit.Assert.assertThat;
import static org.junit.Assume.assumeThat;
import static org.junit.Assume.assumeTrue;
import java.util.Iterator;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.graph.iterators.NodeIterable;
import org.graalvm.compiler.nodes.GuardNode;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.calc.IntegerLowerThanNode;
import org.graalvm.compiler.nodes.calc.IsNullNode;
import org.graalvm.compiler.nodes.spi.LoweringTool;
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.ConvertDeoptimizeToGuardPhase;
import org.graalvm.compiler.phases.common.FloatingReadPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.schedule.SchedulePhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.junit.Test;
public class GuardPrioritiesTest extends GraphScheduleTest {
private int[] array;
private int size;
public void growing(int e) {
if (size >= array.length) {
// grow
GraalDirectives.deoptimizeAndInvalidateWithSpeculation();
}
array[size++] = e;
}
@Test
public void growingTest() {
assumeTrue("GuardPriorities must be turned one", GraalOptions.GuardPriorities.getValue(getInitialOptions()));
StructuredGraph graph = prepareGraph("growing");
NodeIterable<GuardNode> guards = graph.getNodes(GuardNode.TYPE).filter(n -> n.inputs().filter(i -> i instanceof IntegerLowerThanNode).isNotEmpty());
assertThat(guards, isNotEmpty());
assumeThat(guards, hasCount(2));
Iterator<GuardNode> iterator = guards.iterator();
GuardNode g1 = iterator.next();
GuardNode g2 = iterator.next();
assertTrue("There should be one guard with speculation, the other one without", g1.getSpeculation().isNull() ^ g2.getSpeculation().isNull());
GuardNode withSpeculation = g1.getSpeculation().isNull() ? g2 : g1;
GuardNode withoutSpeculation = g1.getSpeculation().isNull() ? g1 : g2;
assertOrderedAfterSchedule(graph, SchedulePhase.SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER, withSpeculation, withoutSpeculation);
}
private StructuredGraph prepareGraph(String method) {
StructuredGraph graph = parseEager(method, StructuredGraph.AllowAssumptions.YES);
HighTierContext highTierContext = getDefaultHighTierContext();
CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
new ConvertDeoptimizeToGuardPhase().apply(graph, highTierContext);
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext);
new FloatingReadPhase().apply(graph);
return graph;
}
public int unknownCondition(Integer c, Object o, int[] a, Integer i) {
if (o != null) {
GraalDirectives.deoptimizeAndInvalidate();
}
if (i > 5560) {
GraalDirectives.deoptimizeAndInvalidate();
}
if (c >= 10) {
GraalDirectives.deoptimizeAndInvalidateWithSpeculation();
}
return array[8] + a[i];
}
@Test
public void unknownTest() {
assumeTrue("GuardPriorities must be turned one", GraalOptions.GuardPriorities.getValue(getInitialOptions()));
StructuredGraph graph = prepareGraph("unknownCondition");
new SchedulePhase(SchedulePhase.SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER).apply(graph);
for (GuardNode g1 : graph.getNodes(GuardNode.TYPE)) {
for (GuardNode g2 : graph.getNodes(GuardNode.TYPE)) {
if (g1.getSpeculation().isNull() ^ g2.getSpeculation().isNull()) {
GuardNode withSpeculation = g1.getSpeculation().isNull() ? g2 : g1;
GuardNode withoutSpeculation = g1.getSpeculation().isNull() ? g1 : g2;
if (withoutSpeculation.isNegated() && withoutSpeculation.getCondition() instanceof IsNullNode) {
IsNullNode isNullNode = (IsNullNode) withoutSpeculation.getCondition();
if (isNullNode.getValue() instanceof ParameterNode && ((ParameterNode) isNullNode.getValue()).index() == 1) {
// this is the null check before the speculative guard, it's the only
// one that should be above
assertOrderedAfterLastSchedule(graph, withoutSpeculation, withSpeculation);
continue;
}
}
assertOrderedAfterLastSchedule(graph, withSpeculation, withoutSpeculation);
}
}
}
}
}

View File

@ -44,7 +44,7 @@ public class LongNodeChainTest extends GraalCompilerTest {
public static final int N = 10000; public static final int N = 10000;
private static final SchedulingStrategy[] Strategies = new SchedulingStrategy[]{SchedulingStrategy.EARLIEST}; private static final SchedulingStrategy[] Strategies = new SchedulingStrategy[]{SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER};
@Test @Test
public void testLongAddChain() { public void testLongAddChain() {

View File

@ -31,13 +31,13 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.MapCursor;
import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionDescriptor; import org.graalvm.compiler.options.OptionDescriptor;
import org.graalvm.compiler.options.OptionDescriptors; import org.graalvm.compiler.options.OptionDescriptors;
import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.MapCursor;
/** /**
* An implementation of {@link OptionDescriptor} that uses reflection to create descriptors from a * An implementation of {@link OptionDescriptor} that uses reflection to create descriptors from a

View File

@ -70,7 +70,7 @@ public class SchedulingTest2 extends GraphScheduleTest {
returnNode.replaceAtPredecessor(beginNode); returnNode.replaceAtPredecessor(beginNode);
beginNode.setNext(returnNode); beginNode.setNext(returnNode);
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph"); debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.EARLIEST); SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER);
schedulePhase.apply(graph); schedulePhase.apply(graph);
ScheduleResult schedule = graph.getLastSchedule(); ScheduleResult schedule = graph.getLastSchedule();
BlockMap<List<Node>> blockToNodesMap = schedule.getBlockToNodesMap(); BlockMap<List<Node>> blockToNodesMap = schedule.getBlockToNodesMap();

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.core.test;
import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.java.BytecodeParserOptions;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.options.OptionValues;
import org.junit.Assert;
import org.junit.Test;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Tests that the defaults for {@link GraalOptions#TrivialInliningSize} and
* {@link BytecodeParserOptions#InlineDuringParsingMaxDepth} prevent explosive graph growth for code
* with small recursive methods.
*/
public class TrivialInliningExplosionTest extends GraalCompilerTest {
public static void trivial() {
trivial();
trivial();
trivial();
}
public static void main() {
trivial();
trivial();
trivial();
trivial();
trivial();
trivial();
trivial();
trivial();
trivial();
}
private int afterParseSize;
@Override
protected StructuredGraph parseForCompile(ResolvedJavaMethod method, CompilationIdentifier compilationId, OptionValues options) {
final StructuredGraph graph = super.parseForCompile(method, compilationId, options);
this.afterParseSize = graph.getNodeCount();
return graph;
}
@Test
public void test() {
ResolvedJavaMethod methodm0 = getResolvedJavaMethod("trivial");
Assert.assertTrue(methodm0.getCodeSize() <= GraalOptions.TrivialInliningSize.getValue(getInitialOptions()));
test("main");
int afterCompileSize = lastCompiledGraph.getNodeCount();
// The values of afterParseSize and afterCompileSize when this
// test was written were 849 and 848 respectively.
Assert.assertTrue(afterParseSize < 2000);
Assert.assertTrue(afterCompileSize < 2000);
}
}

View File

@ -24,6 +24,7 @@ package org.graalvm.compiler.core.test.inlining;
import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Optional; import static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Optional;
import org.graalvm.collections.EconomicSet;
import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.TTY; import org.graalvm.compiler.debug.TTY;
@ -43,7 +44,6 @@ import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.phases.tiers.PhaseContext; import org.graalvm.compiler.phases.tiers.PhaseContext;
import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase; import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase;
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase; import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
import org.graalvm.util.EconomicSet;
import org.junit.Test; import org.junit.Test;
import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaMethod;

View File

@ -25,6 +25,7 @@ package org.graalvm.compiler.core;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import org.graalvm.collections.EconomicSet;
import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext; import org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext;
import org.graalvm.compiler.core.common.GraalOptions; import org.graalvm.compiler.core.common.GraalOptions;
@ -64,7 +65,6 @@ import org.graalvm.compiler.phases.tiers.MidTierContext;
import org.graalvm.compiler.phases.tiers.Suites; import org.graalvm.compiler.phases.tiers.Suites;
import org.graalvm.compiler.phases.tiers.TargetProvider; import org.graalvm.compiler.phases.tiers.TargetProvider;
import org.graalvm.compiler.phases.util.Providers; import org.graalvm.compiler.phases.util.Providers;
import org.graalvm.util.EconomicSet;
import jdk.vm.ci.code.RegisterConfig; import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.code.TargetDescription;

View File

@ -26,6 +26,8 @@ import java.util.ArrayDeque;
import java.util.Arrays; import java.util.Arrays;
import java.util.Queue; import java.util.Queue;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.Equivalence;
import org.graalvm.compiler.debug.CounterKey; import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.GraalError;
@ -42,8 +44,6 @@ import org.graalvm.compiler.nodes.virtual.EscapeObjectState;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.compiler.virtual.nodes.MaterializedObjectState; import org.graalvm.compiler.virtual.nodes.MaterializedObjectState;
import org.graalvm.compiler.virtual.nodes.VirtualObjectState; import org.graalvm.compiler.virtual.nodes.VirtualObjectState;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.Equivalence;
import jdk.vm.ci.code.BytecodeFrame; import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.code.VirtualObject; import jdk.vm.ci.code.VirtualObject;

View File

@ -33,6 +33,8 @@ import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.UnmodifiableMapCursor;
import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.calc.Condition; import org.graalvm.compiler.core.common.calc.Condition;
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
@ -100,8 +102,6 @@ import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.graalvm.compiler.nodes.spi.NodeValueMap; import org.graalvm.compiler.nodes.spi.NodeValueMap;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.UnmodifiableMapCursor;
import jdk.vm.ci.code.CallingConvention; import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.StackSlot; import jdk.vm.ci.code.StackSlot;
@ -538,7 +538,8 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) { public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind(); PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
gen.emitCompareBranch(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability); gen.emitCompareBranch(kind, operand(compare.getX()), operand(compare.getY()), compare.condition().asCondition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor,
trueSuccessorProbability);
} }
public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) { public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
@ -566,7 +567,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
} else if (node instanceof CompareNode) { } else if (node instanceof CompareNode) {
CompareNode compare = (CompareNode) node; CompareNode compare = (CompareNode) node;
PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind(); PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
return gen.emitConditionalMove(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue); return gen.emitConditionalMove(kind, operand(compare.getX()), operand(compare.getY()), compare.condition().asCondition(), compare.unorderedIsTrue(), trueValue, falseValue);
} else if (node instanceof LogicConstantNode) { } else if (node instanceof LogicConstantNode) {
return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue); return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue);
} else if (node instanceof IntegerTestNode) { } else if (node instanceof IntegerTestNode) {

View File

@ -28,6 +28,8 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.Equivalence;
import org.graalvm.compiler.core.gen.NodeLIRBuilder; import org.graalvm.compiler.core.gen.NodeLIRBuilder;
import org.graalvm.compiler.core.match.MatchPattern.Result; import org.graalvm.compiler.core.match.MatchPattern.Result;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
@ -35,8 +37,6 @@ import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.nodes.calc.FloatingNode; import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.Equivalence;
/** /**
* Container for state captured during a match. * Container for state captured during a match.

View File

@ -27,6 +27,9 @@ import static org.graalvm.compiler.debug.DebugOptions.LogVerbose;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.Equivalence;
import org.graalvm.collections.MapCursor;
import org.graalvm.compiler.core.gen.NodeMatchRules; import org.graalvm.compiler.core.gen.NodeMatchRules;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.GraalError;
@ -36,9 +39,6 @@ import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.graph.Position; import org.graalvm.compiler.graph.Position;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.serviceprovider.GraalServices; import org.graalvm.compiler.serviceprovider.GraalServices;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.Equivalence;
import org.graalvm.util.MapCursor;
public class MatchRuleRegistry { public class MatchRuleRegistry {

View File

@ -22,6 +22,8 @@
*/ */
package org.graalvm.compiler.core.phases; package org.graalvm.compiler.core.phases;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Equivalence;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.Graph.NodeEvent; import org.graalvm.compiler.graph.Graph.NodeEvent;
import org.graalvm.compiler.graph.Graph.NodeEventScope; import org.graalvm.compiler.graph.Graph.NodeEventScope;
@ -32,8 +34,6 @@ import org.graalvm.compiler.phases.BasePhase;
import org.graalvm.compiler.phases.PhaseSuite; import org.graalvm.compiler.phases.PhaseSuite;
import org.graalvm.compiler.phases.common.util.HashSetNodeEventListener; import org.graalvm.compiler.phases.common.util.HashSetNodeEventListener;
import org.graalvm.compiler.phases.tiers.PhaseContext; import org.graalvm.compiler.phases.tiers.PhaseContext;
import org.graalvm.util.EconomicSet;
import org.graalvm.util.Equivalence;
/** /**
* A utility phase for detecting when a phase would change the graph and reporting extra information * A utility phase for detecting when a phase would change the graph and reporting extra information

View File

@ -24,6 +24,7 @@ package org.graalvm.compiler.core.target;
import java.util.ArrayList; import java.util.ArrayList;
import org.graalvm.collections.EconomicSet;
import org.graalvm.compiler.asm.Assembler; import org.graalvm.compiler.asm.Assembler;
import org.graalvm.compiler.code.CompilationResult; import org.graalvm.compiler.code.CompilationResult;
import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.common.CompilationIdentifier;
@ -44,7 +45,6 @@ import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.graalvm.compiler.phases.tiers.SuitesProvider; import org.graalvm.compiler.phases.tiers.SuitesProvider;
import org.graalvm.compiler.phases.tiers.TargetProvider; import org.graalvm.compiler.phases.tiers.TargetProvider;
import org.graalvm.compiler.phases.util.Providers; import org.graalvm.compiler.phases.util.Providers;
import org.graalvm.util.EconomicSet;
import jdk.vm.ci.code.BailoutException; import jdk.vm.ci.code.BailoutException;
import jdk.vm.ci.code.CodeCacheProvider; import jdk.vm.ci.code.CodeCacheProvider;
@ -204,31 +204,48 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
} }
try (DebugContext.Scope s2 = debug.scope("CodeInstall", debugContext); try (DebugContext.Scope s2 = debug.scope("CodeInstall", debugContext);
DebugContext.Activation a = debug.activate()) { DebugContext.Activation a = debug.activate()) {
for (CodeInstallationTask task : tasks) { preCodeInstallationTasks(tasks, compilationResult);
task.preProcess(compilationResult);
}
CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult); InstalledCode installedCode;
InstalledCode installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
// Run post-code installation tasks.
try { try {
for (CodeInstallationTask task : tasks) { CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
task.postProcess(installedCode); installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
}
for (CodeInstallationTask task : tasks) {
task.releaseInstallation(installedCode);
}
} catch (Throwable t) { } catch (Throwable t) {
installedCode.invalidate(); failCodeInstallationTasks(tasks, t);
throw t; throw t;
} }
postCodeInstallationTasks(tasks, installedCode);
return installedCode; return installedCode;
} catch (Throwable e) { } catch (Throwable e) {
throw debug.handle(e); throw debug.handle(e);
} }
} }
private static void failCodeInstallationTasks(CodeInstallationTask[] tasks, Throwable t) {
for (CodeInstallationTask task : tasks) {
task.installFailed(t);
}
}
private static void preCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult) {
for (CodeInstallationTask task : tasks) {
task.preProcess(compilationResult);
}
}
private static void postCodeInstallationTasks(CodeInstallationTask[] tasks, InstalledCode installedCode) {
try {
for (CodeInstallationTask task : tasks) {
task.postProcess(installedCode);
}
} catch (Throwable t) {
installedCode.invalidate();
throw t;
}
}
/** /**
* Installs code based on a given compilation result. * Installs code based on a given compilation result.
* *
@ -301,11 +318,10 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
} }
/** /**
* Task to run after all the post-code installation tasks are complete, used to release the * Invoked after {@link #preProcess} when code installation fails.
* installed code.
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
public void releaseInstallation(InstalledCode installedCode) { public void installFailed(Throwable t) {
} }
} }

View File

@ -34,6 +34,7 @@ import java.util.Collections;
import java.util.Formatter; import java.util.Formatter;
import java.util.List; import java.util.List;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.debug.Assertions; import org.graalvm.compiler.debug.Assertions;
import org.graalvm.compiler.debug.CounterKey; import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.DebugCloseable;
@ -46,7 +47,6 @@ import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.debug.DebugVerifyHandler; import org.graalvm.compiler.debug.DebugVerifyHandler;
import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Assume; import org.junit.Assume;
import org.junit.Test; import org.junit.Test;

View File

@ -30,6 +30,7 @@ import static org.junit.Assert.assertEquals;
import java.lang.management.ThreadMXBean; import java.lang.management.ThreadMXBean;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugOptions; import org.graalvm.compiler.debug.DebugOptions;
@ -37,7 +38,6 @@ import org.graalvm.compiler.debug.Management;
import org.graalvm.compiler.debug.TimerKey; import org.graalvm.compiler.debug.TimerKey;
import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.junit.Assume; import org.junit.Assume;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;

View File

@ -22,7 +22,7 @@
*/ */
package org.graalvm.compiler.debug; package org.graalvm.compiler.debug;
import org.graalvm.util.Pair; import org.graalvm.collections.Pair;
class CounterKeyImpl extends AbstractKey implements CounterKey { class CounterKeyImpl extends AbstractKey implements CounterKey {

View File

@ -56,12 +56,12 @@ import java.util.Map;
import java.util.SortedMap; import java.util.SortedMap;
import java.util.TreeMap; import java.util.TreeMap;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Pair;
import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.graphio.GraphOutput; import org.graalvm.graphio.GraphOutput;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.EconomicSet;
import org.graalvm.util.Pair;
import jdk.vm.ci.meta.JavaMethod; import jdk.vm.ci.meta.JavaMethod;
@ -1937,10 +1937,17 @@ public final class DebugContext implements AutoCloseable {
if (description != null) { if (description != null) {
printMetrics(description); printMetrics(description);
} }
if (metricsEnabled && globalMetrics != null && metricValues != null) { if (metricsEnabled && metricValues != null && globalMetrics != null) {
globalMetrics.add(this); globalMetrics.add(this);
} }
metricValues = null; metricValues = null;
if (sharedChannel != null) {
try {
sharedChannel.realClose();
} catch (IOException ex) {
// ignore.
}
}
} }
public void closeDumpHandlers(boolean ignoreErrors) { public void closeDumpHandlers(boolean ignoreErrors) {
@ -2022,7 +2029,6 @@ public final class DebugContext implements AutoCloseable {
} }
} }
} }
} }
/** /**

View File

@ -27,11 +27,11 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType; import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
/** /**
* Options that configure a {@link DebugContext} and related functionality. * Options that configure a {@link DebugContext} and related functionality.

View File

@ -29,10 +29,10 @@ import java.nio.file.Paths;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.MapCursor;
import org.graalvm.collections.Pair;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.MapCursor;
import org.graalvm.util.Pair;
/** /**
* Metric values that can be {@linkplain #add(DebugContext) updated} by multiple threads. * Metric values that can be {@linkplain #add(DebugContext) updated} by multiple threads.

View File

@ -25,7 +25,7 @@ package org.graalvm.compiler.debug;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.graalvm.util.EconomicMap; import org.graalvm.collections.EconomicMap;
/** /**
* Registry for allocating a globally unique integer id to each {@link AbstractKey}. * Registry for allocating a globally unique integer id to each {@link AbstractKey}.

View File

@ -24,7 +24,7 @@ package org.graalvm.compiler.debug;
import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE; import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
import org.graalvm.util.Pair; import org.graalvm.collections.Pair;
class MemUseTrackerKeyImpl extends AccumulatedKey implements MemUseTrackerKey { class MemUseTrackerKeyImpl extends AccumulatedKey implements MemUseTrackerKey {

View File

@ -24,7 +24,7 @@ package org.graalvm.compiler.debug;
import java.util.Comparator; import java.util.Comparator;
import org.graalvm.util.Pair; import org.graalvm.collections.Pair;
/** /**
* A key for a metric. * A key for a metric.

View File

@ -26,7 +26,7 @@ import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.graalvm.util.Pair; import org.graalvm.collections.Pair;
final class TimerKeyImpl extends AccumulatedKey implements TimerKey { final class TimerKeyImpl extends AccumulatedKey implements TimerKey {
static class FlatTimer extends AbstractKey implements TimerKey { static class FlatTimer extends AbstractKey implements TimerKey {

View File

@ -24,7 +24,7 @@ package org.graalvm.compiler.graph;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.graalvm.util.UnmodifiableEconomicMap; import org.graalvm.collections.UnmodifiableEconomicMap;
/** /**
* This class is a container of a graph that needs to be readonly and optionally a lazily created * This class is a container of a graph that needs to be readonly and optionally a lazily created

View File

@ -30,6 +30,9 @@ import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.Equivalence;
import org.graalvm.collections.UnmodifiableEconomicMap;
import org.graalvm.compiler.debug.CounterKey; import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
@ -41,9 +44,6 @@ import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionType; import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.Equivalence;
import org.graalvm.util.UnmodifiableEconomicMap;
/** /**
* This class is a graph container, it contains the set of nodes that belong to this graph. * This class is a graph container, it contains the set of nodes that belong to this graph.

View File

@ -160,6 +160,12 @@ public final class NodeBitMap extends NodeIdAccessor implements NodeIterable<Nod
} }
} }
public void invert() {
for (int i = 0; i < bits.length; i++) {
bits[i] = ~bits[i];
}
}
public void grow() { public void grow() {
nodeCount = Math.max(nodeCount, graph().nodeIdCount()); nodeCount = Math.max(nodeCount, graph().nodeIdCount());
int newLength = sizeForNodeCount(nodeCount); int newLength = sizeForNodeCount(nodeCount);

View File

@ -42,6 +42,8 @@ import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.Equivalence;
import org.graalvm.compiler.core.common.FieldIntrospection; import org.graalvm.compiler.core.common.FieldIntrospection;
import org.graalvm.compiler.core.common.Fields; import org.graalvm.compiler.core.common.Fields;
import org.graalvm.compiler.core.common.FieldsScanner; import org.graalvm.compiler.core.common.FieldsScanner;
@ -65,8 +67,6 @@ import org.graalvm.compiler.nodeinfo.NodeCycles;
import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.nodeinfo.NodeInfo;
import org.graalvm.compiler.nodeinfo.NodeSize; import org.graalvm.compiler.nodeinfo.NodeSize;
import org.graalvm.compiler.nodeinfo.Verbosity; import org.graalvm.compiler.nodeinfo.Verbosity;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.Equivalence;
/** /**
* Metadata for every {@link Node} type. The metadata includes: * Metadata for every {@link Node} type. The metadata includes:

View File

@ -26,8 +26,8 @@ import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import org.graalvm.util.EconomicMap; import org.graalvm.collections.EconomicMap;
import org.graalvm.util.MapCursor; import org.graalvm.collections.MapCursor;
public class NodeMap<T> extends NodeIdAccessor implements EconomicMap<Node, T> { public class NodeMap<T> extends NodeIdAccessor implements EconomicMap<Node, T> {

View File

@ -74,6 +74,10 @@ public final class NodeStack {
return tos == 0; return tos == 0;
} }
public void clear() {
tos = 0;
}
@Override @Override
public String toString() { public String toString() {
if (tos == 0) { if (tos == 0) {

View File

@ -22,7 +22,6 @@
*/ */
package org.graalvm.compiler.hotspot.aarch64; package org.graalvm.compiler.hotspot.aarch64;
import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
import static java.lang.reflect.Modifier.isStatic; import static java.lang.reflect.Modifier.isStatic;
import static jdk.vm.ci.aarch64.AArch64.lr; import static jdk.vm.ci.aarch64.AArch64.lr;
import static jdk.vm.ci.aarch64.AArch64.r10; import static jdk.vm.ci.aarch64.AArch64.r10;
@ -30,7 +29,9 @@ import static jdk.vm.ci.aarch64.AArch64.sp;
import static jdk.vm.ci.aarch64.AArch64.zr; import static jdk.vm.ci.aarch64.AArch64.zr;
import static jdk.vm.ci.code.ValueUtil.asRegister; import static jdk.vm.ci.code.ValueUtil.asRegister;
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp; import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp;
import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
import org.graalvm.collections.EconomicSet;
import org.graalvm.compiler.asm.Assembler; import org.graalvm.compiler.asm.Assembler;
import org.graalvm.compiler.asm.Label; import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.aarch64.AArch64Address; import org.graalvm.compiler.asm.aarch64.AArch64Address;
@ -42,11 +43,11 @@ import org.graalvm.compiler.core.aarch64.AArch64NodeMatchRules;
import org.graalvm.compiler.core.common.CompilationIdentifier; import org.graalvm.compiler.core.common.CompilationIdentifier;
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage; import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotDataBuilder; import org.graalvm.compiler.hotspot.HotSpotDataBuilder;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
import org.graalvm.compiler.hotspot.HotSpotHostBackend; import org.graalvm.compiler.hotspot.HotSpotHostBackend;
import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult; import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider; import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotProviders; import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
import org.graalvm.compiler.hotspot.stubs.Stub; import org.graalvm.compiler.hotspot.stubs.Stub;
@ -64,7 +65,6 @@ import org.graalvm.compiler.lir.gen.LIRGenerationResult;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool; import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.graalvm.util.EconomicSet;
import jdk.vm.ci.code.CallingConvention; import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.Register; import jdk.vm.ci.code.Register;

View File

@ -49,6 +49,7 @@ import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.tiers.CompilerConfiguration; import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
import org.graalvm.compiler.phases.util.Providers; import org.graalvm.compiler.phases.util.Providers;
@ -136,7 +137,7 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
replacements = createReplacements(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider); replacements = createReplacements(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider);
} }
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, stampProvider); plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes, stampProvider);
replacements.setGraphBuilderPlugins(plugins); replacements.setGraphBuilderPlugins(plugins);
} }
try (InitTimer rt = timer("create Suites provider")) { try (InitTimer rt = timer("create Suites provider")) {
@ -152,9 +153,10 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
} }
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection, protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection,
HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection,
HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) { HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements); Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
replacements);
AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider()); AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider());
return plugins; return plugins;
} }

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.hotspot.amd64.test;
import jdk.vm.ci.hotspot.HotSpotSpeculationLog;
import jdk.vm.ci.meta.SpeculationLog;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.junit.Test;
public class ArrayAccessInLoopToAddressTest extends GraalCompilerTest {
public static int positiveInductionVariable(short[] array) {
int sum = 0;
for (int i = 0; i < array.length - 1; i++) {
sum += array[i + 1];
}
return sum;
}
@Test
public void testPositiveInductionVariable() {
test("positiveInductionVariable", new short[]{1, 3, 7, 9});
}
public static int negativeInductionVariable(short[] array) {
int sum = 0;
for (int i = -array.length; i < array.length - 4; i++) {
sum += array[i + 4];
}
return sum;
}
@Test
public void testNegativeInductionVariable() {
test("negativeInductionVariable", new short[]{1, 3, 7, 9});
}
@Override
protected SpeculationLog getSpeculationLog() {
return new HotSpotSpeculationLog();
}
}

View File

@ -24,64 +24,50 @@
package org.graalvm.compiler.hotspot.amd64; package org.graalvm.compiler.hotspot.amd64;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale; import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.core.amd64.AMD64AddressLowering;
import org.graalvm.compiler.core.amd64.AMD64AddressNode; import org.graalvm.compiler.core.amd64.AMD64AddressNode;
import org.graalvm.compiler.core.amd64.AMD64CompressAddressLowering;
import org.graalvm.compiler.core.common.CompressEncoding; import org.graalvm.compiler.core.common.CompressEncoding;
import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.type.IntegerStamp;
import org.graalvm.compiler.core.common.type.ObjectStamp; import org.graalvm.compiler.core.common.type.ObjectStamp;
import org.graalvm.compiler.core.common.type.StampFactory; import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.graph.NodeClass;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode; import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp; import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
import org.graalvm.compiler.nodeinfo.NodeInfo; import org.graalvm.compiler.loop.BasicInductionVariable;
import org.graalvm.compiler.loop.CountedLoopInfo;
import org.graalvm.compiler.loop.DerivedInductionVariable;
import org.graalvm.compiler.loop.InductionVariable;
import org.graalvm.compiler.loop.LoopEx;
import org.graalvm.compiler.loop.LoopsData;
import org.graalvm.compiler.nodes.CompressionNode; import org.graalvm.compiler.nodes.CompressionNode;
import org.graalvm.compiler.nodes.CompressionNode.CompressionOp; import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.NodeView; import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode; import org.graalvm.compiler.nodes.calc.AddNode;
import org.graalvm.compiler.nodes.spi.LIRLowerable; import org.graalvm.compiler.nodes.calc.SignExtendNode;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
import org.graalvm.compiler.nodes.memory.address.AddressNode;
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.code.Register; import jdk.vm.ci.code.Register;
import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.JavaKind;
public class AMD64HotSpotAddressLowering extends AMD64AddressLowering { public class AMD64HotSpotAddressLowering extends AMD64CompressAddressLowering {
private static final CounterKey counterFoldedUncompressDuringAddressLowering = DebugContext.counter("FoldedUncompressDuringAddressLowering"); private static final int ADDRESS_BITS = 64;
private static final int INT_BITS = 32;
private final long heapBase; private final long heapBase;
private final Register heapBaseRegister; private final Register heapBaseRegister;
private final GraalHotSpotVMConfig config; private final GraalHotSpotVMConfig config;
private final boolean generatePIC; private final boolean generatePIC;
@NodeInfo(cycles = CYCLES_0, size = SIZE_0)
public static class HeapBaseNode extends FloatingNode implements LIRLowerable {
public static final NodeClass<HeapBaseNode> TYPE = NodeClass.create(HeapBaseNode.class);
private final Register heapBaseRegister;
public HeapBaseNode(Register heapBaseRegister) {
super(TYPE, StampFactory.pointer());
this.heapBaseRegister = heapBaseRegister;
}
@Override
public void generate(NodeLIRBuilderTool generator) {
LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
generator.setResult(this, heapBaseRegister.asValue(kind));
}
}
public AMD64HotSpotAddressLowering(GraalHotSpotVMConfig config, Register heapBaseRegister, OptionValues options) { public AMD64HotSpotAddressLowering(GraalHotSpotVMConfig config, Register heapBaseRegister, OptionValues options) {
this.heapBase = config.getOopEncoding().getBase(); this.heapBase = config.getOopEncoding().getBase();
this.config = config; this.config = config;
@ -94,35 +80,7 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
} }
@Override @Override
protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated) { protected final boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other) {
if (super.improve(graph, debug, addr, isBaseNegated, isIndexNegated)) {
return true;
}
if (addr.getScale() == Scale.Times1) {
if (addr.getIndex() instanceof CompressionNode) {
if (improveUncompression(addr, (CompressionNode) addr.getIndex(), addr.getBase(), isBaseNegated, isIndexNegated)) {
counterFoldedUncompressDuringAddressLowering.increment(debug);
return true;
}
}
if (addr.getBase() instanceof CompressionNode) {
if (improveUncompression(addr, (CompressionNode) addr.getBase(), addr.getIndex(), isBaseNegated, isIndexNegated)) {
counterFoldedUncompressDuringAddressLowering.increment(debug);
return true;
}
}
}
return false;
}
private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other, boolean isBaseNegated, boolean isIndexNegated) {
if (isBaseNegated || isIndexNegated || compression.getOp() != CompressionOp.Uncompress) {
return false;
}
CompressEncoding encoding = compression.getEncoding(); CompressEncoding encoding = compression.getEncoding();
Scale scale = Scale.fromShift(encoding.getShift()); Scale scale = Scale.fromShift(encoding.getShift());
if (scale == null) { if (scale == null) {
@ -147,7 +105,7 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
return false; return false;
} }
} else { } else {
if (updateDisplacement(addr, encoding.getBase(), isBaseNegated)) { if (updateDisplacement(addr, encoding.getBase(), false)) {
addr.setBase(other); addr.setBase(other);
} else { } else {
return false; return false;
@ -161,4 +119,117 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
addr.setIndex(compression.getValue()); addr.setIndex(compression.getValue());
return true; return true;
} }
@Override
public void preProcess(StructuredGraph graph) {
if (graph.hasLoops()) {
LoopsData loopsData = new LoopsData(graph);
loopsData.detectedCountedLoops();
for (LoopEx loop : loopsData.countedLoops()) {
for (OffsetAddressNode offsetAdressNode : loop.whole().nodes().filter(OffsetAddressNode.class)) {
tryOptimize(offsetAdressNode, loop);
}
}
}
}
@Override
public void postProcess(AddressNode lowered) {
// Allow implicit zero extend for always positive input. This
// assumes that the upper bits of the operand is zero out by
// the backend.
AMD64AddressNode address = (AMD64AddressNode) lowered;
address.setBase(tryImplicitZeroExtend(address.getBase()));
address.setIndex(tryImplicitZeroExtend(address.getIndex()));
}
private static void tryOptimize(OffsetAddressNode offsetAddress, LoopEx loop) {
EconomicMap<Node, InductionVariable> ivs = loop.getInductionVariables();
InductionVariable currentIV = ivs.get(offsetAddress.getOffset());
while (currentIV != null) {
if (!(currentIV instanceof DerivedInductionVariable)) {
break;
}
ValueNode currentValue = currentIV.valueNode();
if (currentValue.isDeleted()) {
break;
}
if (currentValue instanceof ZeroExtendNode) {
ZeroExtendNode zeroExtendNode = (ZeroExtendNode) currentValue;
if (applicableToImplicitZeroExtend(zeroExtendNode)) {
ValueNode input = zeroExtendNode.getValue();
if (input instanceof AddNode) {
AddNode add = (AddNode) input;
if (add.getX().isConstant()) {
optimizeAdd(zeroExtendNode, (ConstantNode) add.getX(), add.getY(), loop);
} else if (add.getY().isConstant()) {
optimizeAdd(zeroExtendNode, (ConstantNode) add.getY(), add.getX(), loop);
}
}
}
}
currentIV = ((DerivedInductionVariable) currentIV).getBase();
}
}
/**
* Given that Add(a, cst) is always positive, performs the following: ZeroExtend(Add(a, cst)) ->
* Add(SignExtend(a), SignExtend(cst)).
*/
private static void optimizeAdd(ZeroExtendNode zeroExtendNode, ConstantNode constant, ValueNode other, LoopEx loop) {
StructuredGraph graph = zeroExtendNode.graph();
AddNode addNode = graph.unique(new AddNode(signExtend(other, loop), ConstantNode.forLong(constant.asJavaConstant().asInt(), graph)));
zeroExtendNode.replaceAtUsages(addNode);
}
/**
* Create a sign extend for {@code input}, or zero extend if {@code input} can be proven
* positive.
*/
private static ValueNode signExtend(ValueNode input, LoopEx loop) {
StructuredGraph graph = input.graph();
if (input instanceof PhiNode) {
EconomicMap<Node, InductionVariable> ivs = loop.getInductionVariables();
InductionVariable inductionVariable = ivs.get(input);
if (inductionVariable != null && inductionVariable instanceof BasicInductionVariable) {
CountedLoopInfo countedLoopInfo = loop.counted();
IntegerStamp initStamp = (IntegerStamp) inductionVariable.initNode().stamp(NodeView.DEFAULT);
if (initStamp.isPositive()) {
if (inductionVariable.isConstantExtremum()) {
long init = inductionVariable.constantInit();
long stride = inductionVariable.constantStride();
long extremum = inductionVariable.constantExtremum();
if (init >= 0 && extremum >= 0) {
long shortestTrip = (extremum - init) / stride + 1;
if (shortestTrip == countedLoopInfo.constantMaxTripCount()) {
return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, true));
}
}
}
if (countedLoopInfo.getCounter() == inductionVariable && inductionVariable.direction() == InductionVariable.Direction.Up && countedLoopInfo.getOverFlowGuard() != null) {
return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, true));
}
}
}
}
return input.graph().maybeAddOrUnique(SignExtendNode.create(input, ADDRESS_BITS, NodeView.DEFAULT));
}
private static boolean applicableToImplicitZeroExtend(ZeroExtendNode zeroExtendNode) {
return zeroExtendNode.isInputAlwaysPositive() && zeroExtendNode.getInputBits() == INT_BITS && zeroExtendNode.getResultBits() == ADDRESS_BITS;
}
private static ValueNode tryImplicitZeroExtend(ValueNode input) {
if (input instanceof ZeroExtendNode) {
ZeroExtendNode zeroExtendNode = (ZeroExtendNode) input;
if (applicableToImplicitZeroExtend(zeroExtendNode)) {
return zeroExtendNode.getValue();
}
}
return input;
}
} }

View File

@ -30,6 +30,7 @@ import static org.graalvm.compiler.core.common.GraalOptions.CanOmitFrame;
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC; import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry; import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
import org.graalvm.collections.EconomicSet;
import org.graalvm.compiler.asm.Assembler; import org.graalvm.compiler.asm.Assembler;
import org.graalvm.compiler.asm.Label; import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.amd64.AMD64Address; import org.graalvm.compiler.asm.amd64.AMD64Address;
@ -66,7 +67,6 @@ import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicSet;
import jdk.vm.ci.amd64.AMD64; import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.amd64.AMD64Kind; import jdk.vm.ci.amd64.AMD64Kind;

View File

@ -49,6 +49,7 @@ import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider;
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider; import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes; import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
import org.graalvm.compiler.nodes.spi.LoweringProvider;
import org.graalvm.compiler.nodes.spi.Replacements; import org.graalvm.compiler.nodes.spi.Replacements;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.phases.tiers.CompilerConfiguration; import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
@ -137,7 +138,7 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
replacements = createReplacements(options, p, snippetReflection, bytecodeProvider); replacements = createReplacements(options, p, snippetReflection, bytecodeProvider);
} }
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) { try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
plugins = createGraphBuilderPlugins(compilerConfiguration, config, options, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, plugins = createGraphBuilderPlugins(compilerConfiguration, config, options, target, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes,
stampProvider); stampProvider);
replacements.setGraphBuilderPlugins(plugins); replacements.setGraphBuilderPlugins(plugins);
} }
@ -154,9 +155,10 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
} }
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, OptionValues options, TargetDescription target, protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, OptionValues options, TargetDescription target,
HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess,
HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) { HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements); Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
replacements);
AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, GraalArithmeticStubs.getValue(options)); AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, GraalArithmeticStubs.getValue(options));
return plugins; return plugins;
} }

View File

@ -572,7 +572,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
if (inputKind.isReference(0)) { if (inputKind.isReference(0)) {
// oop // oop
Variable result = newVariable(lirKindTool.getNarrowOopKind()); Variable result = newVariable(lirKindTool.getNarrowOopKind());
append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, getLIRKindTool())); append(new AMD64Move.CompressPointerOp(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, getLIRKindTool()));
return result; return result;
} else { } else {
// metaspace pointer // metaspace pointer
@ -589,7 +589,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
base = emitLoadConstant(lirKindTool.getWordKind(), JavaConstant.forLong(encoding.getBase())); base = emitLoadConstant(lirKindTool.getWordKind(), JavaConstant.forLong(encoding.getBase()));
} }
} }
append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, getLIRKindTool())); append(new AMD64Move.CompressPointerOp(result, asAllocatable(pointer), base, encoding, nonNull, getLIRKindTool()));
return result; return result;
} }
} }
@ -602,7 +602,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
if (inputKind.isReference(0)) { if (inputKind.isReference(0)) {
// oop // oop
Variable result = newVariable(lirKindTool.getObjectKind()); Variable result = newVariable(lirKindTool.getObjectKind());
append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, lirKindTool)); append(new AMD64Move.UncompressPointerOp(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, lirKindTool));
return result; return result;
} else { } else {
// metaspace pointer // metaspace pointer
@ -620,7 +620,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
base = emitLoadConstant(uncompressedKind, JavaConstant.forLong(encoding.getBase())); base = emitLoadConstant(uncompressedKind, JavaConstant.forLong(encoding.getBase()));
} }
} }
append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, lirKindTool)); append(new AMD64Move.UncompressPointerOp(result, asAllocatable(pointer), base, encoding, nonNull, lirKindTool));
return result; return result;
} }
} }

View File

@ -67,7 +67,8 @@ public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider
public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, GraalHotSpotVMConfig config) { public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, GraalHotSpotVMConfig config) {
convertSnippets = new AMD64ConvertSnippets.Templates(options, factories, providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget()); convertSnippets = new AMD64ConvertSnippets.Templates(options, factories, providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget());
profileSnippets = ProfileNode.Options.ProbabilisticProfiling.getValue(options) profileSnippets = ProfileNode.Options.ProbabilisticProfiling.getValue(options)
? new ProbabilisticProfileSnippets.Templates(options, factories, providers, providers.getCodeCache().getTarget()) : null; ? new ProbabilisticProfileSnippets.Templates(options, factories, providers, providers.getCodeCache().getTarget())
: null;
super.initialize(options, factories, providers, config); super.initialize(options, factories, providers, config);
} }

View File

@ -60,6 +60,7 @@ final class AMD64HotspotDirectVirtualCallOp extends DirectCallOp {
crb.recordMark(invokeKind == InvokeKind.Virtual ? config.MARKID_INVOKEVIRTUAL : config.MARKID_INVOKEINTERFACE); crb.recordMark(invokeKind == InvokeKind.Virtual ? config.MARKID_INVOKEVIRTUAL : config.MARKID_INVOKEINTERFACE);
// This must be emitted exactly like this to ensure it's patchable // This must be emitted exactly like this to ensure it's patchable
masm.movq(AMD64.rax, config.nonOopBits); masm.movq(AMD64.rax, config.nonOopBits);
super.emitCode(crb, masm); int offset = super.emitCall(crb, masm);
crb.recordInvokeVirtualOrInterfaceCallOp(offset, getPosition());
} }
} }

View File

@ -70,7 +70,8 @@ final class AMD64IndirectCallOp extends IndirectCallOp {
crb.recordMark(config.MARKID_INLINE_INVOKE); crb.recordMark(config.MARKID_INLINE_INVOKE);
Register callReg = asRegister(targetAddress); Register callReg = asRegister(targetAddress);
assert !callReg.equals(METHOD); assert !callReg.equals(METHOD);
AMD64Call.indirectCall(crb, masm, callReg, callTarget, state); int pcOffset = AMD64Call.indirectCall(crb, masm, callReg, callTarget, state);
crb.recordInlineInvokeCallOp(pcOffset, getPosition());
} }
@Override @Override

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,15 +26,18 @@ import static org.graalvm.compiler.core.common.GraalOptions.RegisterPressure;
import static org.graalvm.compiler.core.common.GraalOptions.TraceRA; import static org.graalvm.compiler.core.common.GraalOptions.TraceRA;
import static org.junit.Assume.assumeTrue; import static org.junit.Assume.assumeTrue;
import org.graalvm.compiler.core.test.backend.AllocatorTest;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotBackend;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.graalvm.compiler.core.test.backend.AllocatorTest;
import jdk.vm.ci.sparc.SPARC; import jdk.vm.ci.sparc.SPARC;
public class SPARCAllocatorTest extends AllocatorTest { public class SPARCAllocatorTest extends AllocatorTest {
private final GraalHotSpotVMConfig config = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig();
@Before @Before
public void checkSPARC() { public void checkSPARC() {
assumeTrue("skipping SPARC specific test", getTarget().arch instanceof SPARC); assumeTrue("skipping SPARC specific test", getTarget().arch instanceof SPARC);
@ -44,7 +47,7 @@ public class SPARCAllocatorTest extends AllocatorTest {
@Test @Test
public void test1() { public void test1() {
testAllocation("test1snippet", 2, 0, 0); testAllocation("test1snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0);
} }
public static long test1snippet(long x) { public static long test1snippet(long x) {
@ -53,7 +56,7 @@ public class SPARCAllocatorTest extends AllocatorTest {
@Test @Test
public void test2() { public void test2() {
testAllocation("test2snippet", 2, 0, 0); testAllocation("test2snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0);
} }
public static long test2snippet(long x) { public static long test2snippet(long x) {
@ -62,7 +65,7 @@ public class SPARCAllocatorTest extends AllocatorTest {
@Test @Test
public void test3() { public void test3() {
testAllocation("test3snippet", 4, 0, 0); testAllocation("test3snippet", config.threadLocalHandshakes ? 3 : 4, 0, 0);
} }
public static long test3snippet(long x) { public static long test3snippet(long x) {

View File

@ -46,6 +46,9 @@ import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Equivalence;
import org.graalvm.compiler.asm.Assembler; import org.graalvm.compiler.asm.Assembler;
import org.graalvm.compiler.asm.Label; import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.sparc.SPARCAddress; import org.graalvm.compiler.asm.sparc.SPARCAddress;
@ -92,9 +95,6 @@ import org.graalvm.compiler.lir.sparc.SPARCTailDelayedLIRInstruction;
import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.EconomicSet;
import org.graalvm.util.Equivalence;
import jdk.vm.ci.code.CallingConvention; import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.Register; import jdk.vm.ci.code.Register;

View File

@ -101,7 +101,7 @@ public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory {
HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes); HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes);
BytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection); BytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection);
HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(runtime.getOptions(), p, snippetReflection, bytecodeProvider, target); HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(runtime.getOptions(), p, snippetReflection, bytecodeProvider, target);
Plugins plugins = createGraphBuilderPlugins(compilerConfiguration, config, metaAccess, constantReflection, foreignCalls, stampProvider, snippetReflection, replacements, wordTypes); Plugins plugins = createGraphBuilderPlugins(compilerConfiguration, config, metaAccess, constantReflection, foreignCalls, lowerer, stampProvider, snippetReflection, replacements, wordTypes);
replacements.setGraphBuilderPlugins(plugins); replacements.setGraphBuilderPlugins(plugins);
HotSpotSuitesProvider suites = createSuites(config, runtime, compilerConfiguration, plugins, replacements); HotSpotSuitesProvider suites = createSuites(config, runtime, compilerConfiguration, plugins, replacements);
HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers, HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
@ -112,9 +112,10 @@ public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory {
} }
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotMetaAccessProvider metaAccess, protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotMetaAccessProvider metaAccess,
HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, HotSpotStampProvider stampProvider, HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotStampProvider stampProvider,
HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) { HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) {
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements); Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
replacements);
SPARCGraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider()); SPARCGraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider());
return plugins; return plugins;
} }

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.hotspot.test;
import java.lang.reflect.Array;
import java.util.ArrayList;
import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
public class ArrayNewInstanceTest extends GraalCompilerTest {
@Parameters(name = "{index}: class {0} length {1}")
public static Iterable<Object[]> data() {
ArrayList<Object[]> parameters = new ArrayList<>();
Class<?>[] classesToTest = new Class<?>[]{
byte.class,
boolean.class,
short.class,
char.class,
int.class,
long.class,
Void.class,
ArrayNewInstanceTest.class
};
for (Class<?> clazz : classesToTest) {
// Negative sizes always deopt
parameters.add(new Object[]{clazz, -1, true});
parameters.add(new Object[]{clazz, 0, false});
parameters.add(new Object[]{clazz, 42, false});
}
// The void type always throws an exception where graal deopts
parameters.add(new Object[]{void.class, -1, true});
parameters.add(new Object[]{void.class, 0, true});
parameters.add(new Object[]{void.class, 42, true});
return parameters;
}
private final Class<?> type;
private final int length;
private final boolean shouldDeopt;
private final DeoptimizationBox box = new DeoptimizationBox();
public ArrayNewInstanceTest(Class<?> type, int length, boolean shouldDeopt) {
super();
this.type = type;
this.length = length;
this.shouldDeopt = shouldDeopt;
}
public static Object newArray(Class<?> klass, int length, DeoptimizationBox box) {
Object result = Array.newInstance(klass, length);
box.inCompiledCode = GraalDirectives.inCompiledCode();
return result;
}
@Test
public void testNewArray() {
test("newArray", type, length, box);
assertTrue(box.inCompiledCode != shouldDeopt);
}
public static Object newArrayInLoop(Class<?> klass, int length, int iterations, DeoptimizationBox box) {
Object o = null;
for (int i = 0; i < iterations; i++) {
o = Array.newInstance(klass, length);
}
box.inCompiledCode = GraalDirectives.inCompiledCode();
return o;
}
@Test
public void testNewArrayInLoop() {
test("newArrayInLoop", type, length, 2, box);
assertTrue(box.inCompiledCode != shouldDeopt);
}
private static class DeoptimizationBox {
volatile boolean inCompiledCode = false;
}
}

View File

@ -32,6 +32,8 @@ import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.MapCursor;
import org.graalvm.compiler.api.test.Graal; import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
@ -43,8 +45,6 @@ import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding;
import org.graalvm.compiler.runtime.RuntimeProvider; import org.graalvm.compiler.runtime.RuntimeProvider;
import org.graalvm.compiler.serviceprovider.JDK9Method; import org.graalvm.compiler.serviceprovider.JDK9Method;
import org.graalvm.compiler.test.GraalTest; import org.graalvm.compiler.test.GraalTest;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.MapCursor;
import org.junit.Test; import org.junit.Test;
import jdk.vm.ci.hotspot.HotSpotVMConfigStore; import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
@ -416,6 +416,12 @@ public class CheckGraalIntrinsics extends GraalTest {
"java/lang/StringUTF16.toBytes([CII)[B"); "java/lang/StringUTF16.toBytes([CII)[B");
} }
if (isJDK10OrHigher()) {
add(TO_BE_INVESTIGATED,
"java/lang/Math.multiplyHigh(JJ)J",
"jdk/internal/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I");
}
if (!getHostArchitectureName().equals("amd64")) { if (!getHostArchitectureName().equals("amd64")) {
// Can we implement these on non-AMD64 platforms? C2 seems to. // Can we implement these on non-AMD64 platforms? C2 seems to.
add(TO_BE_INVESTIGATED, add(TO_BE_INVESTIGATED,
@ -539,6 +545,10 @@ public class CheckGraalIntrinsics extends GraalTest {
return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9; return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9;
} }
private static boolean isJDK10OrHigher() {
return JDK9Method.JAVA_SPECIFICATION_VERSION >= 10;
}
private static String getHostArchitectureName() { private static String getHostArchitectureName() {
String arch = System.getProperty("os.arch"); String arch = System.getProperty("os.arch");
if (arch.equals("x86_64")) { if (arch.equals("x86_64")) {

View File

@ -68,6 +68,8 @@ import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.UnmodifiableEconomicMap;
import org.graalvm.compiler.api.replacements.Snippet; import org.graalvm.compiler.api.replacements.Snippet;
import org.graalvm.compiler.bytecode.Bytecodes; import org.graalvm.compiler.bytecode.Bytecodes;
import org.graalvm.compiler.core.CompilerThreadFactory; import org.graalvm.compiler.core.CompilerThreadFactory;
@ -85,8 +87,6 @@ import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.options.OptionsParser; import org.graalvm.compiler.options.OptionsParser;
import org.graalvm.compiler.serviceprovider.JDK9Method; import org.graalvm.compiler.serviceprovider.JDK9Method;
import org.graalvm.util.EconomicMap;
import org.graalvm.util.UnmodifiableEconomicMap;
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider; import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.hotspot.HotSpotCompilationRequest; import jdk.vm.ci.hotspot.HotSpotCompilationRequest;

View File

@ -25,12 +25,12 @@ package org.graalvm.compiler.hotspot.test;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction; import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction; import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction; import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.hotspot.HotSpotGraalCompiler; import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.junit.Test; import org.junit.Test;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;

View File

@ -32,6 +32,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.api.directives.GraalDirectives; import org.graalvm.compiler.api.directives.GraalDirectives;
import org.graalvm.compiler.core.phases.HighTier; import org.graalvm.compiler.core.phases.HighTier;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
@ -40,13 +41,12 @@ import org.graalvm.compiler.debug.TTY;
import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase; import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase;
import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionKey;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.util.EconomicMap;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaMethod;
import org.junit.Assume;
import org.junit.BeforeClass;
/** /**
* Test on-stack-replacement with locks. * Test on-stack-replacement with locks.

View File

@ -31,8 +31,8 @@ import static org.junit.Assert.assertTrue;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Arrays; import java.util.Arrays;
import javax.management.Attribute; import javax.management.Attribute;
import javax.management.MBeanAttributeInfo; import javax.management.MBeanAttributeInfo;
import javax.management.MBeanInfo; import javax.management.MBeanInfo;
@ -41,11 +41,11 @@ import javax.management.MBeanServer;
import javax.management.ObjectInstance; import javax.management.ObjectInstance;
import javax.management.ObjectName; import javax.management.ObjectName;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.debug.DebugOptions; import org.graalvm.compiler.debug.DebugOptions;
import org.graalvm.compiler.hotspot.HotSpotGraalMBean; import org.graalvm.compiler.hotspot.HotSpotGraalMBean;
import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.test.GraalTest; import org.graalvm.compiler.test.GraalTest;
import org.graalvm.util.EconomicMap;
import org.junit.Assume; import org.junit.Assume;
import org.junit.Test; import org.junit.Test;

View File

@ -23,8 +23,10 @@
package org.graalvm.compiler.hotspot.test; package org.graalvm.compiler.hotspot.test;
import static org.graalvm.compiler.core.common.CompilationIdentifier.INVALID_COMPILATION_ID; import static org.graalvm.compiler.core.common.CompilationIdentifier.INVALID_COMPILATION_ID;
import java.util.List; import java.util.List;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.api.test.Graal; import org.graalvm.compiler.api.test.Graal;
import org.graalvm.compiler.core.test.GraalCompilerTest; import org.graalvm.compiler.core.test.GraalCompilerTest;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
@ -36,10 +38,9 @@ import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plu
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding; import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin; import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
import org.graalvm.compiler.options.OptionValues;
import org.graalvm.compiler.runtime.RuntimeProvider; import org.graalvm.compiler.runtime.RuntimeProvider;
import org.graalvm.util.EconomicMap;
import org.junit.Test; import org.junit.Test;
import jdk.vm.ci.hotspot.HotSpotVMConfigStore; import jdk.vm.ci.hotspot.HotSpotVMConfigStore;

View File

@ -24,6 +24,7 @@ package org.graalvm.compiler.hotspot.test;
import java.util.List; import java.util.List;
import org.graalvm.collections.EconomicMap;
import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.DebugContext;
import org.graalvm.compiler.debug.DebugContext.Scope; import org.graalvm.compiler.debug.DebugContext.Scope;
@ -58,7 +59,6 @@ import org.graalvm.compiler.phases.graph.ReentrantNodeIterator;
import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure; import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure;
import org.graalvm.compiler.phases.tiers.HighTierContext; import org.graalvm.compiler.phases.tiers.HighTierContext;
import org.graalvm.compiler.phases.tiers.MidTierContext; import org.graalvm.compiler.phases.tiers.MidTierContext;
import org.graalvm.util.EconomicMap;
import org.graalvm.word.LocationIdentity; import org.graalvm.word.LocationIdentity;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;

Some files were not shown because too many files have changed in this diff Show More