8194819: Update Graal
Reviewed-by: kvn
This commit is contained in:
parent
83bb2205e8
commit
333333a507
@ -493,6 +493,7 @@ jdk.internal.vm.compiler_ADD_JAVAC_FLAGS += -parameters -XDstringConcat=inline \
|
||||
#
|
||||
|
||||
jdk.internal.vm.compiler_EXCLUDES += \
|
||||
org.graalvm.collections.test \
|
||||
org.graalvm.compiler.core.match.processor \
|
||||
org.graalvm.compiler.nodeinfo.processor \
|
||||
org.graalvm.compiler.options.processor \
|
||||
@ -511,6 +512,7 @@ jdk.internal.vm.compiler_EXCLUDES += \
|
||||
org.graalvm.compiler.graph.test \
|
||||
org.graalvm.compiler.hotspot.amd64.test \
|
||||
org.graalvm.compiler.hotspot.lir.test \
|
||||
org.graalvm.compiler.hotspot.sparc.test \
|
||||
org.graalvm.compiler.hotspot.test \
|
||||
org.graalvm.compiler.jtt \
|
||||
org.graalvm.compiler.lir.jtt \
|
||||
|
@ -48,6 +48,7 @@ ifeq ($(INCLUDE_GRAAL), true)
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
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.common/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, \
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
SRC := \
|
||||
$(SRC_DIR)/org.graalvm.collections/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.options/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.options.processor/src \
|
||||
$(SRC_DIR)/org.graalvm.util/src \
|
||||
@ -117,6 +119,7 @@ ifeq ($(INCLUDE_GRAAL), true)
|
||||
SETUP := GENERATE_OLDBYTECODE, \
|
||||
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.api.replacements/src \
|
||||
$(SRC_DIR)/org.graalvm.compiler.code/src \
|
||||
|
@ -143,7 +143,7 @@ final class DataPatchProcessor {
|
||||
int alignment = data.getAlignment();
|
||||
byte[] value = new byte[size];
|
||||
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;
|
||||
Symbol relocationSymbol = binaryContainer.getSymbol(targetSymbol);
|
||||
|
@ -82,6 +82,24 @@ suite = {
|
||||
"javaCompliance" : "1.8",
|
||||
"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 -------------
|
||||
|
||||
@ -190,6 +208,9 @@ suite = {
|
||||
"org.graalvm.util" : {
|
||||
"subDir" : "share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"org.graalvm.collections",
|
||||
],
|
||||
"checkstyle" : "org.graalvm.compiler.graph",
|
||||
"javaCompliance" : "1.8",
|
||||
"workingSets" : "API,Graal",
|
||||
@ -201,6 +222,7 @@ suite = {
|
||||
"dependencies" : [
|
||||
"mx:JUNIT",
|
||||
"org.graalvm.util",
|
||||
"org.graalvm.compiler.core.test",
|
||||
],
|
||||
"checkstyle" : "org.graalvm.compiler.graph",
|
||||
"javaCompliance" : "1.8",
|
||||
@ -970,10 +992,11 @@ suite = {
|
||||
"workingSets" : "Graal,SPARC",
|
||||
},
|
||||
|
||||
"org.graalvm.compiler.core.sparc.test" : {
|
||||
"org.graalvm.compiler.hotspot.sparc.test" : {
|
||||
"subDir" : "share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"org.graalvm.compiler.hotspot",
|
||||
"org.graalvm.compiler.lir.jtt",
|
||||
"JVMCI_HOTSPOT"
|
||||
],
|
||||
@ -1007,6 +1030,7 @@ suite = {
|
||||
"subDir" : "share/classes",
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"org.graalvm.collections",
|
||||
"org.graalvm.compiler.debug",
|
||||
"org.graalvm.word",
|
||||
],
|
||||
@ -1037,7 +1061,6 @@ suite = {
|
||||
"sourceDirs" : ["src"],
|
||||
"dependencies" : [
|
||||
"org.graalvm.compiler.debug",
|
||||
"org.graalvm.util",
|
||||
"mx:JUNIT",
|
||||
],
|
||||
"checkstyle" : "org.graalvm.compiler.graph",
|
||||
@ -1225,11 +1248,11 @@ suite = {
|
||||
"org.graalvm.compiler.asm.amd64.test",
|
||||
"org.graalvm.compiler.core.aarch64.test",
|
||||
"org.graalvm.compiler.core.amd64.test",
|
||||
"org.graalvm.compiler.core.sparc.test",
|
||||
"org.graalvm.compiler.debug.test",
|
||||
"org.graalvm.compiler.hotspot.aarch64.test",
|
||||
"org.graalvm.compiler.hotspot.amd64.test",
|
||||
"org.graalvm.compiler.hotspot.lir.test",
|
||||
"org.graalvm.compiler.hotspot.sparc.test",
|
||||
"org.graalvm.compiler.options.test",
|
||||
"org.graalvm.compiler.jtt",
|
||||
"org.graalvm.compiler.lir.jtt",
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
@ -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)})");
|
||||
}
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.options;
|
||||
package org.graalvm.collections.test;
|
||||
|
||||
/**
|
||||
* Categorizes options according to user relevance.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public enum OptionCategory {
|
||||
import org.graalvm.collections.Pair;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* An option common for users to apply.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
USER,
|
||||
public class PairTest {
|
||||
|
||||
/**
|
||||
* An option only relevant in corner cases and for fine-tuning.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
EXPERT,
|
||||
@Test
|
||||
public void testCreate() {
|
||||
Assert.assertEquals(Pair.create(null, null), Pair.empty());
|
||||
Assert.assertNotEquals(Pair.create(null, null), null);
|
||||
Assert.assertEquals(Pair.createLeft(null), Pair.empty());
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
* An option only relevant when debugging language or instrument implementations.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
DEBUG
|
||||
@Test
|
||||
public void testUtilities() {
|
||||
Pair<Integer, Integer> pair = Pair.create(1, null);
|
||||
Assert.assertEquals(pair.getLeft(), Integer.valueOf(1));
|
||||
Assert.assertEquals(pair.getRight(), null);
|
||||
Assert.assertEquals(pair.toString(), "(1, null)");
|
||||
Assert.assertEquals(pair.hashCode(), Pair.createLeft(1).hashCode());
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -20,21 +22,34 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.util;
|
||||
package org.graalvm.collections;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.graalvm.util.impl.EconomicMapImpl;
|
||||
|
||||
/**
|
||||
* Memory efficient map data structure.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Copies all of the mappings from {@code other} to this map.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
default void putAll(EconomicMap<K, V> other) {
|
||||
MapCursor<K, V> e = other.getEntries();
|
||||
while (e.advance()) {
|
||||
@ -42,15 +57,11 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
|
||||
}
|
||||
}
|
||||
|
||||
void clear();
|
||||
|
||||
V removeKey(K key);
|
||||
|
||||
@Override
|
||||
MapCursor<K, V> getEntries();
|
||||
|
||||
void replaceAll(BiFunction<? super K, ? super V, ? extends V> function);
|
||||
|
||||
/**
|
||||
* Copies all of the mappings from {@code other} to this map.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
default void putAll(UnmodifiableEconomicMap<? extends K, ? extends V> other) {
|
||||
UnmodifiableMapCursor<? extends K, ? extends V> entry = other.getEntries();
|
||||
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
|
||||
* {@link Equivalence#DEFAULT} comparison strategy for keys.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
static <K, V> EconomicMap<K, V> create() {
|
||||
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
|
||||
* {@link Equivalence#DEFAULT} comparison strategy for keys and initializes with a specified
|
||||
* capacity.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
static <K, V> EconomicMap<K, V> create(int 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
|
||||
* strategy for keys.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
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
|
||||
* {@link Equivalence#DEFAULT} comparison strategy for keys and copies all elements from the
|
||||
* specified existing map.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
static <K, V> EconomicMap<K, V> create(UnmodifiableEconomicMap<K, V> 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
|
||||
* the specified existing map.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
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
|
||||
* specified capacity.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
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) {
|
||||
return new EconomicMap<K, V>() {
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -20,19 +22,12 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.util.impl;
|
||||
package org.graalvm.collections;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Objects;
|
||||
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
|
||||
* 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
|
||||
* {@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.
|
||||
@ -135,45 +130,46 @@ public final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicS
|
||||
return map;
|
||||
}
|
||||
|
||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy) {
|
||||
return intercept(new EconomicMapImpl<>(strategy));
|
||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, boolean isSet) {
|
||||
return intercept(new EconomicMapImpl<>(strategy, isSet));
|
||||
}
|
||||
|
||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, int initialCapacity) {
|
||||
return intercept(new EconomicMapImpl<>(strategy, initialCapacity));
|
||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, int initialCapacity, boolean isSet) {
|
||||
return intercept(new EconomicMapImpl<>(strategy, initialCapacity, isSet));
|
||||
}
|
||||
|
||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> other) {
|
||||
return intercept(new EconomicMapImpl<>(strategy, other));
|
||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> other, boolean isSet) {
|
||||
return intercept(new EconomicMapImpl<>(strategy, other, isSet));
|
||||
}
|
||||
|
||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicSet<K> other) {
|
||||
return intercept(new EconomicMapImpl<>(strategy, other));
|
||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicSet<K> other, boolean isSet) {
|
||||
return intercept(new EconomicMapImpl<>(strategy, other, isSet));
|
||||
}
|
||||
|
||||
private EconomicMapImpl(Equivalence strategy) {
|
||||
private EconomicMapImpl(Equivalence strategy, boolean isSet) {
|
||||
if (strategy == Equivalence.IDENTITY) {
|
||||
this.strategy = null;
|
||||
} else {
|
||||
this.strategy = strategy;
|
||||
}
|
||||
this.isSet = isSet;
|
||||
}
|
||||
|
||||
private EconomicMapImpl(Equivalence strategy, int initialCapacity) {
|
||||
this(strategy);
|
||||
private EconomicMapImpl(Equivalence strategy, int initialCapacity, boolean isSet) {
|
||||
this(strategy, isSet);
|
||||
init(initialCapacity);
|
||||
}
|
||||
|
||||
private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicMap<K, V> other) {
|
||||
this(strategy);
|
||||
private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicMap<K, V> other, boolean isSet) {
|
||||
this(strategy, isSet);
|
||||
if (!initFrom(other)) {
|
||||
init(other.size());
|
||||
putAll(other);
|
||||
}
|
||||
}
|
||||
|
||||
private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicSet<K> other) {
|
||||
this(strategy);
|
||||
private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicSet<K> other, boolean isSet) {
|
||||
this(strategy, isSet);
|
||||
if (!initFrom(other)) {
|
||||
init(other.size());
|
||||
addAll(other);
|
||||
@ -807,13 +803,22 @@ public final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicS
|
||||
return object;
|
||||
}
|
||||
|
||||
private final boolean isSet;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
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();
|
||||
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("})");
|
||||
return builder.toString();
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -20,56 +22,109 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.util;
|
||||
package org.graalvm.collections;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.graalvm.util.impl.EconomicMapImpl;
|
||||
|
||||
/**
|
||||
* Memory efficient set data structure.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Removes all of the elements from this set. The set will be empty after this call returns.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
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) {
|
||||
addAll(values.iterator());
|
||||
}
|
||||
|
||||
default void addAll(Iterator<E> values) {
|
||||
while (values.hasNext()) {
|
||||
add(values.next());
|
||||
/**
|
||||
* Adds all of the elements enumerated by {@code iterator} to this set if they're not already
|
||||
* 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) {
|
||||
removeAll(values.iterator());
|
||||
}
|
||||
|
||||
default void removeAll(Iterator<E> values) {
|
||||
while (values.hasNext()) {
|
||||
remove(values.next());
|
||||
/**
|
||||
* Removes from this set all of its elements that are enumerated by {@code iterator}.
|
||||
*
|
||||
* @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();
|
||||
while (iterator.hasNext()) {
|
||||
E key = iterator.next();
|
||||
if (!values.contains(key)) {
|
||||
if (!other.contains(key)) {
|
||||
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
|
||||
* default {@link Equivalence#DEFAULT} comparison strategy.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
static <E> EconomicSet<E> create() {
|
||||
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.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
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
|
||||
* default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
|
||||
* specified collection.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
static <E> EconomicSet<E> create(int 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
|
||||
* default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
|
||||
* specified collection.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
static <E> EconomicSet<E> create(UnmodifiableEconomicSet<E> 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
|
||||
* initializes with the given capacity.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
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
|
||||
* all elements of the specified collection.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
static <E> EconomicSet<E> create(Equivalence strategy, UnmodifiableEconomicSet<E> c) {
|
||||
return EconomicMapImpl.create(strategy, c);
|
||||
return EconomicMapImpl.create(strategy, c, true);
|
||||
}
|
||||
}
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -20,11 +22,13 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.util;
|
||||
package org.graalvm.collections;
|
||||
|
||||
/**
|
||||
* Strategy for comparing two objects. Default predefined strategies are {@link #DEFAULT},
|
||||
* {@link #IDENTITY}, and {@link #IDENTITY_WITH_SYSTEM_HASHCODE}.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract class Equivalence {
|
||||
|
||||
@ -32,6 +36,8 @@ public abstract class Equivalence {
|
||||
* 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
|
||||
* other places.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
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
|
||||
* 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() {
|
||||
|
||||
@ -67,6 +75,8 @@ public abstract class Equivalence {
|
||||
* Identity equivalence using {@code ==} to check equality and
|
||||
* {@link System#identityHashCode(Object)} for obtaining 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_WITH_SYSTEM_HASHCODE = new Equivalence() {
|
||||
|
||||
@ -83,11 +93,24 @@ public abstract class Equivalence {
|
||||
|
||||
/**
|
||||
* Subclass for creating custom equivalence definitions.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Returns the hash code of a non-{@code null} argument {@code o}.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public abstract int hashCode(Object o);
|
||||
}
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -20,16 +22,20 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.util;
|
||||
package org.graalvm.collections;
|
||||
|
||||
/**
|
||||
* Cursor to iterate over a mutable map.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface MapCursor<K, V> extends UnmodifiableMapCursor<K, V> {
|
||||
/**
|
||||
* 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
|
||||
* the current entry.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
void remove();
|
||||
}
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -20,24 +22,39 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.util;
|
||||
package org.graalvm.collections;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Utility class representing a pair of values.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public final class Pair<L, R> {
|
||||
|
||||
private static final Pair<Object, Object> EMPTY = new Pair<>(null, null);
|
||||
|
||||
private final L left;
|
||||
private final R right;
|
||||
|
||||
/**
|
||||
* Returns an empty pair.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <L, R> 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) {
|
||||
if (left == null) {
|
||||
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) {
|
||||
if (right == null) {
|
||||
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) {
|
||||
if (right == null && left == null) {
|
||||
return empty();
|
||||
@ -67,19 +98,39 @@ public final class Pair<L, R> {
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the left value of this pair.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public L getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the right value of this pair.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public R getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(left) + 31 * Objects.hashCode(right);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
@ -95,6 +146,11 @@ public final class Pair<L, R> {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("(%s, %s)", left, right);
|
@ -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();
|
||||
}
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
OptionDescriptors getDescriptors();
|
||||
boolean contains(E element);
|
||||
|
||||
/**
|
||||
* Sets the value of {@code optionKey} to {@code value}.
|
||||
*
|
||||
* @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}.
|
||||
* Returns the number of elements in this set.
|
||||
*
|
||||
* @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
|
||||
* {@link #getDescriptors() descriptors} the {@link OptionType#getDefaultValue() default value}
|
||||
* of the given key is returned.
|
||||
* Returns {@code true} if this set contains no elements.
|
||||
*
|
||||
* @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
|
||||
* values.
|
||||
* Stores all of the elements in this set into {@code target}. An
|
||||
* {@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
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
@ -4,7 +4,9 @@
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -20,26 +22,33 @@
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.util;
|
||||
package org.graalvm.collections;
|
||||
|
||||
/**
|
||||
* Cursor to iterate over a map without changing its contents.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
public interface UnmodifiableMapCursor<K, V> {
|
||||
/**
|
||||
* Advances to the next entry.
|
||||
*
|
||||
* @return {@code true} if a next entry exists, {@code false} if there is no next entry.
|
||||
* @since 1.0
|
||||
*/
|
||||
boolean advance();
|
||||
|
||||
/**
|
||||
* The key of the current entry.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
K getKey();
|
||||
|
||||
/**
|
||||
* The value of the current entry.
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
V getValue();
|
||||
}
|
@ -23,11 +23,11 @@
|
||||
* 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.options.OptionValues
|
||||
* @see org.graalvm.collections.EconomicMap
|
||||
* @see org.graalvm.collections.EconomicSet
|
||||
*
|
||||
* @since 1.0
|
||||
*/
|
||||
package org.graalvm.options;
|
||||
package org.graalvm.collections;
|
@ -50,6 +50,21 @@ public class ProbabilityDirectiveTest extends GraalCompilerTest {
|
||||
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
|
||||
protected boolean checkLowTierGraph(StructuredGraph graph) {
|
||||
NodeIterable<IfNode> ifNodes = graph.getNodes(IfNode.TYPE);
|
||||
|
@ -49,6 +49,13 @@ public final class GraalDirectives {
|
||||
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.
|
||||
*/
|
||||
|
@ -26,15 +26,52 @@ import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
import jdk.vm.ci.meta.Signature;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* addition, a compiler is recommended to implement {@link MethodSubstitutionRegistry} to advertise
|
||||
* 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>
|
||||
* @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>
|
||||
* @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)
|
||||
@Target(ElementType.METHOD)
|
||||
|
@ -90,4 +90,12 @@ public interface SnippetReflectionProvider {
|
||||
* if this provider cannot provide a value of the requested 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);
|
||||
}
|
||||
|
@ -22,9 +22,19 @@
|
||||
*/
|
||||
package org.graalvm.compiler.api.runtime;
|
||||
|
||||
import jdk.vm.ci.common.JVMCIError;
|
||||
|
||||
public interface GraalRuntime {
|
||||
|
||||
String getName();
|
||||
|
||||
<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;
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,6 @@ public class AMD64Assembler extends Assembler {
|
||||
}
|
||||
|
||||
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_38 = 0x2;
|
||||
private static final int VEX_OPCODE_0F_3A = 0x3;
|
||||
@ -861,9 +860,26 @@ public class AMD64Assembler extends Assembler {
|
||||
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) {
|
||||
int pre;
|
||||
int opc;
|
||||
boolean rexVexW = (size == QWORD) ? true : false;
|
||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||
int curPrefix = size.sizePrefix | prefix1;
|
||||
@ -881,20 +897,6 @@ public class AMD64Assembler extends Assembler {
|
||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||
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;
|
||||
if (noNds) {
|
||||
encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes);
|
||||
@ -938,9 +940,26 @@ public class AMD64Assembler extends Assembler {
|
||||
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) {
|
||||
int pre;
|
||||
int opc;
|
||||
boolean rexVexW = (size == QWORD) ? true : false;
|
||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||
int curPrefix = size.sizePrefix | prefix1;
|
||||
@ -958,20 +977,6 @@ public class AMD64Assembler extends Assembler {
|
||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||
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) {
|
||||
asm.simdPrefix(dst, Register.None, src, pre, opc, attributes);
|
||||
} else {
|
||||
@ -1055,8 +1060,7 @@ public class AMD64Assembler extends Assembler {
|
||||
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
||||
break;
|
||||
default:
|
||||
opc = VexOpcode.VEX_OPCODE_NONE;
|
||||
break;
|
||||
throw GraalError.shouldNotReachHere("invalid VEX instruction prefix");
|
||||
}
|
||||
int encode;
|
||||
encode = asm.simdPrefixAndEncode(dst, nds, src, pre, opc, attributes);
|
||||
@ -1096,8 +1100,7 @@ public class AMD64Assembler extends Assembler {
|
||||
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
||||
break;
|
||||
default:
|
||||
opc = VexOpcode.VEX_OPCODE_NONE;
|
||||
break;
|
||||
throw GraalError.shouldNotReachHere("invalid VEX instruction prefix");
|
||||
}
|
||||
asm.simdPrefix(dst, nds, src, pre, opc, attributes);
|
||||
asm.emitByte(op);
|
||||
@ -1163,9 +1166,26 @@ public class AMD64Assembler extends Assembler {
|
||||
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) {
|
||||
int pre;
|
||||
int opc;
|
||||
boolean rexVexW = (size == QWORD) ? true : false;
|
||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||
int curPrefix = size.sizePrefix | prefix1;
|
||||
@ -1183,20 +1203,6 @@ public class AMD64Assembler extends Assembler {
|
||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||
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;
|
||||
if (noNds) {
|
||||
encode = asm.simdPrefixAndEncode(src, Register.None, dst, pre, opc, attributes);
|
||||
@ -1222,9 +1228,26 @@ public class AMD64Assembler extends Assembler {
|
||||
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) {
|
||||
int pre;
|
||||
int opc;
|
||||
boolean rexVexW = (size == QWORD) ? true : false;
|
||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||
int curPrefix = size.sizePrefix | prefix1;
|
||||
@ -1242,20 +1265,6 @@ public class AMD64Assembler extends Assembler {
|
||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||
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.emitByte(op);
|
||||
asm.emitOperandHelper(src, dst, 0);
|
||||
@ -1390,9 +1399,26 @@ public class AMD64Assembler extends Assembler {
|
||||
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) {
|
||||
int pre;
|
||||
int opc;
|
||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||
int curPrefix = size.sizePrefix | prefix1;
|
||||
switch (curPrefix) {
|
||||
@ -1409,20 +1435,6 @@ public class AMD64Assembler extends Assembler {
|
||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||
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;
|
||||
if (noNds) {
|
||||
encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes);
|
||||
@ -1453,9 +1465,26 @@ public class AMD64Assembler extends Assembler {
|
||||
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) {
|
||||
int pre;
|
||||
int opc;
|
||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||
int curPrefix = size.sizePrefix | prefix1;
|
||||
switch (curPrefix) {
|
||||
@ -1472,21 +1501,6 @@ public class AMD64Assembler extends Assembler {
|
||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||
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) {
|
||||
asm.simdPrefix(dst, Register.None, src, pre, opc, attributes);
|
||||
} else {
|
||||
|
@ -33,9 +33,9 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import org.graalvm.compiler.core.common.CompilationIdentifier;
|
||||
import org.graalvm.compiler.graph.NodeSourcePosition;
|
||||
import org.graalvm.util.EconomicSet;
|
||||
|
||||
import jdk.vm.ci.code.DebugInfo;
|
||||
import jdk.vm.ci.code.StackSlot;
|
||||
|
@ -40,7 +40,7 @@ public final class DataSection implements Iterable<Data> {
|
||||
|
||||
public interface Patches {
|
||||
|
||||
void registerPatch(VMConstant c);
|
||||
void registerPatch(int position, VMConstant c);
|
||||
}
|
||||
|
||||
public abstract static class Data {
|
||||
|
@ -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.type.AbstractPointerStamp;
|
||||
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.nodes.NodeView;
|
||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||
@ -107,7 +106,9 @@ public class AMD64AddressLowering extends AddressLowering {
|
||||
ret.setBase(add.getX());
|
||||
ret.setIndex(considerNegation(graph, add.getY(), isBaseNegated));
|
||||
return true;
|
||||
} else if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
|
||||
}
|
||||
|
||||
if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
|
||||
AddNode add = (AddNode) ret.getIndex();
|
||||
ret.setBase(considerNegation(graph, add.getX(), isIndexNegated));
|
||||
ret.setIndex(add.getY());
|
||||
@ -188,7 +189,7 @@ public class AMD64AddressLowering extends AddressLowering {
|
||||
return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
|
||||
} else {
|
||||
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:
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@ -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.WORD;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
import org.graalvm.compiler.core.common.LIRKind;
|
||||
import org.graalvm.compiler.lir.VirtualStackSlot;
|
||||
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
|
||||
import org.graalvm.compiler.lir.amd64.AMD64Move.AMD64PushPopStackMove;
|
||||
import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
|
||||
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.code.Architecture;
|
||||
|
@ -44,6 +44,7 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
|
||||
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
|
||||
import org.graalvm.compiler.core.common.LIRKind;
|
||||
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.gen.NodeLIRBuilder;
|
||||
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) {
|
||||
Condition cond = compare.condition();
|
||||
Condition cond = compare.condition().asCondition();
|
||||
AMD64Kind kind = getMemoryKind(access);
|
||||
boolean matchedAsConstant = false; // For assertion checking
|
||||
|
||||
@ -303,7 +304,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
|
||||
@MatchRule("(If (FloatEquals=compare value ValueCompareAndSwap=cas))")
|
||||
@MatchRule("(If (IntegerEquals=compare value ValueCompareAndSwap=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) {
|
||||
return builder -> {
|
||||
LIRKind kind = getLirKind(cas);
|
||||
@ -326,7 +327,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
|
||||
@MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
|
||||
public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
|
||||
JavaConstant constant = value.asJavaConstant();
|
||||
assert compare.condition() == Condition.EQ;
|
||||
assert compare.condition() == CanonicalCondition.EQ;
|
||||
if (constant != null && cas.usages().count() == 1) {
|
||||
long constantValue = constant.asLong();
|
||||
boolean successIsTrue;
|
||||
|
@ -232,6 +232,9 @@ public final class GraalOptions {
|
||||
@Option(help = "", type = OptionType.Debug)
|
||||
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)
|
||||
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)
|
||||
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);
|
||||
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.util;
|
||||
package org.graalvm.compiler.core.common;
|
||||
|
||||
/**
|
||||
* Unmodifiable memory efficient set data structure.
|
||||
*/
|
||||
public interface UnmodifiableEconomicSet<E> extends Iterable<E> {
|
||||
public enum TraceInliningMode {
|
||||
None(false),
|
||||
Linear(true),
|
||||
Tree(true);
|
||||
|
||||
boolean contains(E element);
|
||||
private final boolean tracing;
|
||||
|
||||
int size();
|
||||
TraceInliningMode(boolean tracing) {
|
||||
this.tracing = tracing;
|
||||
}
|
||||
|
||||
boolean isEmpty();
|
||||
|
||||
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;
|
||||
public boolean isTracing() {
|
||||
return tracing;
|
||||
}
|
||||
}
|
@ -22,9 +22,9 @@
|
||||
*/
|
||||
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.util.EconomicMap;
|
||||
import org.graalvm.util.Equivalence;
|
||||
|
||||
import jdk.vm.ci.code.Register;
|
||||
import jdk.vm.ci.code.Register.RegisterCategory;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -115,6 +115,55 @@ public enum Condition {
|
||||
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
|
||||
* 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
|
||||
* result of the mirroring operation might still need to be negated to achieve a canonical form.
|
||||
*/
|
||||
public boolean canonicalMirror() {
|
||||
private boolean canonicalMirror() {
|
||||
switch (this) {
|
||||
case EQ:
|
||||
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
|
||||
* of the negation might still need to be mirrored to achieve a canonical form.
|
||||
*/
|
||||
public boolean canonicalNegate() {
|
||||
private boolean canonicalNegate() {
|
||||
switch (this) {
|
||||
case EQ:
|
||||
return false;
|
||||
|
@ -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.
|
||||
*
|
||||
* 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
|
||||
* questions.
|
||||
*/
|
||||
package org.graalvm.util;
|
||||
package org.graalvm.compiler.core.common.spi;
|
||||
|
||||
/**
|
||||
* Unmodifiable memory efficient map data structure.
|
||||
*/
|
||||
public interface UnmodifiableEconomicMap<K, V> {
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
|
||||
V get(K key);
|
||||
public interface ArrayOffsetProvider {
|
||||
|
||||
default V get(K key, V defaultValue) {
|
||||
V v = get(key);
|
||||
if (v == null) {
|
||||
return defaultValue;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
int arrayBaseOffset(JavaKind elementKind);
|
||||
|
||||
boolean containsKey(K key);
|
||||
|
||||
int size();
|
||||
|
||||
boolean isEmpty();
|
||||
|
||||
Iterable<V> getValues();
|
||||
|
||||
Iterable<K> getKeys();
|
||||
|
||||
UnmodifiableMapCursor<K, V> getEntries();
|
||||
int arrayScalingFactor(JavaKind elementKind);
|
||||
}
|
@ -40,4 +40,5 @@ public interface CodeGenProviders {
|
||||
|
||||
ConstantReflectionProvider getConstantReflection();
|
||||
|
||||
ArrayOffsetProvider getArrayOffsetProvider();
|
||||
}
|
||||
|
@ -28,6 +28,9 @@ import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
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.type.ArithmeticOpTable.BinaryOp.Add;
|
||||
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.util.CollectionsUtil;
|
||||
|
||||
import jdk.vm.ci.meta.Constant;
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
|
||||
/**
|
||||
* Information about arithmetic operations.
|
||||
*/
|
||||
|
@ -25,8 +25,8 @@ package org.graalvm.compiler.core.common.util;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.graalvm.util.Equivalence;
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.Equivalence;
|
||||
|
||||
/**
|
||||
* Creates an array of T objects order by the occurrence frequency of each object. The most
|
||||
|
@ -58,6 +58,9 @@ import javax.tools.FileObject;
|
||||
import javax.tools.JavaFileObject;
|
||||
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.match.ComplexMatchResult;
|
||||
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.nodes.ValueNode;
|
||||
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
|
||||
|
@ -29,6 +29,7 @@ import static jdk.vm.ci.sparc.SPARCKind.WORD;
|
||||
import static jdk.vm.ci.sparc.SPARCKind.XWORD;
|
||||
|
||||
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.gen.NodeMatchRules;
|
||||
import org.graalvm.compiler.core.match.ComplexMatchResult;
|
||||
@ -147,7 +148,7 @@ public class SPARCNodeMatchRules extends NodeMatchRules {
|
||||
@MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
|
||||
public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
|
||||
JavaConstant constant = value.asJavaConstant();
|
||||
assert compare.condition() == Condition.EQ;
|
||||
assert compare.condition() == CanonicalCondition.EQ;
|
||||
if (constant != null && cas.usages().count() == 1) {
|
||||
long constantValue = constant.asLong();
|
||||
boolean successIsTrue;
|
||||
|
@ -123,19 +123,19 @@ public class ConditionalEliminationTest11 extends ConditionalEliminationTestBase
|
||||
|
||||
public static int test6Snippet(int a) {
|
||||
if ((a & 8) != 0) {
|
||||
GraalDirectives.deoptimizeAndInvalidate();
|
||||
GraalDirectives.deoptimize();
|
||||
}
|
||||
if ((a & 15) != 15) {
|
||||
GraalDirectives.deoptimizeAndInvalidate();
|
||||
GraalDirectives.deoptimize();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int reference6Snippet(int a) {
|
||||
if ((a & 8) != 0) {
|
||||
GraalDirectives.deoptimizeAndInvalidate();
|
||||
GraalDirectives.deoptimize();
|
||||
}
|
||||
GraalDirectives.deoptimizeAndInvalidate();
|
||||
GraalDirectives.deoptimize();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,6 @@ public class ConditionalEliminationTestBase extends GraalCompilerTest {
|
||||
new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
|
||||
canonicalizer.apply(graph, context);
|
||||
canonicalizer.apply(graph, context);
|
||||
new ConvertDeoptimizeToGuardPhase().apply(graph, context);
|
||||
} catch (Throwable t) {
|
||||
debug.handle(t);
|
||||
}
|
||||
@ -86,7 +85,6 @@ public class ConditionalEliminationTestBase extends GraalCompilerTest {
|
||||
}
|
||||
canonicalizer.apply(referenceGraph, context);
|
||||
canonicalizer.apply(referenceGraph, context);
|
||||
new ConvertDeoptimizeToGuardPhase().apply(graph, context);
|
||||
} catch (Throwable t) {
|
||||
debug.handle(t);
|
||||
}
|
||||
|
@ -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.NodeSize.SIZE_IGNORED;
|
||||
|
||||
import org.graalvm.compiler.nodes.NodeView;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.graalvm.compiler.api.directives.GraalDirectives;
|
||||
import org.graalvm.compiler.graph.NodeClass;
|
||||
import org.graalvm.compiler.loop.InductionVariable;
|
||||
import org.graalvm.compiler.loop.LoopsData;
|
||||
import org.graalvm.compiler.nodeinfo.NodeInfo;
|
||||
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;
|
||||
@ -42,6 +40,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
|
||||
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
|
||||
import org.graalvm.compiler.nodes.spi.LIRLowerable;
|
||||
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.vm.ci.meta.JavaKind;
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
@ -117,6 +116,21 @@ public class CountedLoopTest extends GraalCompilerTest {
|
||||
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) {
|
||||
int i;
|
||||
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
|
||||
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) {
|
||||
int i;
|
||||
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
|
||||
public void decrementEq4() {
|
||||
test("decrementEqSnippet", -10, 0, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
public static Result twoVariablesSnippet() {
|
||||
Result ret = new Result();
|
||||
int j = 0;
|
||||
|
@ -27,10 +27,10 @@ import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.compiler.debug.DebugOptions;
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -561,7 +561,7 @@ public abstract class GraalCompilerTest extends GraalTest {
|
||||
* @return a scheduled textual dump of {@code 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);
|
||||
ScheduleResult scheduleResult = graph.getLastSchedule();
|
||||
|
||||
|
@ -22,14 +22,14 @@
|
||||
*/
|
||||
package org.graalvm.compiler.core.test;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
import org.graalvm.compiler.debug.DebugOptions;
|
||||
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.AllowAssumptions;
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -24,20 +24,29 @@ package org.graalvm.compiler.core.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
|
||||
import org.graalvm.compiler.graph.Node;
|
||||
import org.graalvm.compiler.graph.NodeMap;
|
||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||
import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
|
||||
import org.graalvm.compiler.nodes.cfg.Block;
|
||||
import org.graalvm.compiler.phases.schedule.SchedulePhase;
|
||||
import org.junit.Assert;
|
||||
|
||||
import jdk.vm.ci.meta.SpeculationLog;
|
||||
|
||||
public class GraphScheduleTest extends GraalCompilerTest {
|
||||
|
||||
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);
|
||||
assertOrderedAfterLastSchedule(graph, a, b);
|
||||
}
|
||||
|
||||
protected void assertOrderedAfterLastSchedule(StructuredGraph graph, Node a, Node b) {
|
||||
assertOrderedAfterSchedule(graph.getLastSchedule(), a, b);
|
||||
}
|
||||
|
||||
@ -48,7 +57,7 @@ public class GraphScheduleTest extends GraalCompilerTest {
|
||||
|
||||
if (bBlock == aBlock) {
|
||||
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 {
|
||||
Block block = bBlock;
|
||||
while (block != null) {
|
||||
@ -60,4 +69,9 @@ public class GraphScheduleTest extends GraalCompilerTest {
|
||||
Assert.fail("block of A doesn't dominate the block of B");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected SpeculationLog getSpeculationLog() {
|
||||
return getCodeCache().createSpeculationLog();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -44,7 +44,7 @@ public class LongNodeChainTest extends GraalCompilerTest {
|
||||
|
||||
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
|
||||
public void testLongAddChain() {
|
||||
|
@ -31,13 +31,13 @@ import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
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.OptionDescriptor;
|
||||
import org.graalvm.compiler.options.OptionDescriptors;
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
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
|
||||
|
@ -70,7 +70,7 @@ public class SchedulingTest2 extends GraphScheduleTest {
|
||||
returnNode.replaceAtPredecessor(beginNode);
|
||||
beginNode.setNext(returnNode);
|
||||
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);
|
||||
ScheduleResult schedule = graph.getLastSchedule();
|
||||
BlockMap<List<Node>> blockToNodesMap = schedule.getBlockToNodesMap();
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ package org.graalvm.compiler.core.test.inlining;
|
||||
|
||||
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.debug.DebugContext;
|
||||
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.virtual.phases.ea.EarlyReadEliminationPhase;
|
||||
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
|
||||
import org.graalvm.util.EconomicSet;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
|
@ -25,6 +25,7 @@ package org.graalvm.compiler.core;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
import org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext;
|
||||
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.TargetProvider;
|
||||
import org.graalvm.compiler.phases.util.Providers;
|
||||
import org.graalvm.util.EconomicSet;
|
||||
|
||||
import jdk.vm.ci.code.RegisterConfig;
|
||||
import jdk.vm.ci.code.TargetDescription;
|
||||
|
@ -26,6 +26,8 @@ import java.util.ArrayDeque;
|
||||
import java.util.Arrays;
|
||||
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.DebugContext;
|
||||
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.virtual.nodes.MaterializedObjectState;
|
||||
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.VirtualObject;
|
||||
|
@ -33,6 +33,8 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
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.calc.Condition;
|
||||
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.virtual.VirtualObjectNode;
|
||||
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.StackSlot;
|
||||
@ -538,7 +538,8 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
|
||||
|
||||
public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
|
||||
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) {
|
||||
@ -566,7 +567,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
|
||||
} else if (node instanceof CompareNode) {
|
||||
CompareNode compare = (CompareNode) node;
|
||||
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) {
|
||||
return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue);
|
||||
} else if (node instanceof IntegerTestNode) {
|
||||
|
@ -28,6 +28,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
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.match.MatchPattern.Result;
|
||||
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.nodes.calc.FloatingNode;
|
||||
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.graalvm.util.Equivalence;
|
||||
|
||||
/**
|
||||
* Container for state captured during a match.
|
||||
|
@ -27,6 +27,9 @@ import static org.graalvm.compiler.debug.DebugOptions.LogVerbose;
|
||||
import java.util.ArrayList;
|
||||
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.debug.DebugContext;
|
||||
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.options.OptionValues;
|
||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.graalvm.util.Equivalence;
|
||||
import org.graalvm.util.MapCursor;
|
||||
|
||||
public class MatchRuleRegistry {
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
*/
|
||||
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.graph.Graph.NodeEvent;
|
||||
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.common.util.HashSetNodeEventListener;
|
||||
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
|
||||
|
@ -24,6 +24,7 @@ package org.graalvm.compiler.core.target;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import org.graalvm.compiler.asm.Assembler;
|
||||
import org.graalvm.compiler.code.CompilationResult;
|
||||
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.TargetProvider;
|
||||
import org.graalvm.compiler.phases.util.Providers;
|
||||
import org.graalvm.util.EconomicSet;
|
||||
|
||||
import jdk.vm.ci.code.BailoutException;
|
||||
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);
|
||||
DebugContext.Activation a = debug.activate()) {
|
||||
for (CodeInstallationTask task : tasks) {
|
||||
task.preProcess(compilationResult);
|
||||
}
|
||||
preCodeInstallationTasks(tasks, compilationResult);
|
||||
|
||||
CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
|
||||
InstalledCode installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
|
||||
|
||||
// Run post-code installation tasks.
|
||||
InstalledCode installedCode;
|
||||
try {
|
||||
for (CodeInstallationTask task : tasks) {
|
||||
task.postProcess(installedCode);
|
||||
}
|
||||
for (CodeInstallationTask task : tasks) {
|
||||
task.releaseInstallation(installedCode);
|
||||
}
|
||||
CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
|
||||
installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
|
||||
} catch (Throwable t) {
|
||||
installedCode.invalidate();
|
||||
failCodeInstallationTasks(tasks, t);
|
||||
throw t;
|
||||
}
|
||||
|
||||
postCodeInstallationTasks(tasks, installedCode);
|
||||
|
||||
return installedCode;
|
||||
} catch (Throwable 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.
|
||||
*
|
||||
@ -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
|
||||
* installed code.
|
||||
* Invoked after {@link #preProcess} when code installation fails.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public void releaseInstallation(InstalledCode installedCode) {
|
||||
public void installFailed(Throwable t) {
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import java.util.Collections;
|
||||
import java.util.Formatter;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.compiler.debug.Assertions;
|
||||
import org.graalvm.compiler.debug.CounterKey;
|
||||
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.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
|
@ -30,6 +30,7 @@ import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.lang.management.ThreadMXBean;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.compiler.debug.DebugCloseable;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
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.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
@ -22,7 +22,7 @@
|
||||
*/
|
||||
package org.graalvm.compiler.debug;
|
||||
|
||||
import org.graalvm.util.Pair;
|
||||
import org.graalvm.collections.Pair;
|
||||
|
||||
class CounterKeyImpl extends AbstractKey implements CounterKey {
|
||||
|
||||
|
@ -56,12 +56,12 @@ import java.util.Map;
|
||||
import java.util.SortedMap;
|
||||
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.OptionValues;
|
||||
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;
|
||||
|
||||
@ -1937,10 +1937,17 @@ public final class DebugContext implements AutoCloseable {
|
||||
if (description != null) {
|
||||
printMetrics(description);
|
||||
}
|
||||
if (metricsEnabled && globalMetrics != null && metricValues != null) {
|
||||
if (metricsEnabled && metricValues != null && globalMetrics != null) {
|
||||
globalMetrics.add(this);
|
||||
}
|
||||
metricValues = null;
|
||||
if (sharedChannel != null) {
|
||||
try {
|
||||
sharedChannel.realClose();
|
||||
} catch (IOException ex) {
|
||||
// ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void closeDumpHandlers(boolean ignoreErrors) {
|
||||
@ -2022,7 +2029,6 @@ public final class DebugContext implements AutoCloseable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,11 +27,11 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.compiler.options.Option;
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionType;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
|
||||
/**
|
||||
* Options that configure a {@link DebugContext} and related functionality.
|
||||
|
@ -29,10 +29,10 @@ import java.nio.file.Paths;
|
||||
import java.util.Collections;
|
||||
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.util.EconomicMap;
|
||||
import org.graalvm.util.MapCursor;
|
||||
import org.graalvm.util.Pair;
|
||||
|
||||
/**
|
||||
* Metric values that can be {@linkplain #add(DebugContext) updated} by multiple threads.
|
||||
|
@ -25,7 +25,7 @@ package org.graalvm.compiler.debug;
|
||||
import java.util.ArrayList;
|
||||
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}.
|
||||
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.debug;
|
||||
|
||||
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 {
|
||||
|
||||
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.debug;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.graalvm.util.Pair;
|
||||
import org.graalvm.collections.Pair;
|
||||
|
||||
/**
|
||||
* A key for a metric.
|
||||
|
@ -26,7 +26,7 @@ import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.graalvm.util.Pair;
|
||||
import org.graalvm.collections.Pair;
|
||||
|
||||
final class TimerKeyImpl extends AccumulatedKey implements TimerKey {
|
||||
static class FlatTimer extends AbstractKey implements TimerKey {
|
||||
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.graph;
|
||||
|
||||
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
|
||||
|
@ -30,6 +30,9 @@ import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
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.DebugCloseable;
|
||||
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.OptionType;
|
||||
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.
|
||||
|
@ -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() {
|
||||
nodeCount = Math.max(nodeCount, graph().nodeIdCount());
|
||||
int newLength = sizeForNodeCount(nodeCount);
|
||||
|
@ -42,6 +42,8 @@ import java.util.NoSuchElementException;
|
||||
import java.util.Objects;
|
||||
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.Fields;
|
||||
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.NodeSize;
|
||||
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:
|
||||
|
@ -26,8 +26,8 @@ import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.graalvm.util.MapCursor;
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.collections.MapCursor;
|
||||
|
||||
public class NodeMap<T> extends NodeIdAccessor implements EconomicMap<Node, T> {
|
||||
|
||||
|
@ -74,6 +74,10 @@ public final class NodeStack {
|
||||
return tos == 0;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
tos = 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (tos == 0) {
|
||||
|
@ -22,7 +22,6 @@
|
||||
*/
|
||||
package org.graalvm.compiler.hotspot.aarch64;
|
||||
|
||||
import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
|
||||
import static java.lang.reflect.Modifier.isStatic;
|
||||
import static jdk.vm.ci.aarch64.AArch64.lr;
|
||||
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.code.ValueUtil.asRegister;
|
||||
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.Label;
|
||||
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.alloc.RegisterAllocationConfig;
|
||||
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.HotSpotGraalRuntimeProvider;
|
||||
import org.graalvm.compiler.hotspot.HotSpotHostBackend;
|
||||
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.HotSpotProviders;
|
||||
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.nodes.StructuredGraph;
|
||||
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
||||
import org.graalvm.util.EconomicSet;
|
||||
|
||||
import jdk.vm.ci.code.CallingConvention;
|
||||
import jdk.vm.ci.code.Register;
|
||||
|
@ -49,6 +49,7 @@ import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider;
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
|
||||
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
|
||||
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.phases.tiers.CompilerConfiguration;
|
||||
import org.graalvm.compiler.phases.util.Providers;
|
||||
@ -136,7 +137,7 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
replacements = createReplacements(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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,
|
||||
HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements,
|
||||
HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
|
||||
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements);
|
||||
HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection,
|
||||
HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
|
||||
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
|
||||
replacements);
|
||||
AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider());
|
||||
return plugins;
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -24,64 +24,50 @@
|
||||
package org.graalvm.compiler.hotspot.amd64;
|
||||
|
||||
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.core.amd64.AMD64AddressLowering;
|
||||
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.LIRKind;
|
||||
import org.graalvm.compiler.core.common.type.IntegerStamp;
|
||||
import org.graalvm.compiler.core.common.type.ObjectStamp;
|
||||
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.graph.Node;
|
||||
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
||||
import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
|
||||
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.CompressionOp;
|
||||
import org.graalvm.compiler.nodes.ConstantNode;
|
||||
import org.graalvm.compiler.nodes.NodeView;
|
||||
import org.graalvm.compiler.nodes.PhiNode;
|
||||
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 org.graalvm.compiler.nodes.calc.AddNode;
|
||||
import org.graalvm.compiler.nodes.calc.SignExtendNode;
|
||||
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 jdk.vm.ci.code.Register;
|
||||
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 Register heapBaseRegister;
|
||||
private final GraalHotSpotVMConfig config;
|
||||
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) {
|
||||
this.heapBase = config.getOopEncoding().getBase();
|
||||
this.config = config;
|
||||
@ -94,35 +80,7 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated) {
|
||||
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;
|
||||
}
|
||||
|
||||
protected final boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other) {
|
||||
CompressEncoding encoding = compression.getEncoding();
|
||||
Scale scale = Scale.fromShift(encoding.getShift());
|
||||
if (scale == null) {
|
||||
@ -147,7 +105,7 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (updateDisplacement(addr, encoding.getBase(), isBaseNegated)) {
|
||||
if (updateDisplacement(addr, encoding.getBase(), false)) {
|
||||
addr.setBase(other);
|
||||
} else {
|
||||
return false;
|
||||
@ -161,4 +119,117 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
|
||||
addr.setIndex(compression.getValue());
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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.ZapStackOnMethodEntry;
|
||||
|
||||
import org.graalvm.collections.EconomicSet;
|
||||
import org.graalvm.compiler.asm.Assembler;
|
||||
import org.graalvm.compiler.asm.Label;
|
||||
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.spi.NodeLIRBuilderTool;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.util.EconomicSet;
|
||||
|
||||
import jdk.vm.ci.amd64.AMD64;
|
||||
import jdk.vm.ci.amd64.AMD64Kind;
|
||||
|
@ -49,6 +49,7 @@ import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider;
|
||||
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
|
||||
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
|
||||
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.options.OptionValues;
|
||||
import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
|
||||
@ -137,7 +138,7 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
replacements = createReplacements(options, p, snippetReflection, bytecodeProvider);
|
||||
}
|
||||
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);
|
||||
replacements.setGraphBuilderPlugins(plugins);
|
||||
}
|
||||
@ -154,9 +155,10 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
}
|
||||
|
||||
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) {
|
||||
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));
|
||||
return plugins;
|
||||
}
|
||||
|
@ -572,7 +572,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
|
||||
if (inputKind.isReference(0)) {
|
||||
// oop
|
||||
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;
|
||||
} else {
|
||||
// metaspace pointer
|
||||
@ -589,7 +589,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -602,7 +602,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
|
||||
if (inputKind.isReference(0)) {
|
||||
// oop
|
||||
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;
|
||||
} else {
|
||||
// metaspace pointer
|
||||
@ -620,7 +620,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,8 @@ public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider
|
||||
public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, GraalHotSpotVMConfig config) {
|
||||
convertSnippets = new AMD64ConvertSnippets.Templates(options, factories, providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget());
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -60,6 +60,7 @@ final class AMD64HotspotDirectVirtualCallOp extends DirectCallOp {
|
||||
crb.recordMark(invokeKind == InvokeKind.Virtual ? config.MARKID_INVOKEVIRTUAL : config.MARKID_INVOKEINTERFACE);
|
||||
// This must be emitted exactly like this to ensure it's patchable
|
||||
masm.movq(AMD64.rax, config.nonOopBits);
|
||||
super.emitCode(crb, masm);
|
||||
int offset = super.emitCall(crb, masm);
|
||||
crb.recordInvokeVirtualOrInterfaceCallOp(offset, getPosition());
|
||||
}
|
||||
}
|
||||
|
@ -70,7 +70,8 @@ final class AMD64IndirectCallOp extends IndirectCallOp {
|
||||
crb.recordMark(config.MARKID_INLINE_INVOKE);
|
||||
Register callReg = asRegister(targetAddress);
|
||||
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
|
||||
|
@ -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.
|
||||
*
|
||||
* 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.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.Test;
|
||||
|
||||
import org.graalvm.compiler.core.test.backend.AllocatorTest;
|
||||
|
||||
import jdk.vm.ci.sparc.SPARC;
|
||||
|
||||
public class SPARCAllocatorTest extends AllocatorTest {
|
||||
|
||||
private final GraalHotSpotVMConfig config = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig();
|
||||
|
||||
@Before
|
||||
public void checkSPARC() {
|
||||
assumeTrue("skipping SPARC specific test", getTarget().arch instanceof SPARC);
|
||||
@ -44,7 +47,7 @@ public class SPARCAllocatorTest extends AllocatorTest {
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
testAllocation("test1snippet", 2, 0, 0);
|
||||
testAllocation("test1snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0);
|
||||
}
|
||||
|
||||
public static long test1snippet(long x) {
|
||||
@ -53,7 +56,7 @@ public class SPARCAllocatorTest extends AllocatorTest {
|
||||
|
||||
@Test
|
||||
public void test2() {
|
||||
testAllocation("test2snippet", 2, 0, 0);
|
||||
testAllocation("test2snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0);
|
||||
}
|
||||
|
||||
public static long test2snippet(long x) {
|
||||
@ -62,7 +65,7 @@ public class SPARCAllocatorTest extends AllocatorTest {
|
||||
|
||||
@Test
|
||||
public void test3() {
|
||||
testAllocation("test3snippet", 4, 0, 0);
|
||||
testAllocation("test3snippet", config.threadLocalHandshakes ? 3 : 4, 0, 0);
|
||||
}
|
||||
|
||||
public static long test3snippet(long x) {
|
@ -46,6 +46,9 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
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.Label;
|
||||
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.spi.NodeLIRBuilderTool;
|
||||
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.Register;
|
||||
|
@ -101,7 +101,7 @@ public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory {
|
||||
HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes);
|
||||
BytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection);
|
||||
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);
|
||||
HotSpotSuitesProvider suites = createSuites(config, runtime, compilerConfiguration, plugins, replacements);
|
||||
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,
|
||||
HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, HotSpotStampProvider stampProvider,
|
||||
HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotStampProvider stampProvider,
|
||||
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());
|
||||
return plugins;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -32,6 +32,8 @@ import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
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.hotspot.GraalHotSpotVMConfig;
|
||||
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.serviceprovider.JDK9Method;
|
||||
import org.graalvm.compiler.test.GraalTest;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.graalvm.util.MapCursor;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
||||
@ -416,6 +416,12 @@ public class CheckGraalIntrinsics extends GraalTest {
|
||||
"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")) {
|
||||
// Can we implement these on non-AMD64 platforms? C2 seems to.
|
||||
add(TO_BE_INVESTIGATED,
|
||||
@ -539,6 +545,10 @@ public class CheckGraalIntrinsics extends GraalTest {
|
||||
return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9;
|
||||
}
|
||||
|
||||
private static boolean isJDK10OrHigher() {
|
||||
return JDK9Method.JAVA_SPECIFICATION_VERSION >= 10;
|
||||
}
|
||||
|
||||
private static String getHostArchitectureName() {
|
||||
String arch = System.getProperty("os.arch");
|
||||
if (arch.equals("x86_64")) {
|
||||
|
@ -68,6 +68,8 @@ import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
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.bytecode.Bytecodes;
|
||||
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.OptionsParser;
|
||||
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.HotSpotCompilationRequest;
|
||||
|
@ -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.CompilationFailureAction;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
|
||||
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
||||
import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
|
||||
import org.graalvm.compiler.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
|
||||
|
@ -32,6 +32,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.compiler.api.directives.GraalDirectives;
|
||||
import org.graalvm.compiler.core.phases.HighTier;
|
||||
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.options.OptionKey;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||
import org.junit.Assume;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
/**
|
||||
* Test on-stack-replacement with locks.
|
||||
|
@ -31,8 +31,8 @@ import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.management.Attribute;
|
||||
import javax.management.MBeanAttributeInfo;
|
||||
import javax.management.MBeanInfo;
|
||||
@ -41,11 +41,11 @@ import javax.management.MBeanServer;
|
||||
import javax.management.ObjectInstance;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.compiler.debug.DebugOptions;
|
||||
import org.graalvm.compiler.hotspot.HotSpotGraalMBean;
|
||||
import org.graalvm.compiler.options.OptionValues;
|
||||
import org.graalvm.compiler.test.GraalTest;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
|
||||
|
@ -23,8 +23,10 @@
|
||||
package org.graalvm.compiler.hotspot.test;
|
||||
|
||||
import static org.graalvm.compiler.core.common.CompilationIdentifier.INVALID_COMPILATION_ID;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.compiler.api.test.Graal;
|
||||
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
||||
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.InvocationPlugins;
|
||||
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.options.OptionValues;
|
||||
import org.graalvm.compiler.runtime.RuntimeProvider;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.junit.Test;
|
||||
|
||||
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
||||
|
@ -24,6 +24,7 @@ package org.graalvm.compiler.hotspot.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.graalvm.collections.EconomicMap;
|
||||
import org.graalvm.compiler.debug.DebugCloseable;
|
||||
import org.graalvm.compiler.debug.DebugContext;
|
||||
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.tiers.HighTierContext;
|
||||
import org.graalvm.compiler.phases.tiers.MidTierContext;
|
||||
import org.graalvm.util.EconomicMap;
|
||||
import org.graalvm.word.LocationIdentity;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user