8233035: Update JVMCI
Reviewed-by: dlong
This commit is contained in:
parent
f9f141b6ab
commit
5c506779b2
@ -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",
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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));
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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(""));
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user