8233035: Update JVMCI

Reviewed-by: dlong
This commit is contained in:
Vladimir Kozlov 2019-10-29 15:35:06 -07:00
parent f9f141b6ab
commit 5c506779b2
20 changed files with 417 additions and 85 deletions

View File

@ -171,7 +171,9 @@ suite = {
"subDir" : "../../test/hotspot/jtreg/compiler/jvmci",
"sourceDirs" : ["src"],
"dependencies" : [
"mx:JUNIT",
"TESTNG",
"jdk.vm.ci.code.test",
"jdk.vm.ci.hotspot",
],
"checkstyle" : "jdk.vm.ci.services",

View File

@ -22,6 +22,7 @@
*/
#include "precompiled.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
@ -2032,7 +2033,7 @@ C2V_VMENTRY_0(jboolean, isTrustedForIntrinsics, (JNIEnv* env, jobject, jobject h
JVMCI_THROW_0(NullPointerException);
}
InstanceKlass* ik = InstanceKlass::cast(JVMCIENV->asKlass(JVMCIENV->wrap(holder)));
if (ik->class_loader_data()->is_builtin_class_loader_data()) {
if (ik->class_loader_data()->is_boot_class_loader_data() || ik->class_loader_data()->is_platform_class_loader_data()) {
return true;
}
return false;

View File

@ -22,11 +22,11 @@
*/
package jdk.vm.ci.code;
import java.util.Arrays;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Set;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaValue;
import jdk.vm.ci.meta.ResolvedJavaField;
@ -74,8 +74,8 @@ public final class VirtualObject implements JavaValue {
* @param id a unique id that identifies the object within the debug information for one
* position in the compiled code.
* @param isAutoBox a flag that tells the runtime that the object may be a boxed primitive and
* that it possibly needs to be obtained for the box cache instead of creating
* a new instance.
* that it possibly needs to be obtained for the box cache instead of creating a new
* instance.
* @return a new {@link VirtualObject} instance.
*/
public static VirtualObject get(ResolvedJavaType type, int id, boolean isAutoBox) {
@ -108,14 +108,32 @@ public final class VirtualObject implements JavaValue {
}
} else {
ResolvedJavaField[] fields = vo.type.getInstanceFields(true);
assert fields.length == vo.values.length : vo.type + ", fields=" + Arrays.toString(fields) + ", values=" + Arrays.toString(vo.values);
for (int i = 0; i < vo.values.length; i++) {
int fieldIndex = 0;
for (int i = 0; i < vo.values.length; i++, fieldIndex++) {
if (i != 0) {
buf.append(',');
}
buf.append(fields[i].getName()).append('=');
if (fieldIndex >= fields.length) {
buf.append("<missing field>");
} else {
ResolvedJavaField field = fields[fieldIndex];
buf.append(field.getName());
if (vo.slotKinds[i].getSlotCount() == 2 && field.getType().getJavaKind().getSlotCount() == 1) {
if (fieldIndex + 1 >= fields.length) {
buf.append("/<missing field>");
} else {
ResolvedJavaField field2 = fields[++fieldIndex];
buf.append('/').append(field2.getName());
}
}
}
buf.append('=');
appendValue(buf, vo.values[i], visited);
}
// Extra fields
for (; fieldIndex < fields.length; fieldIndex++) {
buf.append(fields[fieldIndex].getName()).append("=<missing value>");
}
}
}
buf.append('}');
@ -126,6 +144,55 @@ public final class VirtualObject implements JavaValue {
return buf;
}
public interface LayoutVerifier {
int getOffset(ResolvedJavaField field);
default JavaKind getStorageKind(ResolvedJavaField field) {
return field.getType().getJavaKind();
}
}
public void verifyLayout(LayoutVerifier verifier) {
if (!type.isArray()) {
ResolvedJavaField[] fields = type.getInstanceFields(true);
int fieldIndex = 0;
for (int i = 0; i < values.length; i++, fieldIndex++) {
JavaKind slotKind = slotKinds[i];
if (fieldIndex >= fields.length) {
throw new JVMCIError("Not enough fields for the values provided for %s", toString());
} else {
ResolvedJavaField field = fields[fieldIndex];
JavaKind fieldKind = verifier.getStorageKind(field);
if (slotKind.getSlotCount() == 2 && fieldKind == JavaKind.Int) {
int offset = verifier.getOffset(field);
if (offset % 8 != 0) {
throw new JVMCIError("Double word value stored across two ints must be aligned %s", toString());
}
if (fieldIndex + 1 >= fields.length) {
throw new JVMCIError("Missing second field for double word value stored in two ints %s", toString());
}
ResolvedJavaField field2 = fields[fieldIndex + 1];
if (field2.getType().getJavaKind() != JavaKind.Int) {
throw new JVMCIError("Second field for double word value stored in two ints must be int but got %s in %s", field2.getType().getJavaKind(), toString());
}
int offset2 = verifier.getOffset(field2);
if (offset + 4 != offset2) {
throw new JVMCIError("Double word value stored across two ints must be sequential %s", toString());
}
fieldIndex++;
} else if (fieldKind.getStackKind() != slotKind.getStackKind()) {
throw new JVMCIError("Expected value of kind %s but got %s for field %s in %s", fieldKind, slotKind, field, toString());
}
}
}
// Extra fields
if (fieldIndex < fields.length) {
throw new JVMCIError("Not enough values provided for fields in %s", this);
}
}
}
@Override
public String toString() {
Set<VirtualObject> visited = Collections.newSetFromMap(new IdentityHashMap<VirtualObject, Boolean>());
@ -170,16 +237,18 @@ public final class VirtualObject implements JavaValue {
* the box is in the cache range and try to return a cached object.
*/
public boolean isAutoBox() {
return isAutoBox;
return isAutoBox;
}
/**
* Sets the value of the box flag.
* @param isAutoBox a flag that tells the runtime that the object may be a boxed primitive and that
* it possibly needs to be obtained for the box cache instead of creating a new instance.
*
* @param isAutoBox a flag that tells the runtime that the object may be a boxed primitive and
* that it possibly needs to be obtained for the box cache instead of creating a new
* instance.
*/
public void setIsAutoBox(boolean isAutoBox) {
this.isAutoBox = isAutoBox;
this.isAutoBox = isAutoBox;
}
/**

View File

@ -32,7 +32,7 @@ import jdk.vm.ci.meta.ResolvedJavaType;
* A cleaner tracks a referent object and includes some {@linkplain #doCleanup() cleanup code} that
* is run some time after the referent object has become weakly-reachable.
*
* This is like {@link sun.misc.Cleaner} but with weak semantics instead of phantom. Objects
* This is like {@link java.lang.ref.Cleaner} but with weak semantics instead of phantom. Objects
* referenced by this might be referenced by {@link ResolvedJavaType} which is kept alive by a
* {@link WeakReference} so we need equivalent reference strength.
*/

View File

@ -56,7 +56,7 @@ final class CompilerToVM {
private static native void registerNatives();
/**
* These values mirror the equivalent values from {@link Unsafe} but are approriate for the JVM
* These values mirror the equivalent values from {@code Unsafe} but are appropriate for the JVM
* being compiled against.
*/
// Checkstyle: stop
@ -514,10 +514,10 @@ final class CompilerToVM {
/**
* Reads an object pointer within a VM data structure. That is, any {@link VMField} whose
* {@link VMField#type type} is {@code "oop"} (e.g.,
* {@code Klass::_java_mirror}, {@code JavaThread::_threadObj}).
* {@link VMField#type type} is {@code "oop"} (e.g., {@code Klass::_java_mirror},
* {@code JavaThread::_threadObj}).
*
* Note that {@link Unsafe#getObject(Object, long)} cannot be used for this since it does a
* Note that {@code Unsafe.getObject(Object, long)} cannot be used for this since it does a
* {@code narrowOop} read if the VM is using compressed oops whereas oops within VM data
* structures are (currently) always uncompressed.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019, 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
@ -25,10 +25,12 @@ package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.code.CompiledCode;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.VirtualObject;
import jdk.vm.ci.code.site.DataPatch;
import jdk.vm.ci.code.site.Infopoint;
import jdk.vm.ci.code.site.Site;
import jdk.vm.ci.meta.Assumptions.Assumption;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
@ -156,9 +158,23 @@ public class HotSpotCompiledCode implements CompiledCode {
if (info.debugInfo != null) {
BytecodeFrame frame = info.debugInfo.frame();
assert frame == null || frame.validateFormat();
if (info.debugInfo.getVirtualObjectMapping() != null) {
for (VirtualObject v : info.debugInfo.getVirtualObjectMapping()) {
verifyVirtualObject(v);
}
}
}
}
}
return true;
}
public static void verifyVirtualObject(VirtualObject v) {
v.verifyLayout(new VirtualObject.LayoutVerifier() {
@Override
public int getOffset(ResolvedJavaField field) {
return field.getOffset();
}
});
}
}

View File

@ -31,25 +31,19 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.Serializable;
import java.lang.invoke.CallSite;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandle;
import java.lang.module.ModuleDescriptor.Requires;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.ServiceLoader;
import java.util.function.Predicate;
import jdk.internal.misc.Unsafe;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CompilationRequestResult;
import jdk.vm.ci.code.CompiledCode;
@ -187,9 +181,15 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
// initialized.
JVMCI.getRuntime();
}
// Make sure all the primitive box caches are populated (required to properly materialize boxed primitives
// Make sure all the primitive box caches are populated (required to properly
// materialize boxed primitives
// during deoptimization).
Object[] boxCaches = { Boolean.valueOf(false), Byte.valueOf((byte)0), Short.valueOf((short) 0), Character.valueOf((char) 0), Integer.valueOf(0), Long.valueOf(0) };
Boolean.valueOf(false);
Byte.valueOf((byte) 0);
Short.valueOf((short) 0);
Character.valueOf((char) 0);
Integer.valueOf(0);
Long.valueOf(0);
}
}
return result;
@ -338,7 +338,7 @@ public final class HotSpotJVMCIRuntime implements JVMCIRuntime {
private static HotSpotJVMCIBackendFactory findFactory(String architecture) {
Iterable<HotSpotJVMCIBackendFactory> factories = getHotSpotJVMCIBackendFactories();
assert factories != null : "sanity";
assert factories != null : "sanity";
for (HotSpotJVMCIBackendFactory factory : factories) {
if (factory.getArchitecture().equalsIgnoreCase(architecture)) {
return factory;
@ -391,33 +391,35 @@ assert factories != null : "sanity";
@NativeImageReinitialize private volatile ClassValue<WeakReferenceHolder<HotSpotResolvedJavaType>> resolvedJavaType;
/**
* To avoid calling ClassValue.remove to refresh the weak reference, which
* under certain circumstances can lead to an infinite loop, we use a
* permanent holder with a mutable field that we refresh.
* To avoid calling ClassValue.remove to refresh the weak reference, which under certain
* circumstances can lead to an infinite loop, we use a permanent holder with a mutable field
* that we refresh.
*/
private static class WeakReferenceHolder<T> {
private volatile WeakReference<T> ref;
WeakReferenceHolder(T value) {
set(value);
}
void set(T value) {
ref = new WeakReference<T>(value);
ref = new WeakReference<>(value);
}
T get() {
return ref.get();
}
};
}
@NativeImageReinitialize private HashMap<Long, WeakReference<ResolvedJavaType>> resolvedJavaTypes;
/**
* Stores the value set by {@link #excludeFromJVMCICompilation(Module...)} so that it can
* be read from the VM.
* Stores the value set by {@link #excludeFromJVMCICompilation(Module...)} so that it can be
* read from the VM.
*/
@SuppressWarnings("unused")//
@NativeImageReinitialize private Module[] excludeFromJVMCICompilation;
private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
private volatile List<HotSpotVMEventListener> vmEventListeners;
@ -508,7 +510,7 @@ assert factories != null : "sanity";
if (resolvedJavaType == null) {
synchronized (this) {
if (resolvedJavaType == null) {
resolvedJavaType = new ClassValue<WeakReferenceHolder<HotSpotResolvedJavaType>>() {
resolvedJavaType = new ClassValue<>() {
@Override
protected WeakReferenceHolder<HotSpotResolvedJavaType> computeValue(Class<?> type) {
return new WeakReferenceHolder<>(createClass(type));
@ -522,8 +524,7 @@ assert factories != null : "sanity";
HotSpotResolvedJavaType javaType = ref.get();
if (javaType == null) {
/*
* If the referent has become null, create a new value and
* update cached weak reference.
* If the referent has become null, create a new value and update cached weak reference.
*/
javaType = createClass(javaClass);
ref.set(javaType);
@ -591,7 +592,7 @@ assert factories != null : "sanity";
* compiler.
*/
public Predicate<ResolvedJavaType> getIntrinsificationTrustPredicate(Class<?>... compilerLeafClasses) {
return new Predicate<ResolvedJavaType>() {
return new Predicate<>() {
@Override
public boolean test(ResolvedJavaType type) {
if (type instanceof HotSpotResolvedObjectTypeImpl) {

View File

@ -563,6 +563,10 @@ final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implem
* a deopt instead since they can't really be used if they aren't linked yet.
*/
if (!declaredHolder.isAssignableFrom(this) || this.isArray() || this.equals(declaredHolder) || !isLinked() || isInterface()) {
if (hmethod.canBeStaticallyBound()) {
// No assumptions are required.
return new AssumptionResult<>(hmethod);
}
ResolvedJavaMethod result = hmethod.uniqueConcreteMethod(declaredHolder);
if (result != null) {
return new AssumptionResult<>(result, new ConcreteMethod(method, declaredHolder, result));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, 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
@ -23,7 +23,6 @@
package jdk.vm.ci.services;
import static jdk.vm.ci.services.Services.IS_BUILDING_NATIVE_IMAGE;
import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE;
import java.util.ArrayList;
import java.util.List;
@ -81,7 +80,7 @@ public abstract class JVMCIServiceLocator {
result = ServiceLoader.load(JVMCIServiceLocator.class, ClassLoader.getSystemClassLoader());
if (IS_BUILDING_NATIVE_IMAGE) {
ArrayList<JVMCIServiceLocator> l = new ArrayList<>();
for (JVMCIServiceLocator locator: result) {
for (JVMCIServiceLocator locator : result) {
l.add(locator);
}
l.trimToSize();

View File

@ -33,7 +33,6 @@ import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.Set;
@ -45,9 +44,6 @@ import jdk.internal.reflect.Reflection;
*/
public final class Services {
// This class must be compilable and executable on JDK 8 since it's used in annotation
// processors while building JDK 9 so use of API added in JDK 9 is made via reflection.
/**
* Guards code that should be run when building an JVMCI shared library but should be excluded
* from (being compiled into) the library. Such code must be directly guarded by an {@code if}
@ -73,8 +69,12 @@ public final class Services {
private Services() {
}
private static volatile Map<String, String> savedProperties = VM.getSavedProperties();
static final boolean JVMCI_ENABLED = Boolean.parseBoolean(savedProperties.get("jdk.internal.vm.ci.enabled"));
/**
* In a native image, this field is initialized by {@link #initializeSavedProperties(byte[])}.
*/
private static volatile Map<String, String> savedProperties;
static final boolean JVMCI_ENABLED = Boolean.parseBoolean(VM.getSavedProperties().get("jdk.internal.vm.ci.enabled"));
/**
* Checks that JVMCI is enabled in the VM and throws an error if it isn't.
@ -90,9 +90,22 @@ public final class Services {
*/
public static Map<String, String> getSavedProperties() {
checkJVMCIEnabled();
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new JVMCIPermission());
if (IS_IN_NATIVE_IMAGE) {
if (savedProperties == null) {
throw new InternalError("Saved properties not initialized");
}
} else {
if (savedProperties == null) {
synchronized (Services.class) {
if (savedProperties == null) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new JVMCIPermission());
}
savedProperties = VM.getSavedProperties();
}
}
}
}
return savedProperties;
}

View File

@ -4,9 +4,7 @@
*
* 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.
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, 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
@ -62,32 +62,32 @@ public class DebugInfoTest extends CodeInstallationTest {
/*
* Ensure that any objects mentioned in the VirtualObjects are also in the OopMap.
*/
List<Location> newLocations = new ArrayList<Location>(Arrays.asList(objects));
List<Location> newDerived = new ArrayList<Location>(Arrays.asList(derivedBase));
List<Location> newLocations = new ArrayList<>(Arrays.asList(objects));
List<Location> newDerived = new ArrayList<>(Arrays.asList(derivedBase));
int[] newSizeInBytes = sizeInBytes;
VirtualObject[] vobjs = compiler.compile(asm, values);
if (vobjs != null) {
for (VirtualObject obj : vobjs) {
JavaValue[] objValues = obj.getValues();
for (int i = 0; i < objValues.length; i++) {
if (obj.getSlotKind(i) == JavaKind.Object) {
Location oopLocation = null;
int bytes = -1;
if (objValues[i] instanceof RegisterValue) {
RegisterValue reg = (RegisterValue) objValues[i];
oopLocation = Location.register(reg.getRegister());
bytes = reg.getValueKind().getPlatformKind().getSizeInBytes();
} else if (objValues[i] instanceof StackSlot) {
StackSlot slot = (StackSlot) objValues[i];
oopLocation = Location.stack(asm.getOffset(slot));
bytes = slot.getValueKind().getPlatformKind().getSizeInBytes();
}
if (oopLocation != null && !newLocations.contains(oopLocation)) {
newLocations.add(oopLocation);
newDerived.add(null);
newSizeInBytes = Arrays.copyOf(newSizeInBytes, newSizeInBytes.length + 1);
newSizeInBytes[newSizeInBytes.length - 1] = bytes;
}
if (obj.getSlotKind(i) == JavaKind.Object) {
Location oopLocation = null;
int bytes = -1;
if (objValues[i] instanceof RegisterValue) {
RegisterValue reg = (RegisterValue) objValues[i];
oopLocation = Location.register(reg.getRegister());
bytes = reg.getValueKind().getPlatformKind().getSizeInBytes();
} else if (objValues[i] instanceof StackSlot) {
StackSlot slot = (StackSlot) objValues[i];
oopLocation = Location.stack(asm.getOffset(slot));
bytes = slot.getValueKind().getPlatformKind().getSizeInBytes();
}
if (oopLocation != null && !newLocations.contains(oopLocation)) {
newLocations.add(oopLocation);
newDerived.add(null);
newSizeInBytes = Arrays.copyOf(newSizeInBytes, newSizeInBytes.length + 1);
newSizeInBytes[newSizeInBytes.length - 1] = bytes;
}
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, 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
@ -77,7 +77,8 @@ public class NativeCallTest extends CodeInstallationTest {
@Test
public void testF32SDILDS() {
int sCount = 32;
Object[] remainingArgs = new Object[]{ // Pairs of <Object>, <Class>
// Pairs of <Object>, <Class>
Object[] remainingArgs = new Object[]{
1.2345678F, float.class,
3.212434D, double.class,
43921652, int.class,
@ -101,7 +102,8 @@ public class NativeCallTest extends CodeInstallationTest {
@Test
public void testI32SDILDS() {
int sCount = 32;
Object[] remainingArgs = new Object[]{ // Pairs of <Object>, <Class>
// Pairs of <Object>, <Class>
Object[] remainingArgs = new Object[]{
1.2345678F, float.class,
3.212434D, double.class,
43921652, int.class,
@ -143,6 +145,8 @@ public class NativeCallTest extends CodeInstallationTest {
}
}
// Checkstyle: stop
public static native long getFF();
public static native float _FF(float a, float b);
@ -187,6 +191,7 @@ public class NativeCallTest extends CodeInstallationTest {
double d18, double d19, double d1a, double d1b, double d1c, double d1d, double d1e, double d1f,
float a, double b, int c, long d, double e, float f);
@SuppressWarnings("unused")
public static float D32SDILDS(double d00, double d01, double d02, double d03, double d04, double d05, double d06, double d07,
double d08, double d09, double d0a, double d0b, double d0c, double d0d, double d0e, double d0f,
double d10, double d11, double d12, double d13, double d14, double d15, double d16, double d17,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, 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
@ -206,7 +206,7 @@ public abstract class TestAssembler {
private StackSlot deoptRescue;
public ValueKindFactory<TestValueKind> valueKindFactory = new ValueKindFactory<TestAssembler.TestValueKind>() {
public ValueKindFactory<TestValueKind> valueKindFactory = new ValueKindFactory<>() {
public TestValueKind getValueKind(JavaKind javaKind) {
return (TestValueKind) TestAssembler.this.getValueKind(javaKind);
}
@ -389,7 +389,7 @@ public abstract class TestAssembler {
public abstract void emitLoad(AllocatableValue av, Object prim);
/**
* Emit a call to a fixed address <code>addr</code>
* Emit a call to a fixed address <code>addr</code>.
*/
public abstract void emitCall(long addr);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, 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
@ -42,6 +42,7 @@ public class TestHotSpotVMConfig extends HotSpotVMConfigAccess {
public final int classMirrorHandleOffset = getFieldOffset("Klass::_java_mirror", Integer.class, "OopHandle");
// Checkstyle: stop
public final int MARKID_DEOPT_HANDLER_ENTRY = getConstant("CodeInstaller::DEOPT_HANDLER_ENTRY", Integer.class);
public final long handleDeoptStub = getFieldValue("CompilerToVM::Data::SharedRuntime_deopt_blob_unpack", Long.class, "address");

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2019, 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 jdk.vm.ci.code.test;
import org.junit.Assert;
import org.junit.Test;
import jdk.vm.ci.code.VirtualObject;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaValue;
import jdk.vm.ci.meta.ResolvedJavaType;
public class VirtualObjectFormattingTest extends VirtualObjectTestBase {
@Test
public void testFormat() {
testBase();
}
@Override
protected void test(ResolvedJavaType klass, JavaValue[] kinds, JavaKind[] values, boolean malformed) {
// Verify that VirtualObject.toString will produce output without throwing exceptions or
// asserting.
VirtualObject virtual = VirtualObject.get(klass, 0);
virtual.setValues(kinds, values);
Assert.assertTrue(!virtual.toString().equals(""));
}
}

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2019, 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 jdk.vm.ci.code.test;
import java.util.Arrays;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaValue;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.runtime.JVMCI;
public abstract class VirtualObjectTestBase {
public static class SimpleObject {
int i1;
int i2;
int i3;
int i4;
int i5;
int i6;
}
public static JavaConstant getValue(JavaKind kind) {
long dummyValue = kind.ordinal();
dummyValue = dummyValue | dummyValue << 8;
dummyValue = dummyValue | dummyValue << 16;
dummyValue = dummyValue | dummyValue << 32;
if (kind.isNumericInteger()) {
return JavaConstant.forIntegerKind(kind, dummyValue);
} else if (kind == JavaKind.Float) {
return JavaConstant.forDouble(Double.longBitsToDouble(dummyValue));
} else if (kind == JavaKind.Float) {
return JavaConstant.forFloat(Float.intBitsToFloat((int) dummyValue));
} else {
return JavaConstant.NULL_POINTER;
}
}
public static JavaValue[] getJavaValues(JavaKind[] kinds) {
JavaValue[] values = new JavaValue[kinds.length];
for (int i = 0; i < kinds.length; i++) {
values[i] = getValue(kinds[i]);
}
return values;
}
/**
* Subclasses are expected to override this method to provide their own verification logic using
* the normal JUnit {@link org.junit.Assert} methods.
*
* @param klass class for the {@link jdk.vm.ci.code.VirtualObject}
* @param kinds {@link JavaKind Javakinds} for values
* @param values {@link JavaValue values} for materializing the
* {@link jdk.vm.ci.code.VirtualObject}
* @param malformed indicates whether the resulting virtual object is considered to be properly
* formed relative to the fields of {@code klass}
* @throws AssertionError if a problem is detected
*/
protected abstract void test(ResolvedJavaType klass, JavaValue[] kinds, JavaKind[] values, boolean malformed);
public void testBase() {
MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
ResolvedJavaType simple = metaAccess.lookupJavaType(SimpleObject.class);
ResolvedJavaField[] fields = simple.getInstanceFields(true);
JavaKind[] fieldKinds = new JavaKind[fields.length];
for (int i = 0; i < fields.length; i++) {
fieldKinds[i] = fields[i].getType().getJavaKind();
}
// Generate a straightforward VirtualObject with values that match to declared field types.
JavaKind[] kinds = fieldKinds.clone();
JavaValue[] values = getJavaValues(kinds);
test(simple, values, kinds, false);
// Spread a long value across two int fields
kinds = Arrays.copyOf(fieldKinds, fieldKinds.length - 1);
kinds[1] = JavaKind.Long;
test(simple, getJavaValues(kinds), kinds, false);
// Produce a long value for the final int field so there is no matching int field for the
// second half of the long
kinds = fieldKinds.clone();
kinds[kinds.length - 1] = JavaKind.Long;
test(simple, getJavaValues(kinds), kinds, true);
// Not enough values for the fields.
kinds = Arrays.copyOf(fieldKinds, fieldKinds.length - 1);
test(simple, getJavaValues(kinds), kinds, true);
// Too many values for the fields.
kinds = Arrays.copyOf(fieldKinds, fieldKinds.length + 1);
kinds[kinds.length - 1] = JavaKind.Int;
test(simple, getJavaValues(kinds), kinds, true);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, 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
@ -173,6 +173,7 @@ public class MethodHandleAccessProviderData implements TestInterface {
}
// can't use nested classes for storing these test methods. see JDK-8010319
@SuppressWarnings("unused")
private void privateMethod() {
// empty
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2019, 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 jdk.vm.ci.hotspot.test;
import org.junit.Assert;
import org.junit.Test;
import jdk.vm.ci.code.VirtualObject;
import jdk.vm.ci.code.test.VirtualObjectTestBase;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotCompiledCode;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaValue;
import jdk.vm.ci.meta.ResolvedJavaType;
public class VirtualObjectLayoutTest extends VirtualObjectTestBase {
@Override
protected void test(ResolvedJavaType klass, JavaValue[] values, JavaKind[] kinds, boolean error) {
// Verify that the layout checking will correctly report errors
VirtualObject virtual = VirtualObject.get(klass, 0);
virtual.setValues(values, kinds);
try {
HotSpotCompiledCode.verifyVirtualObject(virtual);
} catch (JVMCIError e) {
Assert.assertTrue("Unexpected error verifying " + virtual, error);
return;
}
Assert.assertFalse("Expected error but passed verifying " + virtual, error);
}
@Test
public void testFormat() {
testBase();
}
}

View File

@ -4,9 +4,7 @@
*
* 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.
* 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