8265480: add basic JVMCI support for JEP 309: Dynamic Class-File Constants

Reviewed-by: kvn, psandoz
This commit is contained in:
Doug Simon 2021-04-22 15:59:12 +00:00
parent 9499175064
commit 7df0c10a4d
10 changed files with 391 additions and 31 deletions

View File

@ -505,10 +505,11 @@ C2V_END
C2V_VMENTRY_0(jboolean, isCompilable,(JNIEnv* env, jobject, jobject jvmci_method))
Method* method = JVMCIENV->asMethod(jvmci_method);
ConstantPool* cp = method->constMethod()->constants();
assert(cp != NULL, "npe");
// don't inline method when constant pool contains a CONSTANT_Dynamic
return !method->is_not_compilable(CompLevel_full_optimization) && !cp->has_dynamic_constant();
// Skip redefined methods
if (method->is_old()) {
return false;
}
return !method->is_not_compilable(CompLevel_full_optimization);
C2V_END
C2V_VMENTRY_0(jboolean, hasNeverInlineDirective,(JNIEnv* env, jobject, jobject jvmci_method))
@ -624,8 +625,48 @@ C2V_VMENTRY_NULL(jobject, lookupClass, (JNIEnv* env, jobject, jclass mirror))
C2V_VMENTRY_NULL(jobject, resolvePossiblyCachedConstantInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
constantPoolHandle cp(THREAD, JVMCIENV->asConstantPool(jvmci_constant_pool));
oop result = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(result));
oop obj = cp->resolve_possibly_cached_constant_at(index, CHECK_NULL);
constantTag tag = cp->tag_at(index);
if (tag.is_dynamic_constant() || tag.is_dynamic_constant_in_error()) {
if (obj == Universe::the_null_sentinel()) {
return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_NULL_POINTER());
}
BasicType bt = Signature::basic_type(cp->uncached_signature_ref_at(index));
if (!is_reference_type(bt)) {
if (!is_java_primitive(bt)) {
return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_ILLEGAL());
}
// Convert standard box (e.g. java.lang.Integer) to JVMCI box (e.g. jdk.vm.ci.meta.PrimitiveConstant)
jvalue value;
jlong raw_value;
BasicType bt2 = java_lang_boxing_object::get_value(obj, &value);
assert(bt2 == bt, "");
switch (bt2) {
case T_BOOLEAN: raw_value = value.z; break;
case T_BYTE: raw_value = value.b; break;
case T_SHORT: raw_value = value.s; break;
case T_CHAR: raw_value = value.c; break;
case T_INT: raw_value = value.i; break;
case T_LONG: raw_value = value.j; break;
case T_FLOAT: {
JVMCIObject result = JVMCIENV->call_JavaConstant_forFloat(value.f, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
}
case T_DOUBLE: {
JVMCIObject result = JVMCIENV->call_JavaConstant_forDouble(value.d, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
}
default: {
return JVMCIENV->get_jobject(JVMCIENV->get_JavaConstant_ILLEGAL());
}
}
JVMCIObject result = JVMCIENV->call_PrimitiveConstant_forTypeChar(type2char(bt2), raw_value, JVMCI_CHECK_NULL);
return JVMCIENV->get_jobject(result);
}
}
return JVMCIENV->get_jobject(JVMCIENV->get_object_constant(obj));
C2V_END
C2V_VMENTRY_0(jint, lookupNameAndTypeRefIndexInPool, (JNIEnv* env, jobject, jobject jvmci_constant_pool, jint index))
@ -2700,7 +2741,7 @@ JNINativeMethod CompilerToVM::methods[] = {
{CC "lookupAppendixInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECTCONSTANT, FN_PTR(lookupAppendixInPool)},
{CC "lookupMethodInPool", CC "(" HS_CONSTANT_POOL "IB)" HS_RESOLVED_METHOD, FN_PTR(lookupMethodInPool)},
{CC "constantPoolRemapInstructionOperandFromCache", CC "(" HS_CONSTANT_POOL "I)I", FN_PTR(constantPoolRemapInstructionOperandFromCache)},
{CC "resolvePossiblyCachedConstantInPool", CC "(" HS_CONSTANT_POOL "I)" OBJECTCONSTANT, FN_PTR(resolvePossiblyCachedConstantInPool)},
{CC "resolvePossiblyCachedConstantInPool", CC "(" HS_CONSTANT_POOL "I)" JAVACONSTANT, FN_PTR(resolvePossiblyCachedConstantInPool)},
{CC "resolveTypeInPool", CC "(" HS_CONSTANT_POOL "I)" HS_RESOLVED_KLASS, FN_PTR(resolveTypeInPool)},
{CC "resolveFieldInPool", CC "(" HS_CONSTANT_POOL "I" HS_RESOLVED_METHOD "B[I)" HS_RESOLVED_KLASS, FN_PTR(resolveFieldInPool)},
{CC "resolveInvokeDynamicInPool", CC "(" HS_CONSTANT_POOL "I)V", FN_PTR(resolveInvokeDynamicInPool)},

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, 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
@ -245,6 +245,7 @@
int_field(BytecodePosition, bci) \
end_class \
start_class(JavaConstant, jdk_vm_ci_meta_JavaConstant) \
static_object_field(JavaConstant, ILLEGAL, "Ljdk/vm/ci/meta/PrimitiveConstant;") \
static_object_field(JavaConstant, NULL_POINTER, "Ljdk/vm/ci/meta/JavaConstant;") \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JavaConstant, forFloat, forFloat_signature, (JVMCIObject kind, jlong value, JVMCI_TRAPS)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JavaConstant, forDouble, forDouble_signature, (JVMCIObject kind, jlong value, JVMCI_TRAPS)) \
@ -286,7 +287,9 @@
static_object_field(JavaKind, Char, "Ljdk/vm/ci/meta/JavaKind;") \
static_object_field(JavaKind, Short, "Ljdk/vm/ci/meta/JavaKind;") \
static_object_field(JavaKind, Int, "Ljdk/vm/ci/meta/JavaKind;") \
static_object_field(JavaKind, Float, "Ljdk/vm/ci/meta/JavaKind;") \
static_object_field(JavaKind, Long, "Ljdk/vm/ci/meta/JavaKind;") \
static_object_field(JavaKind, Double, "Ljdk/vm/ci/meta/JavaKind;") \
end_class \
start_class(ValueKind, jdk_vm_ci_meta_ValueKind) \
object_field(ValueKind, platformKind, "Ljdk/vm/ci/meta/PlatformKind;") \

View File

@ -430,6 +430,7 @@
declare_constant(JVM_CONSTANT_MethodHandle) \
declare_constant(JVM_CONSTANT_MethodType) \
declare_constant(JVM_CONSTANT_InvokeDynamic) \
declare_constant(JVM_CONSTANT_Dynamic) \
declare_constant(JVM_CONSTANT_Module) \
declare_constant(JVM_CONSTANT_Package) \
declare_constant(JVM_CONSTANT_ExternalMax) \

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, 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
@ -215,11 +215,11 @@ final class CompilerToVM {
* constant pool cache first.
*
* The behavior of this method is undefined if {@code cpi} does not denote one of the following
* entry types: {@code JVM_CONSTANT_String}, {@code JVM_CONSTANT_MethodHandle},
* {@code JVM_CONSTANT_MethodHandleInError}, {@code JVM_CONSTANT_MethodType} and
* {@code JVM_CONSTANT_MethodTypeInError}.
* entry types: {@code JVM_CONSTANT_Dynamic}, {@code JVM_CONSTANT_String},
* {@code JVM_CONSTANT_MethodHandle}, {@code JVM_CONSTANT_MethodHandleInError},
* {@code JVM_CONSTANT_MethodType} and {@code JVM_CONSTANT_MethodTypeInError}.
*/
native HotSpotObjectConstantImpl resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi);
native JavaConstant resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi);
/**
* Gets the {@code JVM_CONSTANT_NameAndType} index from the entry at index {@code cpi} in

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, 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
@ -140,6 +140,8 @@ public final class HotSpotConstantPool implements ConstantPool, MetaspaceHandleO
final JvmConstant jvmMethodType = add(new JvmConstant(c.jvmConstantMethodType, "MethodType"));
final JvmConstant jvmMethodTypeInError = add(new JvmConstant(c.jvmConstantMethodTypeInError, "MethodTypeInError"));
final JvmConstant jvmInvokeDynamic = add(new JvmConstant(c.jvmConstantInvokeDynamic, "InvokeDynamic"));
final JvmConstant jvmDynamic = add(new JvmConstant(c.jvmConstantDynamic, "Dynamic"));
final JvmConstant jvmDynamicInError = add(new JvmConstant(c.jvmConstantDynamicInError, "DynamicInError"));
private JvmConstant add(JvmConstant constant) {
table[indexOf(constant.tag)] = constant;
@ -545,6 +547,8 @@ public final class HotSpotConstantPool implements ConstantPool, MetaspaceHandleO
case "MethodHandleInError":
case "MethodType":
case "MethodTypeInError":
case "Dynamic":
case "DynamicInError":
return compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
default:
throw new JVMCIError("Unknown constant pool tag %s", tag);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2021, 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
@ -255,6 +255,8 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
final int jvmConstantMethodHandleInError = getConstant("JVM_CONSTANT_MethodHandleInError", Integer.class);
final int jvmConstantMethodType = getConstant("JVM_CONSTANT_MethodType", Integer.class);
final int jvmConstantMethodTypeInError = getConstant("JVM_CONSTANT_MethodTypeInError", Integer.class);
final int jvmConstantDynamic = getConstant("JVM_CONSTANT_Dynamic", Integer.class);
final int jvmConstantDynamicInError = getConstant("JVM_CONSTANT_DynamicInError", Integer.class);
final int jvmConstantInvokeDynamic = getConstant("JVM_CONSTANT_InvokeDynamic", Integer.class);
final int jvmConstantExternalMax = getConstant("JVM_CONSTANT_ExternalMax", Integer.class);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2021, 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
@ -46,6 +46,7 @@ public interface JavaConstant extends Constant, JavaValue {
PrimitiveConstant DOUBLE_1 = new PrimitiveConstant(JavaKind.Double, Double.doubleToRawLongBits(1.0D));
PrimitiveConstant TRUE = new PrimitiveConstant(JavaKind.Boolean, 1L);
PrimitiveConstant FALSE = new PrimitiveConstant(JavaKind.Boolean, 0L);
PrimitiveConstant ILLEGAL = new PrimitiveConstant(JavaKind.Illegal, 0);
/**
* Returns the Java kind of this constant.
@ -329,7 +330,7 @@ public interface JavaConstant extends Constant, JavaValue {
}
static PrimitiveConstant forIllegal() {
return new PrimitiveConstant(JavaKind.Illegal, 0);
return JavaConstant.ILLEGAL;
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2021, 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
@ -473,7 +473,7 @@ public enum JavaKind {
case Long:
return 64;
default:
throw new IllegalArgumentException("illegal call to bits on " + this);
throw new IllegalArgumentException("illegal call to getBitCount() on " + this);
}
}
}

View File

@ -0,0 +1,304 @@
/*
* Copyright (c) 2021, 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.
*/
/*
* @test
* @requires vm.jvmci
* @summary Test CONSTANT_Dynamic resolution by HotSpotConstantPool.
* @modules java.base/jdk.internal.org.objectweb.asm
* jdk.internal.vm.ci/jdk.vm.ci.hotspot:+open
* jdk.internal.vm.ci/jdk.vm.ci.runtime
* jdk.internal.vm.ci/jdk.vm.ci.meta
* @run testng/othervm
* -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:-UseJVMCICompiler
* jdk.vm.ci.hotspot.test.TestDynamicConstant
*/
package jdk.vm.ci.hotspot.test;
import java.io.File;
import java.io.IOException;
import java.lang.invoke.ConstantBootstraps;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.util.List;
import org.testng.Assert;
import org.testng.annotations.Test;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.ConstantDynamic;
import jdk.internal.org.objectweb.asm.Handle;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.vm.ci.hotspot.HotSpotObjectConstant;
import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.PrimitiveConstant;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.runtime.JVMCI;
/**
* Tests support for Dynamic constants.
*
* @see "https://openjdk.java.net/jeps/309"
* @see "https://bugs.openjdk.java.net/browse/JDK-8177279"
*/
public class TestDynamicConstant implements Opcodes {
private static final int PUBLIC_STATIC = ACC_PUBLIC | ACC_STATIC;
static final String testClassInternalName = Type.getInternalName(TestDynamicConstant.class);
static final String constantBootstrapsClassInternalName = Type.getInternalName(ConstantBootstraps.class);
enum CondyType {
/**
* Condy whose bootstrap method is one of the {@code TestDynamicConstant.get<type>BSM()}
* methods.
*/
CALL_DIRECT_BSM,
/**
* Condy whose bootstrap method is {@link ConstantBootstraps#invoke} that invokes one of the
* {@code TestDynamicConstant.get<type>()} methods.
*/
CALL_INDIRECT_BSM,
/**
* Condy whose bootstrap method is {@link ConstantBootstraps#invoke} that invokes one of the
* {@code TestDynamicConstant.get<type>(<type> p1, <type> p2)} methods with args that are
* condys themselves.
*/
CALL_INDIRECT_WITH_ARGS_BSM
}
/**
* Generates a class with a static {@code run} method that returns a value loaded from
* CONSTANT_Dynamic constant pool entry.
*/
static class TestGenerator {
/**
* Type of value returned by the generated {@code run} method.
*/
final Type type;
/**
* Type of condy used to produce the returned value.
*/
final CondyType condyType;
/**
* Base name of the static {@code TestDynamicConstant.get<type>} method(s) invoked from
* condys in the generated class.
*/
final String getter;
/**
* Name of the generated class.
*/
final String className;
TestGenerator(Class<?> type, CondyType condyType) {
String typeName = type.getSimpleName();
this.type = Type.getType(type);
this.condyType = condyType;
this.getter = "get" + typeName.substring(0, 1).toUpperCase() + typeName.substring(1);
this.className = TestDynamicConstant.class.getName() + "$" + typeName + '_' + condyType;
}
Class<?> generateClass() throws ClassNotFoundException {
TestCL cl = new TestCL(getClass().getClassLoader());
return cl.findClass(className);
}
byte[] generateClassfile() {
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
cw.visit(V16, ACC_SUPER | ACC_PUBLIC, className.replace('.', '/'), null, "java/lang/Object", null);
// @formatter:off
// Object ConstantBootstraps.invoke(MethodHandles.Lookup lookup, String name, Class<?> type, MethodHandle handle, Object... args)
// @formatter:on
String invokeSig = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;";
Handle invokeHandle = new Handle(H_INVOKESTATIC, constantBootstrapsClassInternalName, "invoke", invokeSig, false);
String desc = type.getDescriptor();
if (condyType == CondyType.CALL_DIRECT_BSM) {
// Example: int TestDynamicConstant.getIntBSM(MethodHandles.Lookup l, String name,
// Class<?> type)
String sig = "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)" + desc;
Handle handle = new Handle(H_INVOKESTATIC, testClassInternalName, getter + "BSM", sig, false);
ConstantDynamic condy = new ConstantDynamic("const", desc, handle);
MethodVisitor run = cw.visitMethod(PUBLIC_STATIC, "run", "()" + desc, null, null);
run.visitLdcInsn(condy);
run.visitInsn(type.getOpcode(IRETURN));
run.visitMaxs(0, 0);
run.visitEnd();
} else if (condyType == CondyType.CALL_INDIRECT_BSM) {
// Example: int TestDynamicConstant.getInt()
Handle handle = new Handle(H_INVOKESTATIC, testClassInternalName, getter, "()" + desc, false);
ConstantDynamic condy = new ConstantDynamic("const", desc, invokeHandle, handle);
MethodVisitor run = cw.visitMethod(PUBLIC_STATIC, "run", "()" + desc, null, null);
run.visitLdcInsn(condy);
run.visitInsn(type.getOpcode(IRETURN));
run.visitMaxs(0, 0);
run.visitEnd();
} else {
assert condyType == CondyType.CALL_INDIRECT_WITH_ARGS_BSM;
// Example: int TestDynamicConstant.getInt()
Handle handle1 = new Handle(H_INVOKESTATIC, testClassInternalName, getter, "()" + desc, false);
// Example: int TestDynamicConstant.getInt(int v1, int v2)
Handle handle2 = new Handle(H_INVOKESTATIC, testClassInternalName, getter, "(" + desc + desc + ")" + desc, false);
ConstantDynamic condy1 = new ConstantDynamic("const1", desc, invokeHandle, handle1);
ConstantDynamic condy2 = new ConstantDynamic("const2", desc, invokeHandle, handle2, condy1, condy1);
MethodVisitor run = cw.visitMethod(PUBLIC_STATIC, "run", "()" + desc, null, null);
run.visitLdcInsn(condy2);
run.visitInsn(type.getOpcode(IRETURN));
run.visitMaxs(0, 0);
run.visitEnd();
}
cw.visitEnd();
return cw.toByteArray();
}
private final class TestCL extends ClassLoader {
String saveClassfilesDir = System.getProperty("save.classfiles.dir");
private TestCL(ClassLoader parent) {
super(parent);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
if (name.equals(className)) {
byte[] classfileBytes = generateClassfile();
if (saveClassfilesDir != null) {
try {
File classfile = new File(saveClassfilesDir, name.replace('.', File.separatorChar) + ".class");
File classfileDir = classfile.getParentFile();
classfileDir.mkdirs();
Files.write(classfile.toPath(), classfileBytes);
System.out.println("Wrote: " + classfile.getAbsolutePath());
} catch (IOException cause) {
Assert.fail("Error saving class file for " + name, cause);
}
}
return defineClass(name, classfileBytes, 0, classfileBytes.length);
} else {
return super.findClass(name);
}
}
}
}
@SuppressWarnings("try")
@Test
public void test() throws Throwable {
MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
Class<?>[] types = {
boolean.class,
byte.class,
short.class,
char.class,
int.class,
float.class,
long.class,
double.class,
String.class,
List.class
};
for (Class<?> type : types) {
for (CondyType condyType : CondyType.values()) {
TestGenerator e = new TestGenerator(type, condyType);
Class<?> testClass = e.generateClass();
Method m = testClass.getDeclaredMethod("run");
ResolvedJavaMethod run = metaAccess.lookupJavaMethod(m);
ConstantPool cp = run.getConstantPool();
Method getTagAt = cp.getClass().getDeclaredMethod("getTagAt", int.class);
getTagAt.setAccessible(true);
Object lastConstant = null;
for (int cpi = 1; cpi < cp.length(); cpi++) {
String tag = String.valueOf(getTagAt.invoke(cp, cpi));
if (tag.equals("Dynamic")) {
lastConstant = cp.lookupConstant(cpi);
}
}
Assert.assertTrue(lastConstant != null, "No Dynamic entries in constant pool of " + testClass.getName());
// Execute code to resolve condy by execution and compare
// with condy resolved via ConstantPool
Object expect = m.invoke(null);
Object actual;
if (lastConstant instanceof PrimitiveConstant) {
actual = ((PrimitiveConstant) lastConstant).asBoxedPrimitive();
} else {
actual = ((HotSpotObjectConstant) lastConstant).asObject(type);
}
Assert.assertEquals(actual, expect, m + ":");
}
}
}
// @formatter:off
@SuppressWarnings("unused") public static boolean getBooleanBSM(MethodHandles.Lookup l, String name, Class<?> type) { return true; }
@SuppressWarnings("unused") public static char getCharBSM (MethodHandles.Lookup l, String name, Class<?> type) { return '*'; }
@SuppressWarnings("unused") public static short getShortBSM (MethodHandles.Lookup l, String name, Class<?> type) { return Short.MAX_VALUE; }
@SuppressWarnings("unused") public static byte getByteBSM (MethodHandles.Lookup l, String name, Class<?> type) { return Byte.MAX_VALUE; }
@SuppressWarnings("unused") public static int getIntBSM (MethodHandles.Lookup l, String name, Class<?> type) { return Integer.MAX_VALUE; }
@SuppressWarnings("unused") public static float getFloatBSM (MethodHandles.Lookup l, String name, Class<?> type) { return Float.MAX_VALUE; }
@SuppressWarnings("unused") public static long getLongBSM (MethodHandles.Lookup l, String name, Class<?> type) { return Long.MAX_VALUE; }
@SuppressWarnings("unused") public static double getDoubleBSM (MethodHandles.Lookup l, String name, Class<?> type) { return Double.MAX_VALUE; }
@SuppressWarnings("unused") public static String getStringBSM (MethodHandles.Lookup l, String name, Class<?> type) { return "a string"; }
@SuppressWarnings("unused") public static List<?> getListBSM (MethodHandles.Lookup l, String name, Class<?> type) { return List.of("element"); }
public static boolean getBoolean() { return true; }
public static char getChar () { return '*'; }
public static short getShort () { return Short.MAX_VALUE; }
public static byte getByte () { return Byte.MAX_VALUE; }
public static int getInt () { return Integer.MAX_VALUE; }
public static float getFloat () { return Float.MAX_VALUE; }
public static long getLong () { return Long.MAX_VALUE; }
public static double getDouble () { return Double.MAX_VALUE; }
public static String getString () { return "a string"; }
public static List<?> getList () { return List.of("element"); }
public static boolean getBoolean(boolean v1, boolean v2) { return v1 || v2; }
public static char getChar (char v1, char v2) { return (char)(v1 ^ v2); }
public static short getShort (short v1, short v2) { return (short)(v1 ^ v2); }
public static byte getByte (byte v1, byte v2) { return (byte)(v1 ^ v2); }
public static int getInt (int v1, int v2) { return v1 ^ v2; }
public static float getFloat (float v1, float v2) { return v1 * v2; }
public static long getLong (long v1, long v2) { return v1 ^ v2; }
public static double getDouble (double v1, double v2) { return v1 * v2; }
public static String getString (String v1, String v2) { return v1 + v2; }
public static List<?> getList (List<?> v1, List<?> v2) { return List.of(v1, v2); }
// @formatter:on
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021, 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
@ -33,6 +33,17 @@
package jdk.vm.ci.runtime.test;
import static jdk.vm.ci.meta.MetaUtil.toInternalName;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Test;
import jdk.vm.ci.meta.DeoptimizationAction;
import jdk.vm.ci.meta.DeoptimizationReason;
import jdk.vm.ci.meta.JavaConstant;
@ -42,16 +53,6 @@ import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.Signature;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import static jdk.vm.ci.meta.MetaUtil.toInternalName;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
/**
* Tests for {@link MetaAccessProvider}.
@ -117,7 +118,7 @@ public class TestMetaAccessProvider extends TypeUniverse {
assertEquals("Unexpected javaType: " + result[counter] + " while expecting of class: " + aClass, result[counter].toClassName(), aClass.getName());
}
counter++;
}
}
}
@Test(expected = NullPointerException.class)
@ -187,6 +188,9 @@ public class TestMetaAccessProvider extends TypeUniverse {
public void getMemorySizeTest() {
for (ConstantValue cv : constants()) {
JavaConstant c = cv.value;
if (c.getJavaKind() == JavaKind.Illegal) {
continue;
}
long memSize = metaAccess.getMemorySize(c);
if (c.isNull()) {
assertEquals("Expected size = 0 for null", memSize, 0L);