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 += \
|
jdk.internal.vm.compiler_EXCLUDES += \
|
||||||
|
org.graalvm.collections.test \
|
||||||
org.graalvm.compiler.core.match.processor \
|
org.graalvm.compiler.core.match.processor \
|
||||||
org.graalvm.compiler.nodeinfo.processor \
|
org.graalvm.compiler.nodeinfo.processor \
|
||||||
org.graalvm.compiler.options.processor \
|
org.graalvm.compiler.options.processor \
|
||||||
@ -511,6 +512,7 @@ jdk.internal.vm.compiler_EXCLUDES += \
|
|||||||
org.graalvm.compiler.graph.test \
|
org.graalvm.compiler.graph.test \
|
||||||
org.graalvm.compiler.hotspot.amd64.test \
|
org.graalvm.compiler.hotspot.amd64.test \
|
||||||
org.graalvm.compiler.hotspot.lir.test \
|
org.graalvm.compiler.hotspot.lir.test \
|
||||||
|
org.graalvm.compiler.hotspot.sparc.test \
|
||||||
org.graalvm.compiler.hotspot.test \
|
org.graalvm.compiler.hotspot.test \
|
||||||
org.graalvm.compiler.jtt \
|
org.graalvm.compiler.jtt \
|
||||||
org.graalvm.compiler.lir.jtt \
|
org.graalvm.compiler.lir.jtt \
|
||||||
|
@ -48,6 +48,7 @@ ifeq ($(INCLUDE_GRAAL), true)
|
|||||||
SETUP := GENERATE_OLDBYTECODE, \
|
SETUP := GENERATE_OLDBYTECODE, \
|
||||||
SRC := \
|
SRC := \
|
||||||
$(SRC_DIR)/org.graalvm.word/src \
|
$(SRC_DIR)/org.graalvm.word/src \
|
||||||
|
$(SRC_DIR)/org.graalvm.collections/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.core/src \
|
$(SRC_DIR)/org.graalvm.compiler.core/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.core.common/src \
|
$(SRC_DIR)/org.graalvm.compiler.core.common/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.core.match.processor/src \
|
$(SRC_DIR)/org.graalvm.compiler.core.match.processor/src \
|
||||||
@ -101,6 +102,7 @@ ifeq ($(INCLUDE_GRAAL), true)
|
|||||||
$(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_OPTIONS_PROCESSOR, \
|
$(eval $(call SetupJavaCompilation, BUILD_VM_COMPILER_OPTIONS_PROCESSOR, \
|
||||||
SETUP := GENERATE_OLDBYTECODE, \
|
SETUP := GENERATE_OLDBYTECODE, \
|
||||||
SRC := \
|
SRC := \
|
||||||
|
$(SRC_DIR)/org.graalvm.collections/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.options/src \
|
$(SRC_DIR)/org.graalvm.compiler.options/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.options.processor/src \
|
$(SRC_DIR)/org.graalvm.compiler.options.processor/src \
|
||||||
$(SRC_DIR)/org.graalvm.util/src \
|
$(SRC_DIR)/org.graalvm.util/src \
|
||||||
@ -117,6 +119,7 @@ ifeq ($(INCLUDE_GRAAL), true)
|
|||||||
SETUP := GENERATE_OLDBYTECODE, \
|
SETUP := GENERATE_OLDBYTECODE, \
|
||||||
SRC := \
|
SRC := \
|
||||||
$(SRC_DIR)/org.graalvm.word/src \
|
$(SRC_DIR)/org.graalvm.word/src \
|
||||||
|
$(SRC_DIR)/org.graalvm.collections/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.replacements.verifier/src \
|
$(SRC_DIR)/org.graalvm.compiler.replacements.verifier/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.api.replacements/src \
|
$(SRC_DIR)/org.graalvm.compiler.api.replacements/src \
|
||||||
$(SRC_DIR)/org.graalvm.compiler.code/src \
|
$(SRC_DIR)/org.graalvm.compiler.code/src \
|
||||||
|
@ -143,7 +143,7 @@ final class DataPatchProcessor {
|
|||||||
int alignment = data.getAlignment();
|
int alignment = data.getAlignment();
|
||||||
byte[] value = new byte[size];
|
byte[] value = new byte[size];
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(value).order(ByteOrder.nativeOrder());
|
ByteBuffer buffer = ByteBuffer.wrap(value).order(ByteOrder.nativeOrder());
|
||||||
DataSection.emit(buffer, data, p -> {
|
DataSection.emit(buffer, data, (p, c) -> {
|
||||||
});
|
});
|
||||||
String targetSymbol = "data.M" + methodInfo.getCodeId() + "." + dataOffset;
|
String targetSymbol = "data.M" + methodInfo.getCodeId() + "." + dataOffset;
|
||||||
Symbol relocationSymbol = binaryContainer.getSymbol(targetSymbol);
|
Symbol relocationSymbol = binaryContainer.getSymbol(targetSymbol);
|
||||||
|
@ -82,6 +82,24 @@ suite = {
|
|||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "1.8",
|
||||||
"workingSets" : "API,SDK",
|
"workingSets" : "API,SDK",
|
||||||
},
|
},
|
||||||
|
"org.graalvm.collections" : {
|
||||||
|
"subDir" : "share/classes",
|
||||||
|
"sourceDirs" : ["src"],
|
||||||
|
"checkstyle" : "org.graalvm.word",
|
||||||
|
"javaCompliance" : "1.8",
|
||||||
|
"workingSets" : "API,SDK",
|
||||||
|
},
|
||||||
|
"org.graalvm.collections.test" : {
|
||||||
|
"subDir" : "share/classes",
|
||||||
|
"sourceDirs" : ["src"],
|
||||||
|
"dependencies" : [
|
||||||
|
"mx:JUNIT",
|
||||||
|
"org.graalvm.collections",
|
||||||
|
],
|
||||||
|
"checkstyle" : "org.graalvm.word",
|
||||||
|
"javaCompliance" : "1.8",
|
||||||
|
"workingSets" : "API,SDK,Test",
|
||||||
|
},
|
||||||
|
|
||||||
# ------------- Graal -------------
|
# ------------- Graal -------------
|
||||||
|
|
||||||
@ -190,6 +208,9 @@ suite = {
|
|||||||
"org.graalvm.util" : {
|
"org.graalvm.util" : {
|
||||||
"subDir" : "share/classes",
|
"subDir" : "share/classes",
|
||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
|
"dependencies" : [
|
||||||
|
"org.graalvm.collections",
|
||||||
|
],
|
||||||
"checkstyle" : "org.graalvm.compiler.graph",
|
"checkstyle" : "org.graalvm.compiler.graph",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "1.8",
|
||||||
"workingSets" : "API,Graal",
|
"workingSets" : "API,Graal",
|
||||||
@ -201,6 +222,7 @@ suite = {
|
|||||||
"dependencies" : [
|
"dependencies" : [
|
||||||
"mx:JUNIT",
|
"mx:JUNIT",
|
||||||
"org.graalvm.util",
|
"org.graalvm.util",
|
||||||
|
"org.graalvm.compiler.core.test",
|
||||||
],
|
],
|
||||||
"checkstyle" : "org.graalvm.compiler.graph",
|
"checkstyle" : "org.graalvm.compiler.graph",
|
||||||
"javaCompliance" : "1.8",
|
"javaCompliance" : "1.8",
|
||||||
@ -970,10 +992,11 @@ suite = {
|
|||||||
"workingSets" : "Graal,SPARC",
|
"workingSets" : "Graal,SPARC",
|
||||||
},
|
},
|
||||||
|
|
||||||
"org.graalvm.compiler.core.sparc.test" : {
|
"org.graalvm.compiler.hotspot.sparc.test" : {
|
||||||
"subDir" : "share/classes",
|
"subDir" : "share/classes",
|
||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"dependencies" : [
|
"dependencies" : [
|
||||||
|
"org.graalvm.compiler.hotspot",
|
||||||
"org.graalvm.compiler.lir.jtt",
|
"org.graalvm.compiler.lir.jtt",
|
||||||
"JVMCI_HOTSPOT"
|
"JVMCI_HOTSPOT"
|
||||||
],
|
],
|
||||||
@ -1007,6 +1030,7 @@ suite = {
|
|||||||
"subDir" : "share/classes",
|
"subDir" : "share/classes",
|
||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"dependencies" : [
|
"dependencies" : [
|
||||||
|
"org.graalvm.collections",
|
||||||
"org.graalvm.compiler.debug",
|
"org.graalvm.compiler.debug",
|
||||||
"org.graalvm.word",
|
"org.graalvm.word",
|
||||||
],
|
],
|
||||||
@ -1037,7 +1061,6 @@ suite = {
|
|||||||
"sourceDirs" : ["src"],
|
"sourceDirs" : ["src"],
|
||||||
"dependencies" : [
|
"dependencies" : [
|
||||||
"org.graalvm.compiler.debug",
|
"org.graalvm.compiler.debug",
|
||||||
"org.graalvm.util",
|
|
||||||
"mx:JUNIT",
|
"mx:JUNIT",
|
||||||
],
|
],
|
||||||
"checkstyle" : "org.graalvm.compiler.graph",
|
"checkstyle" : "org.graalvm.compiler.graph",
|
||||||
@ -1225,11 +1248,11 @@ suite = {
|
|||||||
"org.graalvm.compiler.asm.amd64.test",
|
"org.graalvm.compiler.asm.amd64.test",
|
||||||
"org.graalvm.compiler.core.aarch64.test",
|
"org.graalvm.compiler.core.aarch64.test",
|
||||||
"org.graalvm.compiler.core.amd64.test",
|
"org.graalvm.compiler.core.amd64.test",
|
||||||
"org.graalvm.compiler.core.sparc.test",
|
|
||||||
"org.graalvm.compiler.debug.test",
|
"org.graalvm.compiler.debug.test",
|
||||||
"org.graalvm.compiler.hotspot.aarch64.test",
|
"org.graalvm.compiler.hotspot.aarch64.test",
|
||||||
"org.graalvm.compiler.hotspot.amd64.test",
|
"org.graalvm.compiler.hotspot.amd64.test",
|
||||||
"org.graalvm.compiler.hotspot.lir.test",
|
"org.graalvm.compiler.hotspot.lir.test",
|
||||||
|
"org.graalvm.compiler.hotspot.sparc.test",
|
||||||
"org.graalvm.compiler.options.test",
|
"org.graalvm.compiler.options.test",
|
||||||
"org.graalvm.compiler.jtt",
|
"org.graalvm.compiler.jtt",
|
||||||
"org.graalvm.compiler.lir.jtt",
|
"org.graalvm.compiler.lir.jtt",
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,34 +22,31 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.options;
|
package org.graalvm.collections.test;
|
||||||
|
|
||||||
/**
|
import org.graalvm.collections.Pair;
|
||||||
* Categorizes options according to user relevance.
|
import org.junit.Assert;
|
||||||
*
|
import org.junit.Test;
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public enum OptionCategory {
|
|
||||||
|
|
||||||
/**
|
public class PairTest {
|
||||||
* An option common for users to apply.
|
|
||||||
*
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
USER,
|
|
||||||
|
|
||||||
/**
|
@Test
|
||||||
* An option only relevant in corner cases and for fine-tuning.
|
public void testCreate() {
|
||||||
*
|
Assert.assertEquals(Pair.create(null, null), Pair.empty());
|
||||||
* @since 1.0
|
Assert.assertNotEquals(Pair.create(null, null), null);
|
||||||
*/
|
Assert.assertEquals(Pair.createLeft(null), Pair.empty());
|
||||||
EXPERT,
|
Assert.assertEquals(Pair.createRight(null), Pair.empty());
|
||||||
|
Assert.assertEquals(Pair.create(1, null), Pair.createLeft(1));
|
||||||
|
Assert.assertEquals(Pair.create(null, 1), Pair.createRight(1));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
@Test
|
||||||
* An option only relevant when debugging language or instrument implementations.
|
public void testUtilities() {
|
||||||
*
|
Pair<Integer, Integer> pair = Pair.create(1, null);
|
||||||
* @since 1.0
|
Assert.assertEquals(pair.getLeft(), Integer.valueOf(1));
|
||||||
*/
|
Assert.assertEquals(pair.getRight(), null);
|
||||||
DEBUG
|
Assert.assertEquals(pair.toString(), "(1, null)");
|
||||||
|
Assert.assertEquals(pair.hashCode(), Pair.createLeft(1).hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -4,7 +4,9 @@
|
|||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
@ -20,21 +22,34 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.util;
|
package org.graalvm.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import org.graalvm.util.impl.EconomicMapImpl;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory efficient map data structure.
|
* Memory efficient map data structure.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
|
public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associates {@code value} with {@code key} in this map. If the map previously contained a
|
||||||
|
* mapping for {@code key}, the old value is replaced by {@code value}.
|
||||||
|
*
|
||||||
|
* @return the previous value associated with {@code key}, or {@code null} if there was no
|
||||||
|
* mapping for {@code key}.
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
V put(K key, V value);
|
V put(K key, V value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies all of the mappings from {@code other} to this map.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
default void putAll(EconomicMap<K, V> other) {
|
default void putAll(EconomicMap<K, V> other) {
|
||||||
MapCursor<K, V> e = other.getEntries();
|
MapCursor<K, V> e = other.getEntries();
|
||||||
while (e.advance()) {
|
while (e.advance()) {
|
||||||
@ -42,15 +57,11 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear();
|
/**
|
||||||
|
* Copies all of the mappings from {@code other} to this map.
|
||||||
V removeKey(K key);
|
*
|
||||||
|
* @since 1.0
|
||||||
@Override
|
*/
|
||||||
MapCursor<K, V> getEntries();
|
|
||||||
|
|
||||||
void replaceAll(BiFunction<? super K, ? super V, ? extends V> function);
|
|
||||||
|
|
||||||
default void putAll(UnmodifiableEconomicMap<? extends K, ? extends V> other) {
|
default void putAll(UnmodifiableEconomicMap<? extends K, ? extends V> other) {
|
||||||
UnmodifiableMapCursor<? extends K, ? extends V> entry = other.getEntries();
|
UnmodifiableMapCursor<? extends K, ? extends V> entry = other.getEntries();
|
||||||
while (entry.advance()) {
|
while (entry.advance()) {
|
||||||
@ -58,9 +69,45 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all of the mappings from this map. The map will be empty after this call returns.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the mapping for {@code key} from this map if it is present. The map will not contain
|
||||||
|
* a mapping for {@code key} once the call returns.
|
||||||
|
*
|
||||||
|
* @return the previous value associated with {@code key}, or {@code null} if there was no
|
||||||
|
* mapping for {@code key}.
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
V removeKey(K key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link MapCursor} view of the mappings contained in this map.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
MapCursor<K, V> getEntries();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces each entry's value with the result of invoking {@code function} on that entry until
|
||||||
|
* all entries have been processed or the function throws an exception. Exceptions thrown by the
|
||||||
|
* function are relayed to the caller.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
void replaceAll(BiFunction<? super K, ? super V, ? extends V> function);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new map that guarantees insertion order on the key set with the default
|
* Creates a new map that guarantees insertion order on the key set with the default
|
||||||
* {@link Equivalence#DEFAULT} comparison strategy for keys.
|
* {@link Equivalence#DEFAULT} comparison strategy for keys.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <K, V> EconomicMap<K, V> create() {
|
static <K, V> EconomicMap<K, V> create() {
|
||||||
return EconomicMap.create(Equivalence.DEFAULT);
|
return EconomicMap.create(Equivalence.DEFAULT);
|
||||||
@ -70,6 +117,8 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
|
|||||||
* Creates a new map that guarantees insertion order on the key set with the default
|
* Creates a new map that guarantees insertion order on the key set with the default
|
||||||
* {@link Equivalence#DEFAULT} comparison strategy for keys and initializes with a specified
|
* {@link Equivalence#DEFAULT} comparison strategy for keys and initializes with a specified
|
||||||
* capacity.
|
* capacity.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <K, V> EconomicMap<K, V> create(int initialCapacity) {
|
static <K, V> EconomicMap<K, V> create(int initialCapacity) {
|
||||||
return EconomicMap.create(Equivalence.DEFAULT, initialCapacity);
|
return EconomicMap.create(Equivalence.DEFAULT, initialCapacity);
|
||||||
@ -78,15 +127,19 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
|
|||||||
/**
|
/**
|
||||||
* Creates a new map that guarantees insertion order on the key set with the given comparison
|
* Creates a new map that guarantees insertion order on the key set with the given comparison
|
||||||
* strategy for keys.
|
* strategy for keys.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <K, V> EconomicMap<K, V> create(Equivalence strategy) {
|
static <K, V> EconomicMap<K, V> create(Equivalence strategy) {
|
||||||
return EconomicMapImpl.create(strategy);
|
return EconomicMapImpl.create(strategy, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new map that guarantees insertion order on the key set with the default
|
* Creates a new map that guarantees insertion order on the key set with the default
|
||||||
* {@link Equivalence#DEFAULT} comparison strategy for keys and copies all elements from the
|
* {@link Equivalence#DEFAULT} comparison strategy for keys and copies all elements from the
|
||||||
* specified existing map.
|
* specified existing map.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <K, V> EconomicMap<K, V> create(UnmodifiableEconomicMap<K, V> m) {
|
static <K, V> EconomicMap<K, V> create(UnmodifiableEconomicMap<K, V> m) {
|
||||||
return EconomicMap.create(Equivalence.DEFAULT, m);
|
return EconomicMap.create(Equivalence.DEFAULT, m);
|
||||||
@ -95,21 +148,27 @@ public interface EconomicMap<K, V> extends UnmodifiableEconomicMap<K, V> {
|
|||||||
/**
|
/**
|
||||||
* Creates a new map that guarantees insertion order on the key set and copies all elements from
|
* Creates a new map that guarantees insertion order on the key set and copies all elements from
|
||||||
* the specified existing map.
|
* the specified existing map.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <K, V> EconomicMap<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> m) {
|
static <K, V> EconomicMap<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> m) {
|
||||||
return EconomicMapImpl.create(strategy, m);
|
return EconomicMapImpl.create(strategy, m, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new map that guarantees insertion order on the key set and initializes with a
|
* Creates a new map that guarantees insertion order on the key set and initializes with a
|
||||||
* specified capacity.
|
* specified capacity.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <K, V> EconomicMap<K, V> create(Equivalence strategy, int initialCapacity) {
|
static <K, V> EconomicMap<K, V> create(Equivalence strategy, int initialCapacity) {
|
||||||
return EconomicMapImpl.create(strategy, initialCapacity);
|
return EconomicMapImpl.create(strategy, initialCapacity, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps an existing {@link java.util.Map} as an {@link org.graalvm.util.EconomicMap}.
|
* Wraps an existing {@link Map} as an {@link EconomicMap}.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <K, V> EconomicMap<K, V> wrapMap(Map<K, V> map) {
|
static <K, V> EconomicMap<K, V> wrapMap(Map<K, V> map) {
|
||||||
return new EconomicMap<K, V>() {
|
return new EconomicMap<K, V>() {
|
@ -4,7 +4,9 @@
|
|||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
@ -20,19 +22,12 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.util.impl;
|
package org.graalvm.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
import org.graalvm.util.UnmodifiableEconomicMap;
|
|
||||||
import org.graalvm.util.UnmodifiableEconomicSet;
|
|
||||||
import org.graalvm.util.MapCursor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of a map with a memory-efficient structure that always preserves insertion order
|
* Implementation of a map with a memory-efficient structure that always preserves insertion order
|
||||||
* when iterating over keys. Particularly efficient when number of entries is 0 or smaller equal
|
* when iterating over keys. Particularly efficient when number of entries is 0 or smaller equal
|
||||||
@ -58,7 +53,7 @@ import org.graalvm.util.MapCursor;
|
|||||||
* map falls below a specific threshold, the map will be compressed via the
|
* map falls below a specific threshold, the map will be compressed via the
|
||||||
* {@link #maybeCompress(int)} method.
|
* {@link #maybeCompress(int)} method.
|
||||||
*/
|
*/
|
||||||
public final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicSet<K> {
|
final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicSet<K> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initial number of key/value pair entries that is allocated in the first entries array.
|
* Initial number of key/value pair entries that is allocated in the first entries array.
|
||||||
@ -135,45 +130,46 @@ public final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicS
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy) {
|
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, boolean isSet) {
|
||||||
return intercept(new EconomicMapImpl<>(strategy));
|
return intercept(new EconomicMapImpl<>(strategy, isSet));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, int initialCapacity) {
|
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, int initialCapacity, boolean isSet) {
|
||||||
return intercept(new EconomicMapImpl<>(strategy, initialCapacity));
|
return intercept(new EconomicMapImpl<>(strategy, initialCapacity, isSet));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> other) {
|
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicMap<K, V> other, boolean isSet) {
|
||||||
return intercept(new EconomicMapImpl<>(strategy, other));
|
return intercept(new EconomicMapImpl<>(strategy, other, isSet));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicSet<K> other) {
|
public static <K, V> EconomicMapImpl<K, V> create(Equivalence strategy, UnmodifiableEconomicSet<K> other, boolean isSet) {
|
||||||
return intercept(new EconomicMapImpl<>(strategy, other));
|
return intercept(new EconomicMapImpl<>(strategy, other, isSet));
|
||||||
}
|
}
|
||||||
|
|
||||||
private EconomicMapImpl(Equivalence strategy) {
|
private EconomicMapImpl(Equivalence strategy, boolean isSet) {
|
||||||
if (strategy == Equivalence.IDENTITY) {
|
if (strategy == Equivalence.IDENTITY) {
|
||||||
this.strategy = null;
|
this.strategy = null;
|
||||||
} else {
|
} else {
|
||||||
this.strategy = strategy;
|
this.strategy = strategy;
|
||||||
}
|
}
|
||||||
|
this.isSet = isSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
private EconomicMapImpl(Equivalence strategy, int initialCapacity) {
|
private EconomicMapImpl(Equivalence strategy, int initialCapacity, boolean isSet) {
|
||||||
this(strategy);
|
this(strategy, isSet);
|
||||||
init(initialCapacity);
|
init(initialCapacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicMap<K, V> other) {
|
private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicMap<K, V> other, boolean isSet) {
|
||||||
this(strategy);
|
this(strategy, isSet);
|
||||||
if (!initFrom(other)) {
|
if (!initFrom(other)) {
|
||||||
init(other.size());
|
init(other.size());
|
||||||
putAll(other);
|
putAll(other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicSet<K> other) {
|
private EconomicMapImpl(Equivalence strategy, UnmodifiableEconomicSet<K> other, boolean isSet) {
|
||||||
this(strategy);
|
this(strategy, isSet);
|
||||||
if (!initFrom(other)) {
|
if (!initFrom(other)) {
|
||||||
init(other.size());
|
init(other.size());
|
||||||
addAll(other);
|
addAll(other);
|
||||||
@ -807,13 +803,22 @@ public final class EconomicMapImpl<K, V> implements EconomicMap<K, V>, EconomicS
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final boolean isSet;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("map(size=").append(size()).append(", {");
|
builder.append(isSet ? "set(size=" : "map(size=").append(size()).append(", {");
|
||||||
|
String sep = "";
|
||||||
MapCursor<K, V> cursor = getEntries();
|
MapCursor<K, V> cursor = getEntries();
|
||||||
while (cursor.advance()) {
|
while (cursor.advance()) {
|
||||||
builder.append("(").append(cursor.getKey()).append(",").append(cursor.getValue()).append("),");
|
builder.append(sep);
|
||||||
|
if (isSet) {
|
||||||
|
builder.append(cursor.getKey());
|
||||||
|
} else {
|
||||||
|
builder.append("(").append(cursor.getKey()).append(",").append(cursor.getValue()).append(")");
|
||||||
|
}
|
||||||
|
sep = ",";
|
||||||
}
|
}
|
||||||
builder.append("})");
|
builder.append("})");
|
||||||
return builder.toString();
|
return builder.toString();
|
@ -4,7 +4,9 @@
|
|||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
@ -20,56 +22,109 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.util;
|
package org.graalvm.collections;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.graalvm.util.impl.EconomicMapImpl;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Memory efficient set data structure.
|
* Memory efficient set data structure.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
|
public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds {@code element} to this set if it is not already present.
|
||||||
|
*
|
||||||
|
* @return {@code true} if this set did not already contain {@code element}.
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
boolean add(E element);
|
boolean add(E element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes {@code element} from this set if it is present. This set will not contain
|
||||||
|
* {@code element} once the call returns.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
void remove(E element);
|
void remove(E element);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all of the elements from this set. The set will be empty after this call returns.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
default void addAll(EconomicSet<E> values) {
|
/**
|
||||||
addAll(values.iterator());
|
* Adds all of the elements in {@code other} to this set if they're not already present.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
default void addAll(EconomicSet<E> other) {
|
||||||
|
addAll(other.iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds all of the elements in {@code values} to this set if they're not already present.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
default void addAll(Iterable<E> values) {
|
default void addAll(Iterable<E> values) {
|
||||||
addAll(values.iterator());
|
addAll(values.iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
default void addAll(Iterator<E> values) {
|
/**
|
||||||
while (values.hasNext()) {
|
* Adds all of the elements enumerated by {@code iterator} to this set if they're not already
|
||||||
add(values.next());
|
* present.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
default void addAll(Iterator<E> iterator) {
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
add(iterator.next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default void removeAll(EconomicSet<E> values) {
|
/**
|
||||||
removeAll(values.iterator());
|
* Removes from this set all of its elements that are contained in {@code other}.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
default void removeAll(EconomicSet<E> other) {
|
||||||
|
removeAll(other.iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes from this set all of its elements that are contained in {@code values}.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
default void removeAll(Iterable<E> values) {
|
default void removeAll(Iterable<E> values) {
|
||||||
removeAll(values.iterator());
|
removeAll(values.iterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
default void removeAll(Iterator<E> values) {
|
/**
|
||||||
while (values.hasNext()) {
|
* Removes from this set all of its elements that are enumerated by {@code iterator}.
|
||||||
remove(values.next());
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
default void removeAll(Iterator<E> iterator) {
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
remove(iterator.next());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default void retainAll(EconomicSet<E> values) {
|
/**
|
||||||
|
* Removes from this set all of its elements that are not contained in {@code other}.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
default void retainAll(EconomicSet<E> other) {
|
||||||
Iterator<E> iterator = iterator();
|
Iterator<E> iterator = iterator();
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
E key = iterator.next();
|
E key = iterator.next();
|
||||||
if (!values.contains(key)) {
|
if (!other.contains(key)) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,6 +133,8 @@ public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
|
|||||||
/**
|
/**
|
||||||
* Creates a new set guaranteeing insertion order when iterating over its elements with the
|
* Creates a new set guaranteeing insertion order when iterating over its elements with the
|
||||||
* default {@link Equivalence#DEFAULT} comparison strategy.
|
* default {@link Equivalence#DEFAULT} comparison strategy.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <E> EconomicSet<E> create() {
|
static <E> EconomicSet<E> create() {
|
||||||
return EconomicSet.create(Equivalence.DEFAULT);
|
return EconomicSet.create(Equivalence.DEFAULT);
|
||||||
@ -85,15 +142,19 @@ public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new set guaranteeing insertion order when iterating over its elements.
|
* Creates a new set guaranteeing insertion order when iterating over its elements.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <E> EconomicSet<E> create(Equivalence strategy) {
|
static <E> EconomicSet<E> create(Equivalence strategy) {
|
||||||
return EconomicMapImpl.create(strategy);
|
return EconomicMapImpl.create(strategy, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new set guaranteeing insertion order when iterating over its elements with the
|
* Creates a new set guaranteeing insertion order when iterating over its elements with the
|
||||||
* default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
|
* default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
|
||||||
* specified collection.
|
* specified collection.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <E> EconomicSet<E> create(int initialCapacity) {
|
static <E> EconomicSet<E> create(int initialCapacity) {
|
||||||
return EconomicSet.create(Equivalence.DEFAULT, initialCapacity);
|
return EconomicSet.create(Equivalence.DEFAULT, initialCapacity);
|
||||||
@ -103,6 +164,8 @@ public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
|
|||||||
* Creates a new set guaranteeing insertion order when iterating over its elements with the
|
* Creates a new set guaranteeing insertion order when iterating over its elements with the
|
||||||
* default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
|
* default {@link Equivalence#DEFAULT} comparison strategy and inserts all elements of the
|
||||||
* specified collection.
|
* specified collection.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <E> EconomicSet<E> create(UnmodifiableEconomicSet<E> c) {
|
static <E> EconomicSet<E> create(UnmodifiableEconomicSet<E> c) {
|
||||||
return EconomicSet.create(Equivalence.DEFAULT, c);
|
return EconomicSet.create(Equivalence.DEFAULT, c);
|
||||||
@ -111,16 +174,20 @@ public interface EconomicSet<E> extends UnmodifiableEconomicSet<E> {
|
|||||||
/**
|
/**
|
||||||
* Creates a new set guaranteeing insertion order when iterating over its elements and
|
* Creates a new set guaranteeing insertion order when iterating over its elements and
|
||||||
* initializes with the given capacity.
|
* initializes with the given capacity.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <E> EconomicSet<E> create(Equivalence strategy, int initialCapacity) {
|
static <E> EconomicSet<E> create(Equivalence strategy, int initialCapacity) {
|
||||||
return EconomicMapImpl.create(strategy, initialCapacity);
|
return EconomicMapImpl.create(strategy, initialCapacity, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new set guaranteeing insertion order when iterating over its elements and inserts
|
* Creates a new set guaranteeing insertion order when iterating over its elements and inserts
|
||||||
* all elements of the specified collection.
|
* all elements of the specified collection.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
static <E> EconomicSet<E> create(Equivalence strategy, UnmodifiableEconomicSet<E> c) {
|
static <E> EconomicSet<E> create(Equivalence strategy, UnmodifiableEconomicSet<E> c) {
|
||||||
return EconomicMapImpl.create(strategy, c);
|
return EconomicMapImpl.create(strategy, c, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,9 @@
|
|||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
@ -20,11 +22,13 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.util;
|
package org.graalvm.collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strategy for comparing two objects. Default predefined strategies are {@link #DEFAULT},
|
* Strategy for comparing two objects. Default predefined strategies are {@link #DEFAULT},
|
||||||
* {@link #IDENTITY}, and {@link #IDENTITY_WITH_SYSTEM_HASHCODE}.
|
* {@link #IDENTITY}, and {@link #IDENTITY_WITH_SYSTEM_HASHCODE}.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public abstract class Equivalence {
|
public abstract class Equivalence {
|
||||||
|
|
||||||
@ -32,6 +36,8 @@ public abstract class Equivalence {
|
|||||||
* Default equivalence calling {@link #equals(Object)} to check equality and {@link #hashCode()}
|
* Default equivalence calling {@link #equals(Object)} to check equality and {@link #hashCode()}
|
||||||
* for obtaining hash values. Do not change the logic of this class as it may be inlined in
|
* for obtaining hash values. Do not change the logic of this class as it may be inlined in
|
||||||
* other places.
|
* other places.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public static final Equivalence DEFAULT = new Equivalence() {
|
public static final Equivalence DEFAULT = new Equivalence() {
|
||||||
|
|
||||||
@ -49,6 +55,8 @@ public abstract class Equivalence {
|
|||||||
/**
|
/**
|
||||||
* Identity equivalence using {@code ==} to check equality and {@link #hashCode()} for obtaining
|
* Identity equivalence using {@code ==} to check equality and {@link #hashCode()} for obtaining
|
||||||
* hash values. Do not change the logic of this class as it may be inlined in other places.
|
* hash values. Do not change the logic of this class as it may be inlined in other places.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public static final Equivalence IDENTITY = new Equivalence() {
|
public static final Equivalence IDENTITY = new Equivalence() {
|
||||||
|
|
||||||
@ -67,6 +75,8 @@ public abstract class Equivalence {
|
|||||||
* Identity equivalence using {@code ==} to check equality and
|
* Identity equivalence using {@code ==} to check equality and
|
||||||
* {@link System#identityHashCode(Object)} for obtaining hash values. Do not change the logic of
|
* {@link System#identityHashCode(Object)} for obtaining hash values. Do not change the logic of
|
||||||
* this class as it may be inlined in other places.
|
* this class as it may be inlined in other places.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public static final Equivalence IDENTITY_WITH_SYSTEM_HASHCODE = new Equivalence() {
|
public static final Equivalence IDENTITY_WITH_SYSTEM_HASHCODE = new Equivalence() {
|
||||||
|
|
||||||
@ -83,11 +93,24 @@ public abstract class Equivalence {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclass for creating custom equivalence definitions.
|
* Subclass for creating custom equivalence definitions.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
protected Equivalence() {
|
protected Equivalence() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if the non-{@code null} arguments are equal to each other and
|
||||||
|
* {@code false} otherwise.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
public abstract boolean equals(Object a, Object b);
|
public abstract boolean equals(Object a, Object b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hash code of a non-{@code null} argument {@code o}.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
public abstract int hashCode(Object o);
|
public abstract int hashCode(Object o);
|
||||||
}
|
}
|
@ -4,7 +4,9 @@
|
|||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
@ -20,16 +22,20 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.util;
|
package org.graalvm.collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cursor to iterate over a mutable map.
|
* Cursor to iterate over a mutable map.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public interface MapCursor<K, V> extends UnmodifiableMapCursor<K, V> {
|
public interface MapCursor<K, V> extends UnmodifiableMapCursor<K, V> {
|
||||||
/**
|
/**
|
||||||
* Remove the current entry from the map. May only be called once. After calling
|
* Remove the current entry from the map. May only be called once. After calling
|
||||||
* {@link #remove()}, it is no longer valid to call {@link #getKey()} or {@link #getValue()} on
|
* {@link #remove()}, it is no longer valid to call {@link #getKey()} or {@link #getValue()} on
|
||||||
* the current entry.
|
* the current entry.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
void remove();
|
void remove();
|
||||||
}
|
}
|
@ -4,7 +4,9 @@
|
|||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
@ -20,24 +22,39 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.util;
|
package org.graalvm.collections;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class representing a pair of values.
|
* Utility class representing a pair of values.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public final class Pair<L, R> {
|
public final class Pair<L, R> {
|
||||||
|
|
||||||
private static final Pair<Object, Object> EMPTY = new Pair<>(null, null);
|
private static final Pair<Object, Object> EMPTY = new Pair<>(null, null);
|
||||||
|
|
||||||
private final L left;
|
private final L left;
|
||||||
private final R right;
|
private final R right;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an empty pair.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <L, R> Pair<L, R> empty() {
|
public static <L, R> Pair<L, R> empty() {
|
||||||
return (Pair<L, R>) EMPTY;
|
return (Pair<L, R>) EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a pair with its left value being {@code left}, or returns an empty pair if
|
||||||
|
* {@code left} is null.
|
||||||
|
*
|
||||||
|
* @return the constructed pair or an empty pair if {@code left} is null.
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
public static <L, R> Pair<L, R> createLeft(L left) {
|
public static <L, R> Pair<L, R> createLeft(L left) {
|
||||||
if (left == null) {
|
if (left == null) {
|
||||||
return empty();
|
return empty();
|
||||||
@ -46,6 +63,13 @@ public final class Pair<L, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a pair with its right value being {@code right}, or returns an empty pair if
|
||||||
|
* {@code right} is null.
|
||||||
|
*
|
||||||
|
* @return the constructed pair or an empty pair if {@code right} is null.
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
public static <L, R> Pair<L, R> createRight(R right) {
|
public static <L, R> Pair<L, R> createRight(R right) {
|
||||||
if (right == null) {
|
if (right == null) {
|
||||||
return empty();
|
return empty();
|
||||||
@ -54,6 +78,13 @@ public final class Pair<L, R> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a pair with its left value being {@code left}, and its right value being
|
||||||
|
* {@code right}, or returns an empty pair if both inputs are null.
|
||||||
|
*
|
||||||
|
* @return the constructed pair or an empty pair if both inputs are null.
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
public static <L, R> Pair<L, R> create(L left, R right) {
|
public static <L, R> Pair<L, R> create(L left, R right) {
|
||||||
if (right == null && left == null) {
|
if (right == null && left == null) {
|
||||||
return empty();
|
return empty();
|
||||||
@ -67,19 +98,39 @@ public final class Pair<L, R> {
|
|||||||
this.right = right;
|
this.right = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the left value of this pair.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
public L getLeft() {
|
public L getLeft() {
|
||||||
return left;
|
return left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the right value of this pair.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
public R getRight() {
|
public R getRight() {
|
||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(left) + 31 * Objects.hashCode(right);
|
return Objects.hashCode(left) + 31 * Objects.hashCode(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
@ -95,6 +146,11 @@ public final class Pair<L, R> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("(%s, %s)", left, right);
|
return String.format("(%s, %s)", left, right);
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -22,49 +22,56 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.options;
|
package org.graalvm.collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a set of option values based on an {@link OptionDescriptor}.
|
* Unmodifiable memory efficient set data structure.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public interface OptionValues {
|
public interface UnmodifiableEconomicSet<E> extends Iterable<E> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all available options.
|
* Returns {@code true} if this set contains a mapping for the {@code element}.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
OptionDescriptors getDescriptors();
|
boolean contains(E element);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of {@code optionKey} to {@code value}.
|
* Returns the number of elements in this set.
|
||||||
*
|
|
||||||
* @throws IllegalArgumentException if the given value is not {@link OptionType#validate(Object)
|
|
||||||
* validated} by the {@link OptionKey#getType() option type} of the key. Note that
|
|
||||||
* the operation succeeds if the option key is not described by any of the
|
|
||||||
* associated {@link #getDescriptors() descriptors}.
|
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
<T> void set(OptionKey<T> optionKey, T value);
|
int size();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value of a given option. If no value is set or the key is not described by any
|
* Returns {@code true} if this set contains no elements.
|
||||||
* {@link #getDescriptors() descriptors} the {@link OptionType#getDefaultValue() default value}
|
|
||||||
* of the given key is returned.
|
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
<T> T get(OptionKey<T> optionKey);
|
boolean isEmpty();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if a value for {@code optionKey} has been {@link #set} in this set of option
|
* Stores all of the elements in this set into {@code target}. An
|
||||||
* values.
|
* {@link UnsupportedOperationException} will be thrown if the length of {@code target} does not
|
||||||
|
* match the size of this set.
|
||||||
*
|
*
|
||||||
|
* @return an array containing all the elements in this set.
|
||||||
|
* @throws UnsupportedOperationException if the length of {@code target} does not equal the size
|
||||||
|
* of this set.
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
boolean hasBeenSet(OptionKey<?> optionKey);
|
default E[] toArray(E[] target) {
|
||||||
|
if (target.length != size()) {
|
||||||
|
throw new UnsupportedOperationException("Length of target array must equal the size of the set.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (E element : this) {
|
||||||
|
target[index++] = element;
|
||||||
|
}
|
||||||
|
|
||||||
|
return target;
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,7 +4,9 @@
|
|||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
* under the terms of the GNU General Public License version 2 only, as
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
* published by the Free Software Foundation.
|
* published by the Free Software Foundation. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
*
|
*
|
||||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
@ -20,26 +22,33 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.util;
|
package org.graalvm.collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cursor to iterate over a map without changing its contents.
|
* Cursor to iterate over a map without changing its contents.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
public interface UnmodifiableMapCursor<K, V> {
|
public interface UnmodifiableMapCursor<K, V> {
|
||||||
/**
|
/**
|
||||||
* Advances to the next entry.
|
* Advances to the next entry.
|
||||||
*
|
*
|
||||||
* @return {@code true} if a next entry exists, {@code false} if there is no next entry.
|
* @return {@code true} if a next entry exists, {@code false} if there is no next entry.
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
boolean advance();
|
boolean advance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The key of the current entry.
|
* The key of the current entry.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
K getKey();
|
K getKey();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value of the current entry.
|
* The value of the current entry.
|
||||||
|
*
|
||||||
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
V getValue();
|
V getValue();
|
||||||
}
|
}
|
@ -23,11 +23,11 @@
|
|||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* The Graal-SDK options package contains reusable collection classes for options.
|
* The Graal-SDK collections package contains memory efficient data structures.
|
||||||
*
|
*
|
||||||
* @see org.graalvm.options.OptionDescriptor
|
* @see org.graalvm.collections.EconomicMap
|
||||||
* @see org.graalvm.options.OptionValues
|
* @see org.graalvm.collections.EconomicSet
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
*/
|
*/
|
||||||
package org.graalvm.options;
|
package org.graalvm.collections;
|
@ -50,6 +50,21 @@ public class ProbabilityDirectiveTest extends GraalCompilerTest {
|
|||||||
test("branchProbabilitySnippet", 5);
|
test("branchProbabilitySnippet", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int branchProbabilitySnippet2(int arg) {
|
||||||
|
if (!GraalDirectives.injectBranchProbability(0.125, arg <= 0)) {
|
||||||
|
GraalDirectives.controlFlowAnchor(); // prevent removal of the if
|
||||||
|
return 2;
|
||||||
|
} else {
|
||||||
|
GraalDirectives.controlFlowAnchor(); // prevent removal of the if
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBranchProbability2() {
|
||||||
|
test("branchProbabilitySnippet2", 5);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean checkLowTierGraph(StructuredGraph graph) {
|
protected boolean checkLowTierGraph(StructuredGraph graph) {
|
||||||
NodeIterable<IfNode> ifNodes = graph.getNodes(IfNode.TYPE);
|
NodeIterable<IfNode> ifNodes = graph.getNodes(IfNode.TYPE);
|
||||||
|
@ -49,6 +49,13 @@ public final class GraalDirectives {
|
|||||||
public static void deoptimizeAndInvalidate() {
|
public static void deoptimizeAndInvalidate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Directive for the compiler to fall back to the bytecode interpreter at this point, invalidate
|
||||||
|
* the compiled code, record a speculation and reprofile the method.
|
||||||
|
*/
|
||||||
|
public static void deoptimizeAndInvalidateWithSpeculation() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a boolean value indicating whether the method is executed in Graal-compiled code.
|
* Returns a boolean value indicating whether the method is executed in Graal-compiled code.
|
||||||
*/
|
*/
|
||||||
|
@ -26,15 +26,52 @@ import java.lang.annotation.ElementType;
|
|||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.Signature;
|
import jdk.vm.ci.meta.Signature;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Denotes a method whose body is used by a compiler as the substitute (or intrinsification) of
|
* Denotes a method whose body is used by a compiler as the substitute (or intrinsification) of
|
||||||
* another method. The exact method used to do the substitution is compiler dependent but every
|
* another method. The exact mechanism used to do the substitution is compiler dependent but every
|
||||||
* compiler should require substitute methods to be annotated with {@link MethodSubstitution}. In
|
* compiler should require substitute methods to be annotated with {@link MethodSubstitution}. In
|
||||||
* addition, a compiler is recommended to implement {@link MethodSubstitutionRegistry} to advertise
|
* addition, a compiler is recommended to implement {@link MethodSubstitutionRegistry} to advertise
|
||||||
* the mechanism by which it supports registration of method substitutes.
|
* the mechanism by which it supports registration of method substitutes.
|
||||||
|
*
|
||||||
|
* A compiler may support partial intrinsification where only a part of a method is implemented by
|
||||||
|
* the compiler. The unsupported path is expressed by a call to either the original or substitute
|
||||||
|
* method from within the substitute method. Such as call is a <i>partial intrinsic exit</i>.
|
||||||
|
*
|
||||||
|
* For example, here's a HotSpot specific intrinsic for {@link Array#newInstance(Class, int)} that
|
||||||
|
* only handles the case where the VM representation of the array class to be instantiated already
|
||||||
|
* exists:
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* @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)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
|
@ -90,4 +90,12 @@ public interface SnippetReflectionProvider {
|
|||||||
* if this provider cannot provide a value of the requested type
|
* if this provider cannot provide a value of the requested type
|
||||||
*/
|
*/
|
||||||
<T> T getInjectedNodeIntrinsicParameter(Class<T> type);
|
<T> T getInjectedNodeIntrinsicParameter(Class<T> type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the original Java class corresponding to a {@link ResolvedJavaType}.
|
||||||
|
*
|
||||||
|
* @param type the type for which the original Java class is requested
|
||||||
|
* @return the original Java class corresponding to the {@code type} parameter
|
||||||
|
*/
|
||||||
|
Class<?> originalClass(ResolvedJavaType type);
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.graalvm.compiler.api.runtime;
|
package org.graalvm.compiler.api.runtime;
|
||||||
|
|
||||||
|
import jdk.vm.ci.common.JVMCIError;
|
||||||
|
|
||||||
public interface GraalRuntime {
|
public interface GraalRuntime {
|
||||||
|
|
||||||
String getName();
|
String getName();
|
||||||
|
|
||||||
<T> T getCapability(Class<T> clazz);
|
<T> T getCapability(Class<T> clazz);
|
||||||
|
|
||||||
|
default <T> T getRequiredCapability(Class<T> clazz) {
|
||||||
|
T ret = getCapability(clazz);
|
||||||
|
if (ret == null) {
|
||||||
|
throw new JVMCIError("The VM does not expose the required Graal capability %s.", clazz.getName());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,6 @@ public class AMD64Assembler extends Assembler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class VexOpcode {
|
private static class VexOpcode {
|
||||||
private static final int VEX_OPCODE_NONE = 0x0;
|
|
||||||
private static final int VEX_OPCODE_0F = 0x1;
|
private static final int VEX_OPCODE_0F = 0x1;
|
||||||
private static final int VEX_OPCODE_0F_38 = 0x2;
|
private static final int VEX_OPCODE_0F_38 = 0x2;
|
||||||
private static final int VEX_OPCODE_0F_3A = 0x3;
|
private static final int VEX_OPCODE_0F_3A = 0x3;
|
||||||
@ -861,9 +860,26 @@ public class AMD64Assembler extends Assembler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int opc = 0;
|
||||||
|
if (isSimd) {
|
||||||
|
switch (prefix2) {
|
||||||
|
case P_0F:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F;
|
||||||
|
break;
|
||||||
|
case P_0F38:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_38;
|
||||||
|
break;
|
||||||
|
case P_0F3A:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
isSimd = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isSimd) {
|
if (isSimd) {
|
||||||
int pre;
|
int pre;
|
||||||
int opc;
|
|
||||||
boolean rexVexW = (size == QWORD) ? true : false;
|
boolean rexVexW = (size == QWORD) ? true : false;
|
||||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||||
int curPrefix = size.sizePrefix | prefix1;
|
int curPrefix = size.sizePrefix | prefix1;
|
||||||
@ -881,20 +897,6 @@ public class AMD64Assembler extends Assembler {
|
|||||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (prefix2) {
|
|
||||||
case P_0F:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F;
|
|
||||||
break;
|
|
||||||
case P_0F38:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_38;
|
|
||||||
break;
|
|
||||||
case P_0F3A:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int encode;
|
int encode;
|
||||||
if (noNds) {
|
if (noNds) {
|
||||||
encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes);
|
encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes);
|
||||||
@ -938,9 +940,26 @@ public class AMD64Assembler extends Assembler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int opc = 0;
|
||||||
|
if (isSimd) {
|
||||||
|
switch (prefix2) {
|
||||||
|
case P_0F:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F;
|
||||||
|
break;
|
||||||
|
case P_0F38:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_38;
|
||||||
|
break;
|
||||||
|
case P_0F3A:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
isSimd = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isSimd) {
|
if (isSimd) {
|
||||||
int pre;
|
int pre;
|
||||||
int opc;
|
|
||||||
boolean rexVexW = (size == QWORD) ? true : false;
|
boolean rexVexW = (size == QWORD) ? true : false;
|
||||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||||
int curPrefix = size.sizePrefix | prefix1;
|
int curPrefix = size.sizePrefix | prefix1;
|
||||||
@ -958,20 +977,6 @@ public class AMD64Assembler extends Assembler {
|
|||||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (prefix2) {
|
|
||||||
case P_0F:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F;
|
|
||||||
break;
|
|
||||||
case P_0F38:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_38;
|
|
||||||
break;
|
|
||||||
case P_0F3A:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (noNds) {
|
if (noNds) {
|
||||||
asm.simdPrefix(dst, Register.None, src, pre, opc, attributes);
|
asm.simdPrefix(dst, Register.None, src, pre, opc, attributes);
|
||||||
} else {
|
} else {
|
||||||
@ -1055,8 +1060,7 @@ public class AMD64Assembler extends Assembler {
|
|||||||
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
opc = VexOpcode.VEX_OPCODE_NONE;
|
throw GraalError.shouldNotReachHere("invalid VEX instruction prefix");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
int encode;
|
int encode;
|
||||||
encode = asm.simdPrefixAndEncode(dst, nds, src, pre, opc, attributes);
|
encode = asm.simdPrefixAndEncode(dst, nds, src, pre, opc, attributes);
|
||||||
@ -1096,8 +1100,7 @@ public class AMD64Assembler extends Assembler {
|
|||||||
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
opc = VexOpcode.VEX_OPCODE_NONE;
|
throw GraalError.shouldNotReachHere("invalid VEX instruction prefix");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
asm.simdPrefix(dst, nds, src, pre, opc, attributes);
|
asm.simdPrefix(dst, nds, src, pre, opc, attributes);
|
||||||
asm.emitByte(op);
|
asm.emitByte(op);
|
||||||
@ -1163,9 +1166,26 @@ public class AMD64Assembler extends Assembler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int opc = 0;
|
||||||
|
if (isSimd) {
|
||||||
|
switch (prefix2) {
|
||||||
|
case P_0F:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F;
|
||||||
|
break;
|
||||||
|
case P_0F38:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_38;
|
||||||
|
break;
|
||||||
|
case P_0F3A:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
isSimd = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isSimd) {
|
if (isSimd) {
|
||||||
int pre;
|
int pre;
|
||||||
int opc;
|
|
||||||
boolean rexVexW = (size == QWORD) ? true : false;
|
boolean rexVexW = (size == QWORD) ? true : false;
|
||||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||||
int curPrefix = size.sizePrefix | prefix1;
|
int curPrefix = size.sizePrefix | prefix1;
|
||||||
@ -1183,20 +1203,6 @@ public class AMD64Assembler extends Assembler {
|
|||||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (prefix2) {
|
|
||||||
case P_0F:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F;
|
|
||||||
break;
|
|
||||||
case P_0F38:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_38;
|
|
||||||
break;
|
|
||||||
case P_0F3A:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int encode;
|
int encode;
|
||||||
if (noNds) {
|
if (noNds) {
|
||||||
encode = asm.simdPrefixAndEncode(src, Register.None, dst, pre, opc, attributes);
|
encode = asm.simdPrefixAndEncode(src, Register.None, dst, pre, opc, attributes);
|
||||||
@ -1222,9 +1228,26 @@ public class AMD64Assembler extends Assembler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int opc = 0;
|
||||||
|
if (isSimd) {
|
||||||
|
switch (prefix2) {
|
||||||
|
case P_0F:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F;
|
||||||
|
break;
|
||||||
|
case P_0F38:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_38;
|
||||||
|
break;
|
||||||
|
case P_0F3A:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
isSimd = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isSimd) {
|
if (isSimd) {
|
||||||
int pre;
|
int pre;
|
||||||
int opc;
|
|
||||||
boolean rexVexW = (size == QWORD) ? true : false;
|
boolean rexVexW = (size == QWORD) ? true : false;
|
||||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, rexVexW, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||||
int curPrefix = size.sizePrefix | prefix1;
|
int curPrefix = size.sizePrefix | prefix1;
|
||||||
@ -1242,20 +1265,6 @@ public class AMD64Assembler extends Assembler {
|
|||||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (prefix2) {
|
|
||||||
case P_0F:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F;
|
|
||||||
break;
|
|
||||||
case P_0F38:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_38;
|
|
||||||
break;
|
|
||||||
case P_0F3A:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
asm.simdPrefix(src, Register.None, dst, pre, opc, attributes);
|
asm.simdPrefix(src, Register.None, dst, pre, opc, attributes);
|
||||||
asm.emitByte(op);
|
asm.emitByte(op);
|
||||||
asm.emitOperandHelper(src, dst, 0);
|
asm.emitOperandHelper(src, dst, 0);
|
||||||
@ -1390,9 +1399,26 @@ public class AMD64Assembler extends Assembler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int opc = 0;
|
||||||
|
if (isSimd) {
|
||||||
|
switch (prefix2) {
|
||||||
|
case P_0F:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F;
|
||||||
|
break;
|
||||||
|
case P_0F38:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_38;
|
||||||
|
break;
|
||||||
|
case P_0F3A:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
isSimd = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isSimd) {
|
if (isSimd) {
|
||||||
int pre;
|
int pre;
|
||||||
int opc;
|
|
||||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||||
int curPrefix = size.sizePrefix | prefix1;
|
int curPrefix = size.sizePrefix | prefix1;
|
||||||
switch (curPrefix) {
|
switch (curPrefix) {
|
||||||
@ -1409,20 +1435,6 @@ public class AMD64Assembler extends Assembler {
|
|||||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (prefix2) {
|
|
||||||
case P_0F:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F;
|
|
||||||
break;
|
|
||||||
case P_0F38:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_38;
|
|
||||||
break;
|
|
||||||
case P_0F3A:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int encode;
|
int encode;
|
||||||
if (noNds) {
|
if (noNds) {
|
||||||
encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes);
|
encode = asm.simdPrefixAndEncode(dst, Register.None, src, pre, opc, attributes);
|
||||||
@ -1453,9 +1465,26 @@ public class AMD64Assembler extends Assembler {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int opc = 0;
|
||||||
|
if (isSimd) {
|
||||||
|
switch (prefix2) {
|
||||||
|
case P_0F:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F;
|
||||||
|
break;
|
||||||
|
case P_0F38:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_38;
|
||||||
|
break;
|
||||||
|
case P_0F3A:
|
||||||
|
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
isSimd = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (isSimd) {
|
if (isSimd) {
|
||||||
int pre;
|
int pre;
|
||||||
int opc;
|
|
||||||
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
AMD64InstructionAttr attributes = new AMD64InstructionAttr(AvxVectorLen.AVX_128bit, /* rexVexW */ false, /* legacyMode */ false, /* noMaskReg */ false, /* usesVl */ false, asm.target);
|
||||||
int curPrefix = size.sizePrefix | prefix1;
|
int curPrefix = size.sizePrefix | prefix1;
|
||||||
switch (curPrefix) {
|
switch (curPrefix) {
|
||||||
@ -1472,21 +1501,6 @@ public class AMD64Assembler extends Assembler {
|
|||||||
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
pre = VexSimdPrefix.VEX_SIMD_NONE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (prefix2) {
|
|
||||||
case P_0F:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F;
|
|
||||||
break;
|
|
||||||
case P_0F38:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_38;
|
|
||||||
break;
|
|
||||||
case P_0F3A:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_0F_3A;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
opc = VexOpcode.VEX_OPCODE_NONE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (noNds) {
|
if (noNds) {
|
||||||
asm.simdPrefix(dst, Register.None, src, pre, opc, attributes);
|
asm.simdPrefix(dst, Register.None, src, pre, opc, attributes);
|
||||||
} else {
|
} else {
|
||||||
|
@ -33,9 +33,9 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicSet;
|
||||||
import org.graalvm.compiler.core.common.CompilationIdentifier;
|
import org.graalvm.compiler.core.common.CompilationIdentifier;
|
||||||
import org.graalvm.compiler.graph.NodeSourcePosition;
|
import org.graalvm.compiler.graph.NodeSourcePosition;
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
|
|
||||||
import jdk.vm.ci.code.DebugInfo;
|
import jdk.vm.ci.code.DebugInfo;
|
||||||
import jdk.vm.ci.code.StackSlot;
|
import jdk.vm.ci.code.StackSlot;
|
||||||
|
@ -40,7 +40,7 @@ public final class DataSection implements Iterable<Data> {
|
|||||||
|
|
||||||
public interface Patches {
|
public interface Patches {
|
||||||
|
|
||||||
void registerPatch(VMConstant c);
|
void registerPatch(int position, VMConstant c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract static class Data {
|
public abstract static class Data {
|
||||||
|
@ -27,7 +27,6 @@ import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
|
|||||||
import org.graalvm.compiler.core.common.NumUtil;
|
import org.graalvm.compiler.core.common.NumUtil;
|
||||||
import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
|
import org.graalvm.compiler.core.common.type.AbstractPointerStamp;
|
||||||
import org.graalvm.compiler.core.common.type.IntegerStamp;
|
import org.graalvm.compiler.core.common.type.IntegerStamp;
|
||||||
import org.graalvm.compiler.core.common.type.PrimitiveStamp;
|
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.nodes.NodeView;
|
import org.graalvm.compiler.nodes.NodeView;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
@ -107,7 +106,9 @@ public class AMD64AddressLowering extends AddressLowering {
|
|||||||
ret.setBase(add.getX());
|
ret.setBase(add.getX());
|
||||||
ret.setIndex(considerNegation(graph, add.getY(), isBaseNegated));
|
ret.setIndex(considerNegation(graph, add.getY(), isBaseNegated));
|
||||||
return true;
|
return true;
|
||||||
} else if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
|
}
|
||||||
|
|
||||||
|
if (ret.getBase() == null && ret.getIndex() instanceof AddNode) {
|
||||||
AddNode add = (AddNode) ret.getIndex();
|
AddNode add = (AddNode) ret.getIndex();
|
||||||
ret.setBase(considerNegation(graph, add.getX(), isIndexNegated));
|
ret.setBase(considerNegation(graph, add.getX(), isIndexNegated));
|
||||||
ret.setIndex(add.getY());
|
ret.setIndex(add.getY());
|
||||||
@ -188,7 +189,7 @@ public class AMD64AddressLowering extends AddressLowering {
|
|||||||
return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
|
return improveConstDisp(address, node, c, null, shift, negateExtractedDisplacement);
|
||||||
} else {
|
} else {
|
||||||
if (node.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
|
if (node.stamp(NodeView.DEFAULT) instanceof IntegerStamp) {
|
||||||
assert PrimitiveStamp.getBits(node.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
|
assert IntegerStamp.getBits(node.stamp(NodeView.DEFAULT)) == ADDRESS_BITS;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we can't swallow zero-extends because of multiple reasons:
|
* we can't swallow zero-extends because of multiple reasons:
|
||||||
|
@ -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.QWORD;
|
||||||
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD;
|
import static org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize.WORD;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.Equivalence;
|
||||||
import org.graalvm.compiler.core.common.LIRKind;
|
import org.graalvm.compiler.core.common.LIRKind;
|
||||||
import org.graalvm.compiler.lir.VirtualStackSlot;
|
import org.graalvm.compiler.lir.VirtualStackSlot;
|
||||||
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
|
import org.graalvm.compiler.lir.amd64.AMD64LIRInstruction;
|
||||||
import org.graalvm.compiler.lir.amd64.AMD64Move.AMD64PushPopStackMove;
|
import org.graalvm.compiler.lir.amd64.AMD64Move.AMD64PushPopStackMove;
|
||||||
import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
|
import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
|
||||||
import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory;
|
import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory;
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
|
|
||||||
import jdk.vm.ci.amd64.AMD64Kind;
|
import jdk.vm.ci.amd64.AMD64Kind;
|
||||||
import jdk.vm.ci.code.Architecture;
|
import jdk.vm.ci.code.Architecture;
|
||||||
|
@ -44,6 +44,7 @@ import org.graalvm.compiler.asm.amd64.AMD64Assembler.OperandSize;
|
|||||||
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
|
import org.graalvm.compiler.asm.amd64.AMD64Assembler.SSEOp;
|
||||||
import org.graalvm.compiler.core.common.LIRKind;
|
import org.graalvm.compiler.core.common.LIRKind;
|
||||||
import org.graalvm.compiler.core.common.NumUtil;
|
import org.graalvm.compiler.core.common.NumUtil;
|
||||||
|
import org.graalvm.compiler.core.common.calc.CanonicalCondition;
|
||||||
import org.graalvm.compiler.core.common.calc.Condition;
|
import org.graalvm.compiler.core.common.calc.Condition;
|
||||||
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
|
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
|
||||||
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
||||||
@ -128,7 +129,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected ComplexMatchResult emitCompareBranchMemory(IfNode ifNode, CompareNode compare, ValueNode value, LIRLowerableAccess access) {
|
protected ComplexMatchResult emitCompareBranchMemory(IfNode ifNode, CompareNode compare, ValueNode value, LIRLowerableAccess access) {
|
||||||
Condition cond = compare.condition();
|
Condition cond = compare.condition().asCondition();
|
||||||
AMD64Kind kind = getMemoryKind(access);
|
AMD64Kind kind = getMemoryKind(access);
|
||||||
boolean matchedAsConstant = false; // For assertion checking
|
boolean matchedAsConstant = false; // For assertion checking
|
||||||
|
|
||||||
@ -303,7 +304,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
|
|||||||
@MatchRule("(If (FloatEquals=compare value ValueCompareAndSwap=cas))")
|
@MatchRule("(If (FloatEquals=compare value ValueCompareAndSwap=cas))")
|
||||||
@MatchRule("(If (IntegerEquals=compare value ValueCompareAndSwap=cas))")
|
@MatchRule("(If (IntegerEquals=compare value ValueCompareAndSwap=cas))")
|
||||||
public ComplexMatchResult ifCompareValueCas(IfNode root, CompareNode compare, ValueNode value, ValueCompareAndSwapNode cas) {
|
public ComplexMatchResult ifCompareValueCas(IfNode root, CompareNode compare, ValueNode value, ValueCompareAndSwapNode cas) {
|
||||||
assert compare.condition() == Condition.EQ;
|
assert compare.condition() == CanonicalCondition.EQ;
|
||||||
if (value == cas.getExpectedValue() && cas.usages().count() == 1) {
|
if (value == cas.getExpectedValue() && cas.usages().count() == 1) {
|
||||||
return builder -> {
|
return builder -> {
|
||||||
LIRKind kind = getLirKind(cas);
|
LIRKind kind = getLirKind(cas);
|
||||||
@ -326,7 +327,7 @@ public class AMD64NodeMatchRules extends NodeMatchRules {
|
|||||||
@MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
|
@MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
|
||||||
public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
|
public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
|
||||||
JavaConstant constant = value.asJavaConstant();
|
JavaConstant constant = value.asJavaConstant();
|
||||||
assert compare.condition() == Condition.EQ;
|
assert compare.condition() == CanonicalCondition.EQ;
|
||||||
if (constant != null && cas.usages().count() == 1) {
|
if (constant != null && cas.usages().count() == 1) {
|
||||||
long constantValue = constant.asLong();
|
long constantValue = constant.asLong();
|
||||||
boolean successIsTrue;
|
boolean successIsTrue;
|
||||||
|
@ -232,6 +232,9 @@ public final class GraalOptions {
|
|||||||
@Option(help = "", type = OptionType.Debug)
|
@Option(help = "", type = OptionType.Debug)
|
||||||
public static final OptionKey<Boolean> OptScheduleOutOfLoops = new OptionKey<>(true);
|
public static final OptionKey<Boolean> OptScheduleOutOfLoops = new OptionKey<>(true);
|
||||||
|
|
||||||
|
@Option(help = "", type = OptionType.Debug)
|
||||||
|
public static final OptionKey<Boolean> GuardPriorities = new OptionKey<>(true);
|
||||||
|
|
||||||
@Option(help = "", type = OptionType.Debug)
|
@Option(help = "", type = OptionType.Debug)
|
||||||
public static final OptionKey<Boolean> OptEliminateGuards = new OptionKey<>(true);
|
public static final OptionKey<Boolean> OptEliminateGuards = new OptionKey<>(true);
|
||||||
|
|
||||||
@ -271,4 +274,7 @@ public final class GraalOptions {
|
|||||||
@Option(help = "Enable experimental Trace Register Allocation.", type = OptionType.Debug)
|
@Option(help = "Enable experimental Trace Register Allocation.", type = OptionType.Debug)
|
||||||
public static final OptionKey<Boolean> TraceRA = new OptionKey<>(false);
|
public static final OptionKey<Boolean> TraceRA = new OptionKey<>(false);
|
||||||
|
|
||||||
|
@Option(help = "How to trace inlining decisions, one of: None, Linear, Tree", type = OptionType.Debug)
|
||||||
|
public static final OptionKey<TraceInliningMode> TraceInlining = new OptionKey<>(TraceInliningMode.None);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -20,29 +20,20 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.util;
|
package org.graalvm.compiler.core.common;
|
||||||
|
|
||||||
/**
|
public enum TraceInliningMode {
|
||||||
* Unmodifiable memory efficient set data structure.
|
None(false),
|
||||||
*/
|
Linear(true),
|
||||||
public interface UnmodifiableEconomicSet<E> extends Iterable<E> {
|
Tree(true);
|
||||||
|
|
||||||
boolean contains(E element);
|
private final boolean tracing;
|
||||||
|
|
||||||
int size();
|
TraceInliningMode(boolean tracing) {
|
||||||
|
this.tracing = tracing;
|
||||||
|
}
|
||||||
|
|
||||||
boolean isEmpty();
|
public boolean isTracing() {
|
||||||
|
return tracing;
|
||||||
default E[] toArray(E[] target) {
|
|
||||||
if (target.length != size()) {
|
|
||||||
throw new UnsupportedOperationException("Length of target array must equal the size of the set.");
|
|
||||||
}
|
|
||||||
|
|
||||||
int index = 0;
|
|
||||||
for (E element : this) {
|
|
||||||
target[index++] = element;
|
|
||||||
}
|
|
||||||
|
|
||||||
return target;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -22,9 +22,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.graalvm.compiler.core.common.alloc;
|
package org.graalvm.compiler.core.common.alloc;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.Equivalence;
|
||||||
import org.graalvm.compiler.core.common.GraalOptions;
|
import org.graalvm.compiler.core.common.GraalOptions;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
|
|
||||||
import jdk.vm.ci.code.Register;
|
import jdk.vm.ci.code.Register;
|
||||||
import jdk.vm.ci.code.Register.RegisterCategory;
|
import jdk.vm.ci.code.Register.RegisterCategory;
|
||||||
|
@ -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());
|
throw new IllegalArgumentException(this.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final class CanonicalizedCondition {
|
||||||
|
private final CanonicalCondition canonicalCondition;
|
||||||
|
private final boolean mirror;
|
||||||
|
private final boolean negate;
|
||||||
|
|
||||||
|
private CanonicalizedCondition(CanonicalCondition canonicalCondition, boolean mirror, boolean negate) {
|
||||||
|
this.canonicalCondition = canonicalCondition;
|
||||||
|
this.mirror = mirror;
|
||||||
|
this.negate = negate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CanonicalCondition getCanonicalCondition() {
|
||||||
|
return canonicalCondition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean mustMirror() {
|
||||||
|
return mirror;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean mustNegate() {
|
||||||
|
return negate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CanonicalizedCondition canonicalize() {
|
||||||
|
CanonicalCondition canonicalCondition;
|
||||||
|
switch (this) {
|
||||||
|
case EQ:
|
||||||
|
case NE:
|
||||||
|
canonicalCondition = CanonicalCondition.EQ;
|
||||||
|
break;
|
||||||
|
case LT:
|
||||||
|
case LE:
|
||||||
|
case GT:
|
||||||
|
case GE:
|
||||||
|
canonicalCondition = CanonicalCondition.LT;
|
||||||
|
break;
|
||||||
|
case BT:
|
||||||
|
case BE:
|
||||||
|
case AT:
|
||||||
|
case AE:
|
||||||
|
canonicalCondition = CanonicalCondition.BT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException(this.toString());
|
||||||
|
}
|
||||||
|
return new CanonicalizedCondition(canonicalCondition, canonicalMirror(), canonicalNegate());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a condition and its negation, this method returns true for one of the two and false for
|
* Given a condition and its negation, this method returns true for one of the two and false for
|
||||||
* the other one. This can be used to keep comparisons in a canonical form.
|
* the other one. This can be used to keep comparisons in a canonical form.
|
||||||
@ -151,7 +200,7 @@ public enum Condition {
|
|||||||
* Returns true if the condition needs to be mirrored to get to a canonical condition. The
|
* Returns true if the condition needs to be mirrored to get to a canonical condition. The
|
||||||
* result of the mirroring operation might still need to be negated to achieve a canonical form.
|
* result of the mirroring operation might still need to be negated to achieve a canonical form.
|
||||||
*/
|
*/
|
||||||
public boolean canonicalMirror() {
|
private boolean canonicalMirror() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case EQ:
|
case EQ:
|
||||||
return false;
|
return false;
|
||||||
@ -181,7 +230,7 @@ public enum Condition {
|
|||||||
* Returns true if the condition needs to be negated to get to a canonical condition. The result
|
* Returns true if the condition needs to be negated to get to a canonical condition. The result
|
||||||
* of the negation might still need to be mirrored to achieve a canonical form.
|
* of the negation might still need to be mirrored to achieve a canonical form.
|
||||||
*/
|
*/
|
||||||
public boolean canonicalNegate() {
|
private boolean canonicalNegate() {
|
||||||
switch (this) {
|
switch (this) {
|
||||||
case EQ:
|
case EQ:
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -20,32 +20,13 @@
|
|||||||
* or visit www.oracle.com if you need additional information or have any
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
* questions.
|
* questions.
|
||||||
*/
|
*/
|
||||||
package org.graalvm.util;
|
package org.graalvm.compiler.core.common.spi;
|
||||||
|
|
||||||
/**
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
* Unmodifiable memory efficient map data structure.
|
|
||||||
*/
|
|
||||||
public interface UnmodifiableEconomicMap<K, V> {
|
|
||||||
|
|
||||||
V get(K key);
|
public interface ArrayOffsetProvider {
|
||||||
|
|
||||||
default V get(K key, V defaultValue) {
|
int arrayBaseOffset(JavaKind elementKind);
|
||||||
V v = get(key);
|
|
||||||
if (v == null) {
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean containsKey(K key);
|
int arrayScalingFactor(JavaKind elementKind);
|
||||||
|
|
||||||
int size();
|
|
||||||
|
|
||||||
boolean isEmpty();
|
|
||||||
|
|
||||||
Iterable<V> getValues();
|
|
||||||
|
|
||||||
Iterable<K> getKeys();
|
|
||||||
|
|
||||||
UnmodifiableMapCursor<K, V> getEntries();
|
|
||||||
}
|
}
|
@ -40,4 +40,5 @@ public interface CodeGenProviders {
|
|||||||
|
|
||||||
ConstantReflectionProvider getConstantReflection();
|
ConstantReflectionProvider getConstantReflection();
|
||||||
|
|
||||||
|
ArrayOffsetProvider getArrayOffsetProvider();
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,9 @@ import java.util.Arrays;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import jdk.vm.ci.meta.Constant;
|
||||||
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
|
|
||||||
import org.graalvm.compiler.core.common.calc.FloatConvert;
|
import org.graalvm.compiler.core.common.calc.FloatConvert;
|
||||||
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Add;
|
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Add;
|
||||||
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.And;
|
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.And;
|
||||||
@ -51,9 +54,6 @@ import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Not;
|
|||||||
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Sqrt;
|
import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Sqrt;
|
||||||
import org.graalvm.util.CollectionsUtil;
|
import org.graalvm.util.CollectionsUtil;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.Constant;
|
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Information about arithmetic operations.
|
* Information about arithmetic operations.
|
||||||
*/
|
*/
|
||||||
|
@ -25,8 +25,8 @@ package org.graalvm.compiler.core.common.util;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.graalvm.util.EconomicMap;
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.util.Equivalence;
|
import org.graalvm.collections.Equivalence;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an array of T objects order by the occurrence frequency of each object. The most
|
* Creates an array of T objects order by the occurrence frequency of each object. The most
|
||||||
|
@ -58,6 +58,9 @@ import javax.tools.FileObject;
|
|||||||
import javax.tools.JavaFileObject;
|
import javax.tools.JavaFileObject;
|
||||||
import javax.tools.StandardLocation;
|
import javax.tools.StandardLocation;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.EconomicSet;
|
||||||
|
import org.graalvm.collections.Equivalence;
|
||||||
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
||||||
import org.graalvm.compiler.core.match.ComplexMatchResult;
|
import org.graalvm.compiler.core.match.ComplexMatchResult;
|
||||||
import org.graalvm.compiler.core.match.MatchRule;
|
import org.graalvm.compiler.core.match.MatchRule;
|
||||||
@ -70,9 +73,6 @@ import org.graalvm.compiler.debug.GraalError;
|
|||||||
import org.graalvm.compiler.graph.Position;
|
import org.graalvm.compiler.graph.Position;
|
||||||
import org.graalvm.compiler.nodes.ValueNode;
|
import org.graalvm.compiler.nodes.ValueNode;
|
||||||
import org.graalvm.compiler.serviceprovider.ServiceProvider;
|
import org.graalvm.compiler.serviceprovider.ServiceProvider;
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes classes annotated with {@link MatchRule}. A {@link MatchStatementSet} service is
|
* Processes classes annotated with {@link MatchRule}. A {@link MatchStatementSet} service is
|
||||||
|
@ -29,6 +29,7 @@ import static jdk.vm.ci.sparc.SPARCKind.WORD;
|
|||||||
import static jdk.vm.ci.sparc.SPARCKind.XWORD;
|
import static jdk.vm.ci.sparc.SPARCKind.XWORD;
|
||||||
|
|
||||||
import org.graalvm.compiler.core.common.LIRKind;
|
import org.graalvm.compiler.core.common.LIRKind;
|
||||||
|
import org.graalvm.compiler.core.common.calc.CanonicalCondition;
|
||||||
import org.graalvm.compiler.core.common.calc.Condition;
|
import org.graalvm.compiler.core.common.calc.Condition;
|
||||||
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
||||||
import org.graalvm.compiler.core.match.ComplexMatchResult;
|
import org.graalvm.compiler.core.match.ComplexMatchResult;
|
||||||
@ -147,7 +148,7 @@ public class SPARCNodeMatchRules extends NodeMatchRules {
|
|||||||
@MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
|
@MatchRule("(If (IntegerEquals=compare value LogicCompareAndSwap=cas))")
|
||||||
public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
|
public ComplexMatchResult ifCompareLogicCas(IfNode root, CompareNode compare, ValueNode value, LogicCompareAndSwapNode cas) {
|
||||||
JavaConstant constant = value.asJavaConstant();
|
JavaConstant constant = value.asJavaConstant();
|
||||||
assert compare.condition() == Condition.EQ;
|
assert compare.condition() == CanonicalCondition.EQ;
|
||||||
if (constant != null && cas.usages().count() == 1) {
|
if (constant != null && cas.usages().count() == 1) {
|
||||||
long constantValue = constant.asLong();
|
long constantValue = constant.asLong();
|
||||||
boolean successIsTrue;
|
boolean successIsTrue;
|
||||||
|
@ -123,19 +123,19 @@ public class ConditionalEliminationTest11 extends ConditionalEliminationTestBase
|
|||||||
|
|
||||||
public static int test6Snippet(int a) {
|
public static int test6Snippet(int a) {
|
||||||
if ((a & 8) != 0) {
|
if ((a & 8) != 0) {
|
||||||
GraalDirectives.deoptimizeAndInvalidate();
|
GraalDirectives.deoptimize();
|
||||||
}
|
}
|
||||||
if ((a & 15) != 15) {
|
if ((a & 15) != 15) {
|
||||||
GraalDirectives.deoptimizeAndInvalidate();
|
GraalDirectives.deoptimize();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int reference6Snippet(int a) {
|
public static int reference6Snippet(int a) {
|
||||||
if ((a & 8) != 0) {
|
if ((a & 8) != 0) {
|
||||||
GraalDirectives.deoptimizeAndInvalidate();
|
GraalDirectives.deoptimize();
|
||||||
}
|
}
|
||||||
GraalDirectives.deoptimizeAndInvalidate();
|
GraalDirectives.deoptimize();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,6 @@ public class ConditionalEliminationTestBase extends GraalCompilerTest {
|
|||||||
new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
|
new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
|
||||||
canonicalizer.apply(graph, context);
|
canonicalizer.apply(graph, context);
|
||||||
canonicalizer.apply(graph, context);
|
canonicalizer.apply(graph, context);
|
||||||
new ConvertDeoptimizeToGuardPhase().apply(graph, context);
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
debug.handle(t);
|
debug.handle(t);
|
||||||
}
|
}
|
||||||
@ -86,7 +85,6 @@ public class ConditionalEliminationTestBase extends GraalCompilerTest {
|
|||||||
}
|
}
|
||||||
canonicalizer.apply(referenceGraph, context);
|
canonicalizer.apply(referenceGraph, context);
|
||||||
canonicalizer.apply(referenceGraph, context);
|
canonicalizer.apply(referenceGraph, context);
|
||||||
new ConvertDeoptimizeToGuardPhase().apply(graph, context);
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
debug.handle(t);
|
debug.handle(t);
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,12 @@ package org.graalvm.compiler.core.test;
|
|||||||
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
|
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_IGNORED;
|
||||||
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
|
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_IGNORED;
|
||||||
|
|
||||||
import org.graalvm.compiler.nodes.NodeView;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.graalvm.compiler.api.directives.GraalDirectives;
|
import org.graalvm.compiler.api.directives.GraalDirectives;
|
||||||
import org.graalvm.compiler.graph.NodeClass;
|
import org.graalvm.compiler.graph.NodeClass;
|
||||||
import org.graalvm.compiler.loop.InductionVariable;
|
import org.graalvm.compiler.loop.InductionVariable;
|
||||||
import org.graalvm.compiler.loop.LoopsData;
|
import org.graalvm.compiler.loop.LoopsData;
|
||||||
import org.graalvm.compiler.nodeinfo.NodeInfo;
|
import org.graalvm.compiler.nodeinfo.NodeInfo;
|
||||||
|
import org.graalvm.compiler.nodes.NodeView;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.ValueNode;
|
import org.graalvm.compiler.nodes.ValueNode;
|
||||||
import org.graalvm.compiler.nodes.calc.FloatingNode;
|
import org.graalvm.compiler.nodes.calc.FloatingNode;
|
||||||
@ -42,6 +40,7 @@ import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
|
|||||||
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
|
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Registration;
|
||||||
import org.graalvm.compiler.nodes.spi.LIRLowerable;
|
import org.graalvm.compiler.nodes.spi.LIRLowerable;
|
||||||
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
@ -117,6 +116,21 @@ public class CountedLoopTest extends GraalCompilerTest {
|
|||||||
test("incrementSnippet", 0, 256, 3);
|
test("incrementSnippet", 0, 256, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void increment4() {
|
||||||
|
test("incrementSnippet", -10, Integer.MAX_VALUE, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void increment5() {
|
||||||
|
test("incrementSnippet", 256, 256, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void increment6() {
|
||||||
|
test("incrementSnippet", 257, 256, 1);
|
||||||
|
}
|
||||||
|
|
||||||
public static Result incrementEqSnippet(int start, int limit, int step) {
|
public static Result incrementEqSnippet(int start, int limit, int step) {
|
||||||
int i;
|
int i;
|
||||||
int inc = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive
|
int inc = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive
|
||||||
@ -144,6 +158,21 @@ public class CountedLoopTest extends GraalCompilerTest {
|
|||||||
test("incrementEqSnippet", 0, 256, 3);
|
test("incrementEqSnippet", 0, 256, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void incrementEq4() {
|
||||||
|
test("incrementEqSnippet", -10, 0, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void incrementEq5() {
|
||||||
|
test("incrementEqSnippet", 256, 256, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void incrementEq6() {
|
||||||
|
test("incrementEqSnippet", 257, 256, 1);
|
||||||
|
}
|
||||||
|
|
||||||
public static Result decrementSnippet(int start, int limit, int step) {
|
public static Result decrementSnippet(int start, int limit, int step) {
|
||||||
int i;
|
int i;
|
||||||
int dec = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive
|
int dec = ((step - 1) & 0xFFFF) + 1; // make sure this value is always strictly positive
|
||||||
@ -198,6 +227,11 @@ public class CountedLoopTest extends GraalCompilerTest {
|
|||||||
test("decrementEqSnippet", 256, 0, 3);
|
test("decrementEqSnippet", 256, 0, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void decrementEq4() {
|
||||||
|
test("decrementEqSnippet", -10, 0, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
public static Result twoVariablesSnippet() {
|
public static Result twoVariablesSnippet() {
|
||||||
Result ret = new Result();
|
Result ret = new Result();
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
@ -27,10 +27,10 @@ import java.nio.file.DirectoryStream;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.debug.DebugOptions;
|
import org.graalvm.compiler.debug.DebugOptions;
|
||||||
import org.graalvm.compiler.options.OptionKey;
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -561,7 +561,7 @@ public abstract class GraalCompilerTest extends GraalTest {
|
|||||||
* @return a scheduled textual dump of {@code graph} .
|
* @return a scheduled textual dump of {@code graph} .
|
||||||
*/
|
*/
|
||||||
protected static String getScheduledGraphString(StructuredGraph graph) {
|
protected static String getScheduledGraphString(StructuredGraph graph) {
|
||||||
SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST);
|
SchedulePhase schedule = new SchedulePhase(SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER);
|
||||||
schedule.apply(graph);
|
schedule.apply(graph);
|
||||||
ScheduleResult scheduleResult = graph.getLastSchedule();
|
ScheduleResult scheduleResult = graph.getLastSchedule();
|
||||||
|
|
||||||
|
@ -22,14 +22,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.graalvm.compiler.core.test;
|
package org.graalvm.compiler.core.test;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.debug.DebugOptions;
|
|
||||||
import org.graalvm.compiler.debug.DebugContext.Scope;
|
import org.graalvm.compiler.debug.DebugContext.Scope;
|
||||||
|
import org.graalvm.compiler.debug.DebugOptions;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
|
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
|
||||||
import org.graalvm.compiler.options.OptionKey;
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -24,20 +24,29 @@ package org.graalvm.compiler.core.test;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.Assert;
|
|
||||||
|
|
||||||
import org.graalvm.compiler.graph.Node;
|
import org.graalvm.compiler.graph.Node;
|
||||||
import org.graalvm.compiler.graph.NodeMap;
|
import org.graalvm.compiler.graph.NodeMap;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
|
import org.graalvm.compiler.nodes.StructuredGraph.ScheduleResult;
|
||||||
import org.graalvm.compiler.nodes.cfg.Block;
|
import org.graalvm.compiler.nodes.cfg.Block;
|
||||||
import org.graalvm.compiler.phases.schedule.SchedulePhase;
|
import org.graalvm.compiler.phases.schedule.SchedulePhase;
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
import jdk.vm.ci.meta.SpeculationLog;
|
||||||
|
|
||||||
public class GraphScheduleTest extends GraalCompilerTest {
|
public class GraphScheduleTest extends GraalCompilerTest {
|
||||||
|
|
||||||
protected void assertOrderedAfterSchedule(StructuredGraph graph, Node a, Node b) {
|
protected void assertOrderedAfterSchedule(StructuredGraph graph, Node a, Node b) {
|
||||||
SchedulePhase ibp = new SchedulePhase(SchedulePhase.SchedulingStrategy.LATEST);
|
assertOrderedAfterSchedule(graph, SchedulePhase.SchedulingStrategy.LATEST, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void assertOrderedAfterSchedule(StructuredGraph graph, SchedulePhase.SchedulingStrategy strategy, Node a, Node b) {
|
||||||
|
SchedulePhase ibp = new SchedulePhase(strategy);
|
||||||
ibp.apply(graph);
|
ibp.apply(graph);
|
||||||
|
assertOrderedAfterLastSchedule(graph, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void assertOrderedAfterLastSchedule(StructuredGraph graph, Node a, Node b) {
|
||||||
assertOrderedAfterSchedule(graph.getLastSchedule(), a, b);
|
assertOrderedAfterSchedule(graph.getLastSchedule(), a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,7 +57,7 @@ public class GraphScheduleTest extends GraalCompilerTest {
|
|||||||
|
|
||||||
if (bBlock == aBlock) {
|
if (bBlock == aBlock) {
|
||||||
List<Node> instructions = ibp.nodesFor(bBlock);
|
List<Node> instructions = ibp.nodesFor(bBlock);
|
||||||
Assert.assertTrue(instructions.indexOf(b) > instructions.indexOf(a));
|
Assert.assertTrue(a + " should be before " + b, instructions.indexOf(b) > instructions.indexOf(a));
|
||||||
} else {
|
} else {
|
||||||
Block block = bBlock;
|
Block block = bBlock;
|
||||||
while (block != null) {
|
while (block != null) {
|
||||||
@ -60,4 +69,9 @@ public class GraphScheduleTest extends GraalCompilerTest {
|
|||||||
Assert.fail("block of A doesn't dominate the block of B");
|
Assert.fail("block of A doesn't dominate the block of B");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SpeculationLog getSpeculationLog() {
|
||||||
|
return getCodeCache().createSpeculationLog();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
public static final int N = 10000;
|
||||||
|
|
||||||
private static final SchedulingStrategy[] Strategies = new SchedulingStrategy[]{SchedulingStrategy.EARLIEST};
|
private static final SchedulingStrategy[] Strategies = new SchedulingStrategy[]{SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER};
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLongAddChain() {
|
public void testLongAddChain() {
|
||||||
|
@ -31,13 +31,13 @@ import java.util.Iterator;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.MapCursor;
|
||||||
import org.graalvm.compiler.options.Option;
|
import org.graalvm.compiler.options.Option;
|
||||||
import org.graalvm.compiler.options.OptionDescriptor;
|
import org.graalvm.compiler.options.OptionDescriptor;
|
||||||
import org.graalvm.compiler.options.OptionDescriptors;
|
import org.graalvm.compiler.options.OptionDescriptors;
|
||||||
import org.graalvm.compiler.options.OptionKey;
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.MapCursor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of {@link OptionDescriptor} that uses reflection to create descriptors from a
|
* An implementation of {@link OptionDescriptor} that uses reflection to create descriptors from a
|
||||||
|
@ -70,7 +70,7 @@ public class SchedulingTest2 extends GraphScheduleTest {
|
|||||||
returnNode.replaceAtPredecessor(beginNode);
|
returnNode.replaceAtPredecessor(beginNode);
|
||||||
beginNode.setNext(returnNode);
|
beginNode.setNext(returnNode);
|
||||||
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
|
debug.dump(DebugContext.BASIC_LEVEL, graph, "Graph");
|
||||||
SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.EARLIEST);
|
SchedulePhase schedulePhase = new SchedulePhase(SchedulingStrategy.EARLIEST_WITH_GUARD_ORDER);
|
||||||
schedulePhase.apply(graph);
|
schedulePhase.apply(graph);
|
||||||
ScheduleResult schedule = graph.getLastSchedule();
|
ScheduleResult schedule = graph.getLastSchedule();
|
||||||
BlockMap<List<Node>> blockToNodesMap = schedule.getBlockToNodesMap();
|
BlockMap<List<Node>> blockToNodesMap = schedule.getBlockToNodesMap();
|
||||||
|
@ -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 static org.graalvm.compiler.phases.common.DeadCodeEliminationPhase.Optionality.Optional;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicSet;
|
||||||
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.debug.TTY;
|
import org.graalvm.compiler.debug.TTY;
|
||||||
@ -43,7 +44,6 @@ import org.graalvm.compiler.phases.tiers.HighTierContext;
|
|||||||
import org.graalvm.compiler.phases.tiers.PhaseContext;
|
import org.graalvm.compiler.phases.tiers.PhaseContext;
|
||||||
import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase;
|
import org.graalvm.compiler.virtual.phases.ea.EarlyReadEliminationPhase;
|
||||||
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
|
import org.graalvm.compiler.virtual.phases.ea.PartialEscapePhase;
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
|
@ -25,6 +25,7 @@ package org.graalvm.compiler.core;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicSet;
|
||||||
import org.graalvm.compiler.code.CompilationResult;
|
import org.graalvm.compiler.code.CompilationResult;
|
||||||
import org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext;
|
import org.graalvm.compiler.core.LIRGenerationPhase.LIRGenerationContext;
|
||||||
import org.graalvm.compiler.core.common.GraalOptions;
|
import org.graalvm.compiler.core.common.GraalOptions;
|
||||||
@ -64,7 +65,6 @@ import org.graalvm.compiler.phases.tiers.MidTierContext;
|
|||||||
import org.graalvm.compiler.phases.tiers.Suites;
|
import org.graalvm.compiler.phases.tiers.Suites;
|
||||||
import org.graalvm.compiler.phases.tiers.TargetProvider;
|
import org.graalvm.compiler.phases.tiers.TargetProvider;
|
||||||
import org.graalvm.compiler.phases.util.Providers;
|
import org.graalvm.compiler.phases.util.Providers;
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
|
|
||||||
import jdk.vm.ci.code.RegisterConfig;
|
import jdk.vm.ci.code.RegisterConfig;
|
||||||
import jdk.vm.ci.code.TargetDescription;
|
import jdk.vm.ci.code.TargetDescription;
|
||||||
|
@ -26,6 +26,8 @@ import java.util.ArrayDeque;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.Equivalence;
|
||||||
import org.graalvm.compiler.debug.CounterKey;
|
import org.graalvm.compiler.debug.CounterKey;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.debug.GraalError;
|
import org.graalvm.compiler.debug.GraalError;
|
||||||
@ -42,8 +44,6 @@ import org.graalvm.compiler.nodes.virtual.EscapeObjectState;
|
|||||||
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
|
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
|
||||||
import org.graalvm.compiler.virtual.nodes.MaterializedObjectState;
|
import org.graalvm.compiler.virtual.nodes.MaterializedObjectState;
|
||||||
import org.graalvm.compiler.virtual.nodes.VirtualObjectState;
|
import org.graalvm.compiler.virtual.nodes.VirtualObjectState;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
|
|
||||||
import jdk.vm.ci.code.BytecodeFrame;
|
import jdk.vm.ci.code.BytecodeFrame;
|
||||||
import jdk.vm.ci.code.VirtualObject;
|
import jdk.vm.ci.code.VirtualObject;
|
||||||
|
@ -33,6 +33,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.UnmodifiableMapCursor;
|
||||||
import org.graalvm.compiler.core.common.LIRKind;
|
import org.graalvm.compiler.core.common.LIRKind;
|
||||||
import org.graalvm.compiler.core.common.calc.Condition;
|
import org.graalvm.compiler.core.common.calc.Condition;
|
||||||
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
|
import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
|
||||||
@ -100,8 +102,6 @@ import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
|||||||
import org.graalvm.compiler.nodes.spi.NodeValueMap;
|
import org.graalvm.compiler.nodes.spi.NodeValueMap;
|
||||||
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
|
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.UnmodifiableMapCursor;
|
|
||||||
|
|
||||||
import jdk.vm.ci.code.CallingConvention;
|
import jdk.vm.ci.code.CallingConvention;
|
||||||
import jdk.vm.ci.code.StackSlot;
|
import jdk.vm.ci.code.StackSlot;
|
||||||
@ -538,7 +538,8 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
|
|||||||
|
|
||||||
public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
|
public void emitCompareBranch(CompareNode compare, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
|
||||||
PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
|
PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
|
||||||
gen.emitCompareBranch(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor, trueSuccessorProbability);
|
gen.emitCompareBranch(kind, operand(compare.getX()), operand(compare.getY()), compare.condition().asCondition(), compare.unorderedIsTrue(), trueSuccessor, falseSuccessor,
|
||||||
|
trueSuccessorProbability);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
|
public void emitIntegerTestBranch(IntegerTestNode test, LabelRef trueSuccessor, LabelRef falseSuccessor, double trueSuccessorProbability) {
|
||||||
@ -566,7 +567,7 @@ public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGeneratio
|
|||||||
} else if (node instanceof CompareNode) {
|
} else if (node instanceof CompareNode) {
|
||||||
CompareNode compare = (CompareNode) node;
|
CompareNode compare = (CompareNode) node;
|
||||||
PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
|
PlatformKind kind = gen.getLIRKind(compare.getX().stamp(NodeView.DEFAULT)).getPlatformKind();
|
||||||
return gen.emitConditionalMove(kind, operand(compare.getX()), operand(compare.getY()), compare.condition(), compare.unorderedIsTrue(), trueValue, falseValue);
|
return gen.emitConditionalMove(kind, operand(compare.getX()), operand(compare.getY()), compare.condition().asCondition(), compare.unorderedIsTrue(), trueValue, falseValue);
|
||||||
} else if (node instanceof LogicConstantNode) {
|
} else if (node instanceof LogicConstantNode) {
|
||||||
return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue);
|
return gen.emitMove(((LogicConstantNode) node).getValue() ? trueValue : falseValue);
|
||||||
} else if (node instanceof IntegerTestNode) {
|
} else if (node instanceof IntegerTestNode) {
|
||||||
|
@ -28,6 +28,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.Equivalence;
|
||||||
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
|
import org.graalvm.compiler.core.gen.NodeLIRBuilder;
|
||||||
import org.graalvm.compiler.core.match.MatchPattern.Result;
|
import org.graalvm.compiler.core.match.MatchPattern.Result;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
@ -35,8 +37,6 @@ import org.graalvm.compiler.debug.GraalError;
|
|||||||
import org.graalvm.compiler.graph.Node;
|
import org.graalvm.compiler.graph.Node;
|
||||||
import org.graalvm.compiler.nodes.calc.FloatingNode;
|
import org.graalvm.compiler.nodes.calc.FloatingNode;
|
||||||
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
|
import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for state captured during a match.
|
* Container for state captured during a match.
|
||||||
|
@ -27,6 +27,9 @@ import static org.graalvm.compiler.debug.DebugOptions.LogVerbose;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.Equivalence;
|
||||||
|
import org.graalvm.collections.MapCursor;
|
||||||
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
import org.graalvm.compiler.core.gen.NodeMatchRules;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.debug.GraalError;
|
import org.graalvm.compiler.debug.GraalError;
|
||||||
@ -36,9 +39,6 @@ import org.graalvm.compiler.graph.NodeClass;
|
|||||||
import org.graalvm.compiler.graph.Position;
|
import org.graalvm.compiler.graph.Position;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.serviceprovider.GraalServices;
|
import org.graalvm.compiler.serviceprovider.GraalServices;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
import org.graalvm.util.MapCursor;
|
|
||||||
|
|
||||||
public class MatchRuleRegistry {
|
public class MatchRuleRegistry {
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.graalvm.compiler.core.phases;
|
package org.graalvm.compiler.core.phases;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicSet;
|
||||||
|
import org.graalvm.collections.Equivalence;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.graph.Graph.NodeEvent;
|
import org.graalvm.compiler.graph.Graph.NodeEvent;
|
||||||
import org.graalvm.compiler.graph.Graph.NodeEventScope;
|
import org.graalvm.compiler.graph.Graph.NodeEventScope;
|
||||||
@ -32,8 +34,6 @@ import org.graalvm.compiler.phases.BasePhase;
|
|||||||
import org.graalvm.compiler.phases.PhaseSuite;
|
import org.graalvm.compiler.phases.PhaseSuite;
|
||||||
import org.graalvm.compiler.phases.common.util.HashSetNodeEventListener;
|
import org.graalvm.compiler.phases.common.util.HashSetNodeEventListener;
|
||||||
import org.graalvm.compiler.phases.tiers.PhaseContext;
|
import org.graalvm.compiler.phases.tiers.PhaseContext;
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A utility phase for detecting when a phase would change the graph and reporting extra information
|
* A utility phase for detecting when a phase would change the graph and reporting extra information
|
||||||
|
@ -24,6 +24,7 @@ package org.graalvm.compiler.core.target;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicSet;
|
||||||
import org.graalvm.compiler.asm.Assembler;
|
import org.graalvm.compiler.asm.Assembler;
|
||||||
import org.graalvm.compiler.code.CompilationResult;
|
import org.graalvm.compiler.code.CompilationResult;
|
||||||
import org.graalvm.compiler.core.common.CompilationIdentifier;
|
import org.graalvm.compiler.core.common.CompilationIdentifier;
|
||||||
@ -44,7 +45,6 @@ import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
|||||||
import org.graalvm.compiler.phases.tiers.SuitesProvider;
|
import org.graalvm.compiler.phases.tiers.SuitesProvider;
|
||||||
import org.graalvm.compiler.phases.tiers.TargetProvider;
|
import org.graalvm.compiler.phases.tiers.TargetProvider;
|
||||||
import org.graalvm.compiler.phases.util.Providers;
|
import org.graalvm.compiler.phases.util.Providers;
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
|
|
||||||
import jdk.vm.ci.code.BailoutException;
|
import jdk.vm.ci.code.BailoutException;
|
||||||
import jdk.vm.ci.code.CodeCacheProvider;
|
import jdk.vm.ci.code.CodeCacheProvider;
|
||||||
@ -204,31 +204,48 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
|
|||||||
}
|
}
|
||||||
try (DebugContext.Scope s2 = debug.scope("CodeInstall", debugContext);
|
try (DebugContext.Scope s2 = debug.scope("CodeInstall", debugContext);
|
||||||
DebugContext.Activation a = debug.activate()) {
|
DebugContext.Activation a = debug.activate()) {
|
||||||
for (CodeInstallationTask task : tasks) {
|
preCodeInstallationTasks(tasks, compilationResult);
|
||||||
task.preProcess(compilationResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
|
InstalledCode installedCode;
|
||||||
InstalledCode installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
|
|
||||||
|
|
||||||
// Run post-code installation tasks.
|
|
||||||
try {
|
try {
|
||||||
for (CodeInstallationTask task : tasks) {
|
CompiledCode compiledCode = createCompiledCode(method, compilationRequest, compilationResult);
|
||||||
task.postProcess(installedCode);
|
installedCode = getProviders().getCodeCache().installCode(method, compiledCode, predefinedInstalledCode, speculationLog, isDefault);
|
||||||
}
|
|
||||||
for (CodeInstallationTask task : tasks) {
|
|
||||||
task.releaseInstallation(installedCode);
|
|
||||||
}
|
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
installedCode.invalidate();
|
failCodeInstallationTasks(tasks, t);
|
||||||
throw t;
|
throw t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postCodeInstallationTasks(tasks, installedCode);
|
||||||
|
|
||||||
return installedCode;
|
return installedCode;
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw debug.handle(e);
|
throw debug.handle(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void failCodeInstallationTasks(CodeInstallationTask[] tasks, Throwable t) {
|
||||||
|
for (CodeInstallationTask task : tasks) {
|
||||||
|
task.installFailed(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void preCodeInstallationTasks(CodeInstallationTask[] tasks, CompilationResult compilationResult) {
|
||||||
|
for (CodeInstallationTask task : tasks) {
|
||||||
|
task.preProcess(compilationResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void postCodeInstallationTasks(CodeInstallationTask[] tasks, InstalledCode installedCode) {
|
||||||
|
try {
|
||||||
|
for (CodeInstallationTask task : tasks) {
|
||||||
|
task.postProcess(installedCode);
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
installedCode.invalidate();
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Installs code based on a given compilation result.
|
* Installs code based on a given compilation result.
|
||||||
*
|
*
|
||||||
@ -301,11 +318,10 @@ public abstract class Backend implements TargetProvider, ValueKindFactory<LIRKin
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Task to run after all the post-code installation tasks are complete, used to release the
|
* Invoked after {@link #preProcess} when code installation fails.
|
||||||
* installed code.
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public void releaseInstallation(InstalledCode installedCode) {
|
public void installFailed(Throwable t) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ import java.util.Collections;
|
|||||||
import java.util.Formatter;
|
import java.util.Formatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.debug.Assertions;
|
import org.graalvm.compiler.debug.Assertions;
|
||||||
import org.graalvm.compiler.debug.CounterKey;
|
import org.graalvm.compiler.debug.CounterKey;
|
||||||
import org.graalvm.compiler.debug.DebugCloseable;
|
import org.graalvm.compiler.debug.DebugCloseable;
|
||||||
@ -46,7 +47,6 @@ import org.graalvm.compiler.debug.DebugOptions;
|
|||||||
import org.graalvm.compiler.debug.DebugVerifyHandler;
|
import org.graalvm.compiler.debug.DebugVerifyHandler;
|
||||||
import org.graalvm.compiler.options.OptionKey;
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -30,6 +30,7 @@ import static org.junit.Assert.assertEquals;
|
|||||||
|
|
||||||
import java.lang.management.ThreadMXBean;
|
import java.lang.management.ThreadMXBean;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.debug.DebugCloseable;
|
import org.graalvm.compiler.debug.DebugCloseable;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.debug.DebugOptions;
|
import org.graalvm.compiler.debug.DebugOptions;
|
||||||
@ -37,7 +38,6 @@ import org.graalvm.compiler.debug.Management;
|
|||||||
import org.graalvm.compiler.debug.TimerKey;
|
import org.graalvm.compiler.debug.TimerKey;
|
||||||
import org.graalvm.compiler.options.OptionKey;
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.graalvm.compiler.debug;
|
package org.graalvm.compiler.debug;
|
||||||
|
|
||||||
import org.graalvm.util.Pair;
|
import org.graalvm.collections.Pair;
|
||||||
|
|
||||||
class CounterKeyImpl extends AbstractKey implements CounterKey {
|
class CounterKeyImpl extends AbstractKey implements CounterKey {
|
||||||
|
|
||||||
|
@ -56,12 +56,12 @@ import java.util.Map;
|
|||||||
import java.util.SortedMap;
|
import java.util.SortedMap;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.EconomicSet;
|
||||||
|
import org.graalvm.collections.Pair;
|
||||||
import org.graalvm.compiler.options.OptionKey;
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.graphio.GraphOutput;
|
import org.graalvm.graphio.GraphOutput;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
import org.graalvm.util.Pair;
|
|
||||||
|
|
||||||
import jdk.vm.ci.meta.JavaMethod;
|
import jdk.vm.ci.meta.JavaMethod;
|
||||||
|
|
||||||
@ -1937,10 +1937,17 @@ public final class DebugContext implements AutoCloseable {
|
|||||||
if (description != null) {
|
if (description != null) {
|
||||||
printMetrics(description);
|
printMetrics(description);
|
||||||
}
|
}
|
||||||
if (metricsEnabled && globalMetrics != null && metricValues != null) {
|
if (metricsEnabled && metricValues != null && globalMetrics != null) {
|
||||||
globalMetrics.add(this);
|
globalMetrics.add(this);
|
||||||
}
|
}
|
||||||
metricValues = null;
|
metricValues = null;
|
||||||
|
if (sharedChannel != null) {
|
||||||
|
try {
|
||||||
|
sharedChannel.realClose();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
// ignore.
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void closeDumpHandlers(boolean ignoreErrors) {
|
public void closeDumpHandlers(boolean ignoreErrors) {
|
||||||
@ -2022,7 +2029,6 @@ public final class DebugContext implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,11 +27,11 @@ import java.nio.file.Files;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.options.Option;
|
import org.graalvm.compiler.options.Option;
|
||||||
import org.graalvm.compiler.options.OptionKey;
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
import org.graalvm.compiler.options.OptionType;
|
import org.graalvm.compiler.options.OptionType;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Options that configure a {@link DebugContext} and related functionality.
|
* Options that configure a {@link DebugContext} and related functionality.
|
||||||
|
@ -29,10 +29,10 @@ import java.nio.file.Paths;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.MapCursor;
|
||||||
|
import org.graalvm.collections.Pair;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.MapCursor;
|
|
||||||
import org.graalvm.util.Pair;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metric values that can be {@linkplain #add(DebugContext) updated} by multiple threads.
|
* Metric values that can be {@linkplain #add(DebugContext) updated} by multiple threads.
|
||||||
|
@ -25,7 +25,7 @@ package org.graalvm.compiler.debug;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.graalvm.util.EconomicMap;
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registry for allocating a globally unique integer id to each {@link AbstractKey}.
|
* Registry for allocating a globally unique integer id to each {@link AbstractKey}.
|
||||||
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.debug;
|
|||||||
|
|
||||||
import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
|
import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
|
||||||
|
|
||||||
import org.graalvm.util.Pair;
|
import org.graalvm.collections.Pair;
|
||||||
|
|
||||||
class MemUseTrackerKeyImpl extends AccumulatedKey implements MemUseTrackerKey {
|
class MemUseTrackerKeyImpl extends AccumulatedKey implements MemUseTrackerKey {
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.debug;
|
|||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
import org.graalvm.util.Pair;
|
import org.graalvm.collections.Pair;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A key for a metric.
|
* A key for a metric.
|
||||||
|
@ -26,7 +26,7 @@ import static org.graalvm.compiler.debug.DebugCloseable.VOID_CLOSEABLE;
|
|||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.graalvm.util.Pair;
|
import org.graalvm.collections.Pair;
|
||||||
|
|
||||||
final class TimerKeyImpl extends AccumulatedKey implements TimerKey {
|
final class TimerKeyImpl extends AccumulatedKey implements TimerKey {
|
||||||
static class FlatTimer extends AbstractKey implements TimerKey {
|
static class FlatTimer extends AbstractKey implements TimerKey {
|
||||||
|
@ -24,7 +24,7 @@ package org.graalvm.compiler.graph;
|
|||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import org.graalvm.util.UnmodifiableEconomicMap;
|
import org.graalvm.collections.UnmodifiableEconomicMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a container of a graph that needs to be readonly and optionally a lazily created
|
* This class is a container of a graph that needs to be readonly and optionally a lazily created
|
||||||
|
@ -30,6 +30,9 @@ import java.util.Arrays;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.Equivalence;
|
||||||
|
import org.graalvm.collections.UnmodifiableEconomicMap;
|
||||||
import org.graalvm.compiler.debug.CounterKey;
|
import org.graalvm.compiler.debug.CounterKey;
|
||||||
import org.graalvm.compiler.debug.DebugCloseable;
|
import org.graalvm.compiler.debug.DebugCloseable;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
@ -41,9 +44,6 @@ import org.graalvm.compiler.options.Option;
|
|||||||
import org.graalvm.compiler.options.OptionKey;
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
import org.graalvm.compiler.options.OptionType;
|
import org.graalvm.compiler.options.OptionType;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
import org.graalvm.util.UnmodifiableEconomicMap;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a graph container, it contains the set of nodes that belong to this graph.
|
* This class is a graph container, it contains the set of nodes that belong to this graph.
|
||||||
|
@ -160,6 +160,12 @@ public final class NodeBitMap extends NodeIdAccessor implements NodeIterable<Nod
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void invert() {
|
||||||
|
for (int i = 0; i < bits.length; i++) {
|
||||||
|
bits[i] = ~bits[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void grow() {
|
public void grow() {
|
||||||
nodeCount = Math.max(nodeCount, graph().nodeIdCount());
|
nodeCount = Math.max(nodeCount, graph().nodeIdCount());
|
||||||
int newLength = sizeForNodeCount(nodeCount);
|
int newLength = sizeForNodeCount(nodeCount);
|
||||||
|
@ -42,6 +42,8 @@ import java.util.NoSuchElementException;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.Equivalence;
|
||||||
import org.graalvm.compiler.core.common.FieldIntrospection;
|
import org.graalvm.compiler.core.common.FieldIntrospection;
|
||||||
import org.graalvm.compiler.core.common.Fields;
|
import org.graalvm.compiler.core.common.Fields;
|
||||||
import org.graalvm.compiler.core.common.FieldsScanner;
|
import org.graalvm.compiler.core.common.FieldsScanner;
|
||||||
@ -65,8 +67,6 @@ import org.graalvm.compiler.nodeinfo.NodeCycles;
|
|||||||
import org.graalvm.compiler.nodeinfo.NodeInfo;
|
import org.graalvm.compiler.nodeinfo.NodeInfo;
|
||||||
import org.graalvm.compiler.nodeinfo.NodeSize;
|
import org.graalvm.compiler.nodeinfo.NodeSize;
|
||||||
import org.graalvm.compiler.nodeinfo.Verbosity;
|
import org.graalvm.compiler.nodeinfo.Verbosity;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata for every {@link Node} type. The metadata includes:
|
* Metadata for every {@link Node} type. The metadata includes:
|
||||||
|
@ -26,8 +26,8 @@ import java.util.Arrays;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import org.graalvm.util.EconomicMap;
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.util.MapCursor;
|
import org.graalvm.collections.MapCursor;
|
||||||
|
|
||||||
public class NodeMap<T> extends NodeIdAccessor implements EconomicMap<Node, T> {
|
public class NodeMap<T> extends NodeIdAccessor implements EconomicMap<Node, T> {
|
||||||
|
|
||||||
|
@ -74,6 +74,10 @@ public final class NodeStack {
|
|||||||
return tos == 0;
|
return tos == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
tos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (tos == 0) {
|
if (tos == 0) {
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.graalvm.compiler.hotspot.aarch64;
|
package org.graalvm.compiler.hotspot.aarch64;
|
||||||
|
|
||||||
import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
|
|
||||||
import static java.lang.reflect.Modifier.isStatic;
|
import static java.lang.reflect.Modifier.isStatic;
|
||||||
import static jdk.vm.ci.aarch64.AArch64.lr;
|
import static jdk.vm.ci.aarch64.AArch64.lr;
|
||||||
import static jdk.vm.ci.aarch64.AArch64.r10;
|
import static jdk.vm.ci.aarch64.AArch64.r10;
|
||||||
@ -30,7 +29,9 @@ import static jdk.vm.ci.aarch64.AArch64.sp;
|
|||||||
import static jdk.vm.ci.aarch64.AArch64.zr;
|
import static jdk.vm.ci.aarch64.AArch64.zr;
|
||||||
import static jdk.vm.ci.code.ValueUtil.asRegister;
|
import static jdk.vm.ci.code.ValueUtil.asRegister;
|
||||||
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp;
|
import static jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig.fp;
|
||||||
|
import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicSet;
|
||||||
import org.graalvm.compiler.asm.Assembler;
|
import org.graalvm.compiler.asm.Assembler;
|
||||||
import org.graalvm.compiler.asm.Label;
|
import org.graalvm.compiler.asm.Label;
|
||||||
import org.graalvm.compiler.asm.aarch64.AArch64Address;
|
import org.graalvm.compiler.asm.aarch64.AArch64Address;
|
||||||
@ -42,11 +43,11 @@ import org.graalvm.compiler.core.aarch64.AArch64NodeMatchRules;
|
|||||||
import org.graalvm.compiler.core.common.CompilationIdentifier;
|
import org.graalvm.compiler.core.common.CompilationIdentifier;
|
||||||
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
|
import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig;
|
||||||
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
|
import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
|
||||||
|
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotDataBuilder;
|
import org.graalvm.compiler.hotspot.HotSpotDataBuilder;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
|
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotHostBackend;
|
import org.graalvm.compiler.hotspot.HotSpotHostBackend;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
|
import org.graalvm.compiler.hotspot.HotSpotLIRGenerationResult;
|
||||||
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
|
||||||
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
|
import org.graalvm.compiler.hotspot.meta.HotSpotForeignCallsProvider;
|
||||||
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
|
import org.graalvm.compiler.hotspot.meta.HotSpotProviders;
|
||||||
import org.graalvm.compiler.hotspot.stubs.Stub;
|
import org.graalvm.compiler.hotspot.stubs.Stub;
|
||||||
@ -64,7 +65,6 @@ import org.graalvm.compiler.lir.gen.LIRGenerationResult;
|
|||||||
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
|
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
|
|
||||||
import jdk.vm.ci.code.CallingConvention;
|
import jdk.vm.ci.code.CallingConvention;
|
||||||
import jdk.vm.ci.code.Register;
|
import jdk.vm.ci.code.Register;
|
||||||
|
@ -49,6 +49,7 @@ import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider;
|
|||||||
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
|
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
|
||||||
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
|
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
|
||||||
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
|
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
|
||||||
|
import org.graalvm.compiler.nodes.spi.LoweringProvider;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
|
import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
|
||||||
import org.graalvm.compiler.phases.util.Providers;
|
import org.graalvm.compiler.phases.util.Providers;
|
||||||
@ -136,7 +137,7 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
|
|||||||
replacements = createReplacements(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider);
|
replacements = createReplacements(graalRuntime.getOptions(), p, snippetReflection, bytecodeProvider);
|
||||||
}
|
}
|
||||||
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
|
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
|
||||||
plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes, stampProvider);
|
plugins = createGraphBuilderPlugins(compilerConfiguration, config, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes, stampProvider);
|
||||||
replacements.setGraphBuilderPlugins(plugins);
|
replacements.setGraphBuilderPlugins(plugins);
|
||||||
}
|
}
|
||||||
try (InitTimer rt = timer("create Suites provider")) {
|
try (InitTimer rt = timer("create Suites provider")) {
|
||||||
@ -152,9 +153,10 @@ public class AArch64HotSpotBackendFactory implements HotSpotBackendFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection,
|
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotConstantReflectionProvider constantReflection,
|
||||||
HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements,
|
HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess, HotSpotSnippetReflectionProvider snippetReflection,
|
||||||
HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
|
HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
|
||||||
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements);
|
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
|
||||||
|
replacements);
|
||||||
AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider());
|
AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider());
|
||||||
return plugins;
|
return plugins;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
package org.graalvm.compiler.hotspot.amd64;
|
||||||
|
|
||||||
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
|
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
|
||||||
import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
|
|
||||||
import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
|
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
|
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
|
||||||
import org.graalvm.compiler.core.amd64.AMD64AddressLowering;
|
|
||||||
import org.graalvm.compiler.core.amd64.AMD64AddressNode;
|
import org.graalvm.compiler.core.amd64.AMD64AddressNode;
|
||||||
|
import org.graalvm.compiler.core.amd64.AMD64CompressAddressLowering;
|
||||||
import org.graalvm.compiler.core.common.CompressEncoding;
|
import org.graalvm.compiler.core.common.CompressEncoding;
|
||||||
import org.graalvm.compiler.core.common.LIRKind;
|
import org.graalvm.compiler.core.common.type.IntegerStamp;
|
||||||
import org.graalvm.compiler.core.common.type.ObjectStamp;
|
import org.graalvm.compiler.core.common.type.ObjectStamp;
|
||||||
import org.graalvm.compiler.core.common.type.StampFactory;
|
import org.graalvm.compiler.graph.Node;
|
||||||
import org.graalvm.compiler.debug.CounterKey;
|
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
|
||||||
import org.graalvm.compiler.graph.NodeClass;
|
|
||||||
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
||||||
import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
|
import org.graalvm.compiler.hotspot.nodes.GraalHotSpotVMConfigNode;
|
||||||
import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
|
import org.graalvm.compiler.hotspot.nodes.type.KlassPointerStamp;
|
||||||
import org.graalvm.compiler.nodeinfo.NodeInfo;
|
import org.graalvm.compiler.loop.BasicInductionVariable;
|
||||||
|
import org.graalvm.compiler.loop.CountedLoopInfo;
|
||||||
|
import org.graalvm.compiler.loop.DerivedInductionVariable;
|
||||||
|
import org.graalvm.compiler.loop.InductionVariable;
|
||||||
|
import org.graalvm.compiler.loop.LoopEx;
|
||||||
|
import org.graalvm.compiler.loop.LoopsData;
|
||||||
import org.graalvm.compiler.nodes.CompressionNode;
|
import org.graalvm.compiler.nodes.CompressionNode;
|
||||||
import org.graalvm.compiler.nodes.CompressionNode.CompressionOp;
|
import org.graalvm.compiler.nodes.ConstantNode;
|
||||||
import org.graalvm.compiler.nodes.NodeView;
|
import org.graalvm.compiler.nodes.NodeView;
|
||||||
|
import org.graalvm.compiler.nodes.PhiNode;
|
||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.ValueNode;
|
import org.graalvm.compiler.nodes.ValueNode;
|
||||||
import org.graalvm.compiler.nodes.calc.FloatingNode;
|
import org.graalvm.compiler.nodes.calc.AddNode;
|
||||||
import org.graalvm.compiler.nodes.spi.LIRLowerable;
|
import org.graalvm.compiler.nodes.calc.SignExtendNode;
|
||||||
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
import org.graalvm.compiler.nodes.calc.ZeroExtendNode;
|
||||||
|
import org.graalvm.compiler.nodes.memory.address.AddressNode;
|
||||||
|
import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
|
|
||||||
import jdk.vm.ci.code.Register;
|
import jdk.vm.ci.code.Register;
|
||||||
import jdk.vm.ci.meta.JavaKind;
|
import jdk.vm.ci.meta.JavaKind;
|
||||||
|
|
||||||
public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
|
public class AMD64HotSpotAddressLowering extends AMD64CompressAddressLowering {
|
||||||
|
|
||||||
private static final CounterKey counterFoldedUncompressDuringAddressLowering = DebugContext.counter("FoldedUncompressDuringAddressLowering");
|
private static final int ADDRESS_BITS = 64;
|
||||||
|
private static final int INT_BITS = 32;
|
||||||
|
|
||||||
private final long heapBase;
|
private final long heapBase;
|
||||||
private final Register heapBaseRegister;
|
private final Register heapBaseRegister;
|
||||||
private final GraalHotSpotVMConfig config;
|
private final GraalHotSpotVMConfig config;
|
||||||
private final boolean generatePIC;
|
private final boolean generatePIC;
|
||||||
|
|
||||||
@NodeInfo(cycles = CYCLES_0, size = SIZE_0)
|
|
||||||
public static class HeapBaseNode extends FloatingNode implements LIRLowerable {
|
|
||||||
|
|
||||||
public static final NodeClass<HeapBaseNode> TYPE = NodeClass.create(HeapBaseNode.class);
|
|
||||||
|
|
||||||
private final Register heapBaseRegister;
|
|
||||||
|
|
||||||
public HeapBaseNode(Register heapBaseRegister) {
|
|
||||||
super(TYPE, StampFactory.pointer());
|
|
||||||
this.heapBaseRegister = heapBaseRegister;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void generate(NodeLIRBuilderTool generator) {
|
|
||||||
LIRKind kind = generator.getLIRGeneratorTool().getLIRKind(stamp(NodeView.DEFAULT));
|
|
||||||
generator.setResult(this, heapBaseRegister.asValue(kind));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AMD64HotSpotAddressLowering(GraalHotSpotVMConfig config, Register heapBaseRegister, OptionValues options) {
|
public AMD64HotSpotAddressLowering(GraalHotSpotVMConfig config, Register heapBaseRegister, OptionValues options) {
|
||||||
this.heapBase = config.getOopEncoding().getBase();
|
this.heapBase = config.getOopEncoding().getBase();
|
||||||
this.config = config;
|
this.config = config;
|
||||||
@ -94,35 +80,7 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean improve(StructuredGraph graph, DebugContext debug, AMD64AddressNode addr, boolean isBaseNegated, boolean isIndexNegated) {
|
protected final boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other) {
|
||||||
if (super.improve(graph, debug, addr, isBaseNegated, isIndexNegated)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr.getScale() == Scale.Times1) {
|
|
||||||
if (addr.getIndex() instanceof CompressionNode) {
|
|
||||||
if (improveUncompression(addr, (CompressionNode) addr.getIndex(), addr.getBase(), isBaseNegated, isIndexNegated)) {
|
|
||||||
counterFoldedUncompressDuringAddressLowering.increment(debug);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr.getBase() instanceof CompressionNode) {
|
|
||||||
if (improveUncompression(addr, (CompressionNode) addr.getBase(), addr.getIndex(), isBaseNegated, isIndexNegated)) {
|
|
||||||
counterFoldedUncompressDuringAddressLowering.increment(debug);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean improveUncompression(AMD64AddressNode addr, CompressionNode compression, ValueNode other, boolean isBaseNegated, boolean isIndexNegated) {
|
|
||||||
if (isBaseNegated || isIndexNegated || compression.getOp() != CompressionOp.Uncompress) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
CompressEncoding encoding = compression.getEncoding();
|
CompressEncoding encoding = compression.getEncoding();
|
||||||
Scale scale = Scale.fromShift(encoding.getShift());
|
Scale scale = Scale.fromShift(encoding.getShift());
|
||||||
if (scale == null) {
|
if (scale == null) {
|
||||||
@ -147,7 +105,7 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (updateDisplacement(addr, encoding.getBase(), isBaseNegated)) {
|
if (updateDisplacement(addr, encoding.getBase(), false)) {
|
||||||
addr.setBase(other);
|
addr.setBase(other);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@ -161,4 +119,117 @@ public class AMD64HotSpotAddressLowering extends AMD64AddressLowering {
|
|||||||
addr.setIndex(compression.getValue());
|
addr.setIndex(compression.getValue());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void preProcess(StructuredGraph graph) {
|
||||||
|
if (graph.hasLoops()) {
|
||||||
|
LoopsData loopsData = new LoopsData(graph);
|
||||||
|
loopsData.detectedCountedLoops();
|
||||||
|
for (LoopEx loop : loopsData.countedLoops()) {
|
||||||
|
for (OffsetAddressNode offsetAdressNode : loop.whole().nodes().filter(OffsetAddressNode.class)) {
|
||||||
|
tryOptimize(offsetAdressNode, loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postProcess(AddressNode lowered) {
|
||||||
|
// Allow implicit zero extend for always positive input. This
|
||||||
|
// assumes that the upper bits of the operand is zero out by
|
||||||
|
// the backend.
|
||||||
|
AMD64AddressNode address = (AMD64AddressNode) lowered;
|
||||||
|
address.setBase(tryImplicitZeroExtend(address.getBase()));
|
||||||
|
address.setIndex(tryImplicitZeroExtend(address.getIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void tryOptimize(OffsetAddressNode offsetAddress, LoopEx loop) {
|
||||||
|
EconomicMap<Node, InductionVariable> ivs = loop.getInductionVariables();
|
||||||
|
InductionVariable currentIV = ivs.get(offsetAddress.getOffset());
|
||||||
|
while (currentIV != null) {
|
||||||
|
if (!(currentIV instanceof DerivedInductionVariable)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ValueNode currentValue = currentIV.valueNode();
|
||||||
|
if (currentValue.isDeleted()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentValue instanceof ZeroExtendNode) {
|
||||||
|
ZeroExtendNode zeroExtendNode = (ZeroExtendNode) currentValue;
|
||||||
|
if (applicableToImplicitZeroExtend(zeroExtendNode)) {
|
||||||
|
ValueNode input = zeroExtendNode.getValue();
|
||||||
|
if (input instanceof AddNode) {
|
||||||
|
AddNode add = (AddNode) input;
|
||||||
|
if (add.getX().isConstant()) {
|
||||||
|
optimizeAdd(zeroExtendNode, (ConstantNode) add.getX(), add.getY(), loop);
|
||||||
|
} else if (add.getY().isConstant()) {
|
||||||
|
optimizeAdd(zeroExtendNode, (ConstantNode) add.getY(), add.getX(), loop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIV = ((DerivedInductionVariable) currentIV).getBase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given that Add(a, cst) is always positive, performs the following: ZeroExtend(Add(a, cst)) ->
|
||||||
|
* Add(SignExtend(a), SignExtend(cst)).
|
||||||
|
*/
|
||||||
|
private static void optimizeAdd(ZeroExtendNode zeroExtendNode, ConstantNode constant, ValueNode other, LoopEx loop) {
|
||||||
|
StructuredGraph graph = zeroExtendNode.graph();
|
||||||
|
AddNode addNode = graph.unique(new AddNode(signExtend(other, loop), ConstantNode.forLong(constant.asJavaConstant().asInt(), graph)));
|
||||||
|
zeroExtendNode.replaceAtUsages(addNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a sign extend for {@code input}, or zero extend if {@code input} can be proven
|
||||||
|
* positive.
|
||||||
|
*/
|
||||||
|
private static ValueNode signExtend(ValueNode input, LoopEx loop) {
|
||||||
|
StructuredGraph graph = input.graph();
|
||||||
|
if (input instanceof PhiNode) {
|
||||||
|
EconomicMap<Node, InductionVariable> ivs = loop.getInductionVariables();
|
||||||
|
InductionVariable inductionVariable = ivs.get(input);
|
||||||
|
if (inductionVariable != null && inductionVariable instanceof BasicInductionVariable) {
|
||||||
|
CountedLoopInfo countedLoopInfo = loop.counted();
|
||||||
|
IntegerStamp initStamp = (IntegerStamp) inductionVariable.initNode().stamp(NodeView.DEFAULT);
|
||||||
|
if (initStamp.isPositive()) {
|
||||||
|
if (inductionVariable.isConstantExtremum()) {
|
||||||
|
long init = inductionVariable.constantInit();
|
||||||
|
long stride = inductionVariable.constantStride();
|
||||||
|
long extremum = inductionVariable.constantExtremum();
|
||||||
|
|
||||||
|
if (init >= 0 && extremum >= 0) {
|
||||||
|
long shortestTrip = (extremum - init) / stride + 1;
|
||||||
|
if (shortestTrip == countedLoopInfo.constantMaxTripCount()) {
|
||||||
|
return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (countedLoopInfo.getCounter() == inductionVariable && inductionVariable.direction() == InductionVariable.Direction.Up && countedLoopInfo.getOverFlowGuard() != null) {
|
||||||
|
return graph.unique(new ZeroExtendNode(input, INT_BITS, ADDRESS_BITS, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return input.graph().maybeAddOrUnique(SignExtendNode.create(input, ADDRESS_BITS, NodeView.DEFAULT));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean applicableToImplicitZeroExtend(ZeroExtendNode zeroExtendNode) {
|
||||||
|
return zeroExtendNode.isInputAlwaysPositive() && zeroExtendNode.getInputBits() == INT_BITS && zeroExtendNode.getResultBits() == ADDRESS_BITS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ValueNode tryImplicitZeroExtend(ValueNode input) {
|
||||||
|
if (input instanceof ZeroExtendNode) {
|
||||||
|
ZeroExtendNode zeroExtendNode = (ZeroExtendNode) input;
|
||||||
|
if (applicableToImplicitZeroExtend(zeroExtendNode)) {
|
||||||
|
return zeroExtendNode.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import static org.graalvm.compiler.core.common.GraalOptions.CanOmitFrame;
|
|||||||
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
|
import static org.graalvm.compiler.core.common.GraalOptions.GeneratePIC;
|
||||||
import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
|
import static org.graalvm.compiler.core.common.GraalOptions.ZapStackOnMethodEntry;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicSet;
|
||||||
import org.graalvm.compiler.asm.Assembler;
|
import org.graalvm.compiler.asm.Assembler;
|
||||||
import org.graalvm.compiler.asm.Label;
|
import org.graalvm.compiler.asm.Label;
|
||||||
import org.graalvm.compiler.asm.amd64.AMD64Address;
|
import org.graalvm.compiler.asm.amd64.AMD64Address;
|
||||||
@ -66,7 +67,6 @@ import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
|
|||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
|
|
||||||
import jdk.vm.ci.amd64.AMD64;
|
import jdk.vm.ci.amd64.AMD64;
|
||||||
import jdk.vm.ci.amd64.AMD64Kind;
|
import jdk.vm.ci.amd64.AMD64Kind;
|
||||||
|
@ -49,6 +49,7 @@ import org.graalvm.compiler.hotspot.meta.HotSpotStampProvider;
|
|||||||
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
|
import org.graalvm.compiler.hotspot.meta.HotSpotSuitesProvider;
|
||||||
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
|
import org.graalvm.compiler.hotspot.word.HotSpotWordTypes;
|
||||||
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
|
import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins;
|
||||||
|
import org.graalvm.compiler.nodes.spi.LoweringProvider;
|
||||||
import org.graalvm.compiler.nodes.spi.Replacements;
|
import org.graalvm.compiler.nodes.spi.Replacements;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
|
import org.graalvm.compiler.phases.tiers.CompilerConfiguration;
|
||||||
@ -137,7 +138,7 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
|
|||||||
replacements = createReplacements(options, p, snippetReflection, bytecodeProvider);
|
replacements = createReplacements(options, p, snippetReflection, bytecodeProvider);
|
||||||
}
|
}
|
||||||
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
|
try (InitTimer rt = timer("create GraphBuilderPhase plugins")) {
|
||||||
plugins = createGraphBuilderPlugins(compilerConfiguration, config, options, target, constantReflection, foreignCalls, metaAccess, snippetReflection, replacements, wordTypes,
|
plugins = createGraphBuilderPlugins(compilerConfiguration, config, options, target, constantReflection, foreignCalls, lowerer, metaAccess, snippetReflection, replacements, wordTypes,
|
||||||
stampProvider);
|
stampProvider);
|
||||||
replacements.setGraphBuilderPlugins(plugins);
|
replacements.setGraphBuilderPlugins(plugins);
|
||||||
}
|
}
|
||||||
@ -154,9 +155,10 @@ public class AMD64HotSpotBackendFactory implements HotSpotBackendFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, OptionValues options, TargetDescription target,
|
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, OptionValues options, TargetDescription target,
|
||||||
HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, HotSpotMetaAccessProvider metaAccess,
|
HotSpotConstantReflectionProvider constantReflection, HotSpotHostForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotMetaAccessProvider metaAccess,
|
||||||
HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
|
HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes, HotSpotStampProvider stampProvider) {
|
||||||
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements);
|
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
|
||||||
|
replacements);
|
||||||
AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, GraalArithmeticStubs.getValue(options));
|
AMD64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), (AMD64) target.arch, GraalArithmeticStubs.getValue(options));
|
||||||
return plugins;
|
return plugins;
|
||||||
}
|
}
|
||||||
|
@ -572,7 +572,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
|
|||||||
if (inputKind.isReference(0)) {
|
if (inputKind.isReference(0)) {
|
||||||
// oop
|
// oop
|
||||||
Variable result = newVariable(lirKindTool.getNarrowOopKind());
|
Variable result = newVariable(lirKindTool.getNarrowOopKind());
|
||||||
append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, getLIRKindTool()));
|
append(new AMD64Move.CompressPointerOp(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, getLIRKindTool()));
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
// metaspace pointer
|
// metaspace pointer
|
||||||
@ -589,7 +589,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
|
|||||||
base = emitLoadConstant(lirKindTool.getWordKind(), JavaConstant.forLong(encoding.getBase()));
|
base = emitLoadConstant(lirKindTool.getWordKind(), JavaConstant.forLong(encoding.getBase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
append(new AMD64Move.CompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, getLIRKindTool()));
|
append(new AMD64Move.CompressPointerOp(result, asAllocatable(pointer), base, encoding, nonNull, getLIRKindTool()));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -602,7 +602,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
|
|||||||
if (inputKind.isReference(0)) {
|
if (inputKind.isReference(0)) {
|
||||||
// oop
|
// oop
|
||||||
Variable result = newVariable(lirKindTool.getObjectKind());
|
Variable result = newVariable(lirKindTool.getObjectKind());
|
||||||
append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, lirKindTool));
|
append(new AMD64Move.UncompressPointerOp(result, asAllocatable(pointer), getProviders().getRegisters().getHeapBaseRegister().asValue(), encoding, nonNull, lirKindTool));
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
// metaspace pointer
|
// metaspace pointer
|
||||||
@ -620,7 +620,7 @@ public class AMD64HotSpotLIRGenerator extends AMD64LIRGenerator implements HotSp
|
|||||||
base = emitLoadConstant(uncompressedKind, JavaConstant.forLong(encoding.getBase()));
|
base = emitLoadConstant(uncompressedKind, JavaConstant.forLong(encoding.getBase()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
append(new AMD64Move.UncompressPointer(result, asAllocatable(pointer), base, encoding, nonNull, lirKindTool));
|
append(new AMD64Move.UncompressPointerOp(result, asAllocatable(pointer), base, encoding, nonNull, lirKindTool));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,8 @@ public class AMD64HotSpotLoweringProvider extends DefaultHotSpotLoweringProvider
|
|||||||
public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, GraalHotSpotVMConfig config) {
|
public void initialize(OptionValues options, Iterable<DebugHandlersFactory> factories, HotSpotProviders providers, GraalHotSpotVMConfig config) {
|
||||||
convertSnippets = new AMD64ConvertSnippets.Templates(options, factories, providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget());
|
convertSnippets = new AMD64ConvertSnippets.Templates(options, factories, providers, providers.getSnippetReflection(), providers.getCodeCache().getTarget());
|
||||||
profileSnippets = ProfileNode.Options.ProbabilisticProfiling.getValue(options)
|
profileSnippets = ProfileNode.Options.ProbabilisticProfiling.getValue(options)
|
||||||
? new ProbabilisticProfileSnippets.Templates(options, factories, providers, providers.getCodeCache().getTarget()) : null;
|
? new ProbabilisticProfileSnippets.Templates(options, factories, providers, providers.getCodeCache().getTarget())
|
||||||
|
: null;
|
||||||
super.initialize(options, factories, providers, config);
|
super.initialize(options, factories, providers, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,6 +60,7 @@ final class AMD64HotspotDirectVirtualCallOp extends DirectCallOp {
|
|||||||
crb.recordMark(invokeKind == InvokeKind.Virtual ? config.MARKID_INVOKEVIRTUAL : config.MARKID_INVOKEINTERFACE);
|
crb.recordMark(invokeKind == InvokeKind.Virtual ? config.MARKID_INVOKEVIRTUAL : config.MARKID_INVOKEINTERFACE);
|
||||||
// This must be emitted exactly like this to ensure it's patchable
|
// This must be emitted exactly like this to ensure it's patchable
|
||||||
masm.movq(AMD64.rax, config.nonOopBits);
|
masm.movq(AMD64.rax, config.nonOopBits);
|
||||||
super.emitCode(crb, masm);
|
int offset = super.emitCall(crb, masm);
|
||||||
|
crb.recordInvokeVirtualOrInterfaceCallOp(offset, getPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,8 @@ final class AMD64IndirectCallOp extends IndirectCallOp {
|
|||||||
crb.recordMark(config.MARKID_INLINE_INVOKE);
|
crb.recordMark(config.MARKID_INLINE_INVOKE);
|
||||||
Register callReg = asRegister(targetAddress);
|
Register callReg = asRegister(targetAddress);
|
||||||
assert !callReg.equals(METHOD);
|
assert !callReg.equals(METHOD);
|
||||||
AMD64Call.indirectCall(crb, masm, callReg, callTarget, state);
|
int pcOffset = AMD64Call.indirectCall(crb, masm, callReg, callTarget, state);
|
||||||
|
crb.recordInlineInvokeCallOp(pcOffset, getPosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -26,15 +26,18 @@ import static org.graalvm.compiler.core.common.GraalOptions.RegisterPressure;
|
|||||||
import static org.graalvm.compiler.core.common.GraalOptions.TraceRA;
|
import static org.graalvm.compiler.core.common.GraalOptions.TraceRA;
|
||||||
import static org.junit.Assume.assumeTrue;
|
import static org.junit.Assume.assumeTrue;
|
||||||
|
|
||||||
|
import org.graalvm.compiler.core.test.backend.AllocatorTest;
|
||||||
|
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
||||||
|
import org.graalvm.compiler.hotspot.HotSpotBackend;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.graalvm.compiler.core.test.backend.AllocatorTest;
|
|
||||||
|
|
||||||
import jdk.vm.ci.sparc.SPARC;
|
import jdk.vm.ci.sparc.SPARC;
|
||||||
|
|
||||||
public class SPARCAllocatorTest extends AllocatorTest {
|
public class SPARCAllocatorTest extends AllocatorTest {
|
||||||
|
|
||||||
|
private final GraalHotSpotVMConfig config = ((HotSpotBackend) getBackend()).getRuntime().getVMConfig();
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void checkSPARC() {
|
public void checkSPARC() {
|
||||||
assumeTrue("skipping SPARC specific test", getTarget().arch instanceof SPARC);
|
assumeTrue("skipping SPARC specific test", getTarget().arch instanceof SPARC);
|
||||||
@ -44,7 +47,7 @@ public class SPARCAllocatorTest extends AllocatorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test1() {
|
public void test1() {
|
||||||
testAllocation("test1snippet", 2, 0, 0);
|
testAllocation("test1snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long test1snippet(long x) {
|
public static long test1snippet(long x) {
|
||||||
@ -53,7 +56,7 @@ public class SPARCAllocatorTest extends AllocatorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test2() {
|
public void test2() {
|
||||||
testAllocation("test2snippet", 2, 0, 0);
|
testAllocation("test2snippet", config.threadLocalHandshakes ? 1 : 2, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long test2snippet(long x) {
|
public static long test2snippet(long x) {
|
||||||
@ -62,7 +65,7 @@ public class SPARCAllocatorTest extends AllocatorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test3() {
|
public void test3() {
|
||||||
testAllocation("test3snippet", 4, 0, 0);
|
testAllocation("test3snippet", config.threadLocalHandshakes ? 3 : 4, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long test3snippet(long x) {
|
public static long test3snippet(long x) {
|
@ -46,6 +46,9 @@ import java.util.HashSet;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.EconomicSet;
|
||||||
|
import org.graalvm.collections.Equivalence;
|
||||||
import org.graalvm.compiler.asm.Assembler;
|
import org.graalvm.compiler.asm.Assembler;
|
||||||
import org.graalvm.compiler.asm.Label;
|
import org.graalvm.compiler.asm.Label;
|
||||||
import org.graalvm.compiler.asm.sparc.SPARCAddress;
|
import org.graalvm.compiler.asm.sparc.SPARCAddress;
|
||||||
@ -92,9 +95,6 @@ import org.graalvm.compiler.lir.sparc.SPARCTailDelayedLIRInstruction;
|
|||||||
import org.graalvm.compiler.nodes.StructuredGraph;
|
import org.graalvm.compiler.nodes.StructuredGraph;
|
||||||
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.EconomicSet;
|
|
||||||
import org.graalvm.util.Equivalence;
|
|
||||||
|
|
||||||
import jdk.vm.ci.code.CallingConvention;
|
import jdk.vm.ci.code.CallingConvention;
|
||||||
import jdk.vm.ci.code.Register;
|
import jdk.vm.ci.code.Register;
|
||||||
|
@ -101,7 +101,7 @@ public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory {
|
|||||||
HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes);
|
HotSpotSnippetReflectionProvider snippetReflection = new HotSpotSnippetReflectionProvider(runtime, constantReflection, wordTypes);
|
||||||
BytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection);
|
BytecodeProvider bytecodeProvider = new ClassfileBytecodeProvider(metaAccess, snippetReflection);
|
||||||
HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(runtime.getOptions(), p, snippetReflection, bytecodeProvider, target);
|
HotSpotReplacementsImpl replacements = new HotSpotReplacementsImpl(runtime.getOptions(), p, snippetReflection, bytecodeProvider, target);
|
||||||
Plugins plugins = createGraphBuilderPlugins(compilerConfiguration, config, metaAccess, constantReflection, foreignCalls, stampProvider, snippetReflection, replacements, wordTypes);
|
Plugins plugins = createGraphBuilderPlugins(compilerConfiguration, config, metaAccess, constantReflection, foreignCalls, lowerer, stampProvider, snippetReflection, replacements, wordTypes);
|
||||||
replacements.setGraphBuilderPlugins(plugins);
|
replacements.setGraphBuilderPlugins(plugins);
|
||||||
HotSpotSuitesProvider suites = createSuites(config, runtime, compilerConfiguration, plugins, replacements);
|
HotSpotSuitesProvider suites = createSuites(config, runtime, compilerConfiguration, plugins, replacements);
|
||||||
HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
|
HotSpotProviders providers = new HotSpotProviders(metaAccess, codeCache, constantReflection, constantFieldProvider, foreignCalls, lowerer, replacements, suites, registers,
|
||||||
@ -112,9 +112,10 @@ public class SPARCHotSpotBackendFactory implements HotSpotBackendFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotMetaAccessProvider metaAccess,
|
protected Plugins createGraphBuilderPlugins(CompilerConfiguration compilerConfiguration, GraalHotSpotVMConfig config, HotSpotMetaAccessProvider metaAccess,
|
||||||
HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, HotSpotStampProvider stampProvider,
|
HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, LoweringProvider lowerer, HotSpotStampProvider stampProvider,
|
||||||
HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) {
|
HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) {
|
||||||
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements);
|
Plugins plugins = HotSpotGraphBuilderPlugins.create(compilerConfiguration, config, wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, lowerer, stampProvider,
|
||||||
|
replacements);
|
||||||
SPARCGraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider());
|
SPARCGraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider());
|
||||||
return plugins;
|
return plugins;
|
||||||
}
|
}
|
||||||
|
@ -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.TreeSet;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.MapCursor;
|
||||||
import org.graalvm.compiler.api.test.Graal;
|
import org.graalvm.compiler.api.test.Graal;
|
||||||
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
|
import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider;
|
||||||
@ -43,8 +45,6 @@ import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding;
|
|||||||
import org.graalvm.compiler.runtime.RuntimeProvider;
|
import org.graalvm.compiler.runtime.RuntimeProvider;
|
||||||
import org.graalvm.compiler.serviceprovider.JDK9Method;
|
import org.graalvm.compiler.serviceprovider.JDK9Method;
|
||||||
import org.graalvm.compiler.test.GraalTest;
|
import org.graalvm.compiler.test.GraalTest;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.MapCursor;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
||||||
@ -416,6 +416,12 @@ public class CheckGraalIntrinsics extends GraalTest {
|
|||||||
"java/lang/StringUTF16.toBytes([CII)[B");
|
"java/lang/StringUTF16.toBytes([CII)[B");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isJDK10OrHigher()) {
|
||||||
|
add(TO_BE_INVESTIGATED,
|
||||||
|
"java/lang/Math.multiplyHigh(JJ)J",
|
||||||
|
"jdk/internal/util/ArraysSupport.vectorizedMismatch(Ljava/lang/Object;JLjava/lang/Object;JII)I");
|
||||||
|
}
|
||||||
|
|
||||||
if (!getHostArchitectureName().equals("amd64")) {
|
if (!getHostArchitectureName().equals("amd64")) {
|
||||||
// Can we implement these on non-AMD64 platforms? C2 seems to.
|
// Can we implement these on non-AMD64 platforms? C2 seems to.
|
||||||
add(TO_BE_INVESTIGATED,
|
add(TO_BE_INVESTIGATED,
|
||||||
@ -539,6 +545,10 @@ public class CheckGraalIntrinsics extends GraalTest {
|
|||||||
return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9;
|
return JDK9Method.JAVA_SPECIFICATION_VERSION >= 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isJDK10OrHigher() {
|
||||||
|
return JDK9Method.JAVA_SPECIFICATION_VERSION >= 10;
|
||||||
|
}
|
||||||
|
|
||||||
private static String getHostArchitectureName() {
|
private static String getHostArchitectureName() {
|
||||||
String arch = System.getProperty("os.arch");
|
String arch = System.getProperty("os.arch");
|
||||||
if (arch.equals("x86_64")) {
|
if (arch.equals("x86_64")) {
|
||||||
|
@ -68,6 +68,8 @@ import java.util.jar.JarEntry;
|
|||||||
import java.util.jar.JarFile;
|
import java.util.jar.JarFile;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
|
import org.graalvm.collections.UnmodifiableEconomicMap;
|
||||||
import org.graalvm.compiler.api.replacements.Snippet;
|
import org.graalvm.compiler.api.replacements.Snippet;
|
||||||
import org.graalvm.compiler.bytecode.Bytecodes;
|
import org.graalvm.compiler.bytecode.Bytecodes;
|
||||||
import org.graalvm.compiler.core.CompilerThreadFactory;
|
import org.graalvm.compiler.core.CompilerThreadFactory;
|
||||||
@ -85,8 +87,6 @@ import org.graalvm.compiler.options.OptionKey;
|
|||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.options.OptionsParser;
|
import org.graalvm.compiler.options.OptionsParser;
|
||||||
import org.graalvm.compiler.serviceprovider.JDK9Method;
|
import org.graalvm.compiler.serviceprovider.JDK9Method;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.util.UnmodifiableEconomicMap;
|
|
||||||
|
|
||||||
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
|
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
|
||||||
import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
|
import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
|
||||||
|
@ -25,12 +25,12 @@ package org.graalvm.compiler.hotspot.test;
|
|||||||
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
|
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
|
||||||
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
|
import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
|
import org.graalvm.compiler.core.CompilationWrapper.ExceptionAction;
|
||||||
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
|
import org.graalvm.compiler.hotspot.HotSpotGraalCompiler;
|
||||||
import org.graalvm.compiler.options.OptionKey;
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
|
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
|
||||||
|
@ -32,6 +32,7 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.api.directives.GraalDirectives;
|
import org.graalvm.compiler.api.directives.GraalDirectives;
|
||||||
import org.graalvm.compiler.core.phases.HighTier;
|
import org.graalvm.compiler.core.phases.HighTier;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
@ -40,13 +41,12 @@ import org.graalvm.compiler.debug.TTY;
|
|||||||
import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase;
|
import org.graalvm.compiler.hotspot.phases.OnStackReplacementPhase;
|
||||||
import org.graalvm.compiler.options.OptionKey;
|
import org.graalvm.compiler.options.OptionKey;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
import jdk.vm.ci.meta.ResolvedJavaMethod;
|
||||||
import org.junit.Assume;
|
|
||||||
import org.junit.BeforeClass;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test on-stack-replacement with locks.
|
* Test on-stack-replacement with locks.
|
||||||
|
@ -31,8 +31,8 @@ import static org.junit.Assert.assertTrue;
|
|||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
import java.lang.management.ManagementFactory;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import javax.management.Attribute;
|
import javax.management.Attribute;
|
||||||
import javax.management.MBeanAttributeInfo;
|
import javax.management.MBeanAttributeInfo;
|
||||||
import javax.management.MBeanInfo;
|
import javax.management.MBeanInfo;
|
||||||
@ -41,11 +41,11 @@ import javax.management.MBeanServer;
|
|||||||
import javax.management.ObjectInstance;
|
import javax.management.ObjectInstance;
|
||||||
import javax.management.ObjectName;
|
import javax.management.ObjectName;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.debug.DebugOptions;
|
import org.graalvm.compiler.debug.DebugOptions;
|
||||||
import org.graalvm.compiler.hotspot.HotSpotGraalMBean;
|
import org.graalvm.compiler.hotspot.HotSpotGraalMBean;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.test.GraalTest;
|
import org.graalvm.compiler.test.GraalTest;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.junit.Assume;
|
import org.junit.Assume;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
@ -23,8 +23,10 @@
|
|||||||
package org.graalvm.compiler.hotspot.test;
|
package org.graalvm.compiler.hotspot.test;
|
||||||
|
|
||||||
import static org.graalvm.compiler.core.common.CompilationIdentifier.INVALID_COMPILATION_ID;
|
import static org.graalvm.compiler.core.common.CompilationIdentifier.INVALID_COMPILATION_ID;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.api.test.Graal;
|
import org.graalvm.compiler.api.test.Graal;
|
||||||
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
import org.graalvm.compiler.core.test.GraalCompilerTest;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
@ -36,10 +38,9 @@ import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plu
|
|||||||
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
|
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin;
|
||||||
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
|
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins;
|
||||||
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding;
|
import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding;
|
||||||
import org.graalvm.compiler.options.OptionValues;
|
|
||||||
import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
|
import org.graalvm.compiler.nodes.graphbuilderconf.MethodSubstitutionPlugin;
|
||||||
|
import org.graalvm.compiler.options.OptionValues;
|
||||||
import org.graalvm.compiler.runtime.RuntimeProvider;
|
import org.graalvm.compiler.runtime.RuntimeProvider;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
|
||||||
|
@ -24,6 +24,7 @@ package org.graalvm.compiler.hotspot.test;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.graalvm.collections.EconomicMap;
|
||||||
import org.graalvm.compiler.debug.DebugCloseable;
|
import org.graalvm.compiler.debug.DebugCloseable;
|
||||||
import org.graalvm.compiler.debug.DebugContext;
|
import org.graalvm.compiler.debug.DebugContext;
|
||||||
import org.graalvm.compiler.debug.DebugContext.Scope;
|
import org.graalvm.compiler.debug.DebugContext.Scope;
|
||||||
@ -58,7 +59,6 @@ import org.graalvm.compiler.phases.graph.ReentrantNodeIterator;
|
|||||||
import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure;
|
import org.graalvm.compiler.phases.graph.ReentrantNodeIterator.NodeIteratorClosure;
|
||||||
import org.graalvm.compiler.phases.tiers.HighTierContext;
|
import org.graalvm.compiler.phases.tiers.HighTierContext;
|
||||||
import org.graalvm.compiler.phases.tiers.MidTierContext;
|
import org.graalvm.compiler.phases.tiers.MidTierContext;
|
||||||
import org.graalvm.util.EconomicMap;
|
|
||||||
import org.graalvm.word.LocationIdentity;
|
import org.graalvm.word.LocationIdentity;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user