--- old/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java 2019-03-28 11:24:01.000000000 -0700 +++ new/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodHandleAccessProvider.java 2019-03-28 11:24:00.000000000 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -26,9 +26,10 @@ import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime; import java.lang.invoke.MethodHandle; -import java.util.Objects; import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.common.NativeImageReinitialize; +import jdk.vm.ci.hotspot.HotSpotMethodData.VMState; import jdk.vm.ci.meta.ConstantReflectionProvider; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.MethodHandleAccessProvider; @@ -45,15 +46,16 @@ } /** - * Lazy initialization to break class initialization cycle. Field and method lookup is only - * possible after the {@link HotSpotJVMCIRuntime} is fully initialized. + * Lazy initialized reflection on {@link MethodHandle} internals. Field and method lookup is + * only possible after the {@link HotSpotJVMCIRuntime} is fully initialized. */ - static class LazyInitialization { - static final ResolvedJavaType lambdaFormType; - static final ResolvedJavaField methodHandleFormField; - static final ResolvedJavaField lambdaFormVmentryField; - static final ResolvedJavaField methodField; - static final HotSpotResolvedJavaField vmtargetField; + static final class Internals { + final ResolvedJavaType lambdaFormType; + final ResolvedJavaField methodHandleFormField; + final ResolvedJavaField lambdaFormVmentryField; + final HotSpotResolvedJavaField callSiteTargetField; + final ResolvedJavaField methodField; + final HotSpotResolvedJavaField vmtargetField; /** * Search for an instance field with the given name in a class. @@ -71,34 +73,53 @@ return field; } } - throw new NoSuchFieldError(fieldType.getName() + " " + declaringType + "." + fieldName); + throw new NoSuchFieldError(declaringType + "." + fieldName); } - private static ResolvedJavaType resolveType(Class c) { - return runtime().fromClass(c); + private static ResolvedJavaType resolveType(String className) { + return (ResolvedJavaType) runtime().lookupTypeInternal(className, null, true); } - private static ResolvedJavaType resolveType(String className) throws ClassNotFoundException { - return resolveType(Class.forName(className)); - } - - static { + private Internals() { try { - ResolvedJavaType methodHandleType = resolveType(MethodHandle.class); - ResolvedJavaType memberNameType = resolveType("java.lang.invoke.MemberName"); - lambdaFormType = resolveType("java.lang.invoke.LambdaForm"); + ResolvedJavaType methodHandleType = resolveType("Ljava/lang/invoke/MethodHandle;"); + ResolvedJavaType memberNameType = resolveType("Ljava/lang/invoke/MemberName;"); + lambdaFormType = resolveType("Ljava/lang/invoke/LambdaForm;"); methodHandleFormField = findFieldInClass(methodHandleType, "form", lambdaFormType); lambdaFormVmentryField = findFieldInClass(lambdaFormType, "vmentry", memberNameType); - ResolvedJavaType methodType = resolveType("java.lang.invoke.ResolvedMethodName"); + + ResolvedJavaType methodType = resolveType("Ljava/lang/invoke/ResolvedMethodName;"); methodField = findFieldInClass(memberNameType, "method", methodType); - vmtargetField = (HotSpotResolvedJavaField) findFieldInClass(methodType, "vmtarget", resolveType(HotSpotJVMCIRuntime.getHostWordKind().toJavaClass())); + vmtargetField = (HotSpotResolvedJavaField) findFieldInClass(methodType, "vmtarget", resolveType(Character.toString(HotSpotJVMCIRuntime.getHostWordKind().getTypeChar()))); + ResolvedJavaType callSiteType = resolveType("Ljava/lang/invoke/CallSite;"); + callSiteTargetField = (HotSpotResolvedJavaField) findFieldInClass(callSiteType, "target", methodHandleType); } catch (Throwable ex) { throw new JVMCIError(ex); } } + + /** + * Singleton instance lazily initialized via double-checked locking. + */ + @NativeImageReinitialize private static volatile Internals instance; + + static Internals instance() { + Internals result = instance; + if (result == null) { + synchronized (VMState.class) { + result = instance; + if (result == null) { + instance = result = new Internals(); + } + } + } + return result; + } + } + @Override public IntrinsicMethod lookupMethodHandleIntrinsic(ResolvedJavaMethod method) { int intrinsicId = ((HotSpotResolvedJavaMethodImpl) method).intrinsicId(); @@ -131,19 +152,19 @@ } /* Load non-public field: LambdaForm MethodHandle.form */ - JavaConstant lambdaForm = constantReflection.readFieldValue(LazyInitialization.methodHandleFormField, methodHandle); + Internals internals = Internals.instance(); + JavaConstant lambdaForm = constantReflection.readFieldValue(internals.methodHandleFormField, methodHandle); if (lambdaForm == null || lambdaForm.isNull()) { return null; } - JavaConstant memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm); + JavaConstant memberName = constantReflection.readFieldValue(internals.lambdaFormVmentryField, lambdaForm); if (memberName.isNull() && forceBytecodeGeneration) { - Object lf = ((HotSpotObjectConstant) lambdaForm).asObject(LazyInitialization.lambdaFormType); - compilerToVM().compileToBytecode(Objects.requireNonNull(lf)); - memberName = constantReflection.readFieldValue(LazyInitialization.lambdaFormVmentryField, lambdaForm); + compilerToVM().compileToBytecode((HotSpotObjectConstantImpl) lambdaForm); + memberName = constantReflection.readFieldValue(internals.lambdaFormVmentryField, lambdaForm); assert memberName.isNonNull(); } - JavaConstant method = constantReflection.readFieldValue(LazyInitialization.methodField, memberName); + JavaConstant method = constantReflection.readFieldValue(internals.methodField, memberName); return getTargetMethod(method); } @@ -152,7 +173,7 @@ if (memberName.isNull()) { return null; } - JavaConstant method = constantReflection.readFieldValue(LazyInitialization.methodField, memberName); + JavaConstant method = constantReflection.readFieldValue(Internals.instance().methodField, memberName); return getTargetMethod(method); } @@ -165,8 +186,7 @@ throw new IllegalArgumentException("unexpected type for memberName"); } - Object object = ((HotSpotObjectConstantImpl) method).object(); /* Read the ResolvedJavaMethod from the injected field MemberName.method.vmtarget */ - return compilerToVM().getResolvedJavaMethod(object, LazyInitialization.vmtargetField.getOffset()); + return compilerToVM().getResolvedJavaMethod((HotSpotObjectConstantImpl) method, Internals.instance().vmtargetField.getOffset()); } }