RFR: JDK-8136893: Improve early java.lang.invoke infrastructure initialization

Claes Redestad claes.redestad at oracle.com
Tue Oct 13 11:26:59 UTC 2015


On 2015-09-30 12:50, Paul Sandoz wrote:
>> On 25 Sep 2015, at 17:19, Peter Levart <peter.levart at gmail.com> wrote:
>> Hi Paul,
>> Thanks for looking into this.
> Apologies for the late reply.
>> On 09/25/2015 04:07 PM, Paul Sandoz wrote:
>>> Hi,
>>> This looks like a partial dup of https://bugs.openjdk.java.net/browse/JDK-8076596
>> Ah, sorry, I wasn't aware this has already been registered in JIRA. I have linked the two issues together as DUPs.
> Thanks.
>>> The changes look ok, but I am concerned post initialization there may be code paths taken that require the system class loader to be used but instead the boot stream class loader is used instead. Is that a legitimate concern?
>> It is legitimate, but I have inspected usages and:
>> - In java.lang.invoke.BoundMethodHandle.Factory#makeCbmhCtor, null is passed explicitly and this method is used only from java.lang.invoke.BoundMethodHandle.Factory#makeCtors which is used from java.lang.invoke.BoundMethodHandle.SpeciesData#initForBootstrap and java.lang.invoke.BoundMethodHandle.SpeciesData#SpeciesData(java.lang.String, java.lang.Class<? extends java.lang.invoke.BoundMethodHandle>). These usages only deal with erased MH types (Object, long, int, double, float).
>> - In java.lang.invoke.MemberName#getMethodType, the result of MemberName.getClassLoader() is passed to the method. This is the class loader of the member's declaring class. Any types referenced from the member declaration should be resolvable from this class loader. A member declared by a bootstrap class (MemberName.getClassLoader() returns null) can only reference types resolvable from bootstrap loader.
>> - In java.lang.invoke.MemberName#getFieldType, the result of MemberName.getClassLoader() is passed to the method. Similar applies as above.
>> - In java.lang.invoke.MethodHandleNatives#fixMethodType(Class<?> callerClass, Object type), the callerClass.getClassLoader() is passed to the method. This is invoked from:
>> java.lang.invoke.MethodHandleNatives#linkMethodImpl(
>>                                      Class<?> callerClass, int refKind,
>>                                      Class<?> defc, String name, Object type,
>>                                      Object[] appendixResult)
>> which is called from java.lang.invoke.MethodHandleNatives#linkMethod(same args)
>> I suppose this is an upcall from VM to link a call to the @PolymorphicSignature method and callerClass is the class in which the invocation bytecodes are executed. Am I right?
> Yes.
> And before that there is an upcall to MethodHandleNatives.findMethodHandleType, see SystemDictionary::find_method_handle_invoker in src/share/vm/classfile/systemDictionary.cpp.
> AFAICT the “type” argument passed to the linkMethod should always be of MethodType:
> static MemberName linkMethod(Class<?> callerClass, int refKind,
>                               Class<?> defc, String name, Object type,
>                               Object[] appendixResult) {
>          return linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
>      return linkMethodTracing(callerClass, refKind, defc, name, type, appendixResult);
> }
> static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
>                                   Class<?> defc, String name, Object type,
>                                   Object[] appendixResult) {
>      try {
>          if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
>              return Invokers.methodHandleInvokeLinkerMethod(name, fixMethodType(callerClass, type), appendixResult);
>          }
>      } catch (Throwable ex) {
>          if (ex instanceof LinkageError)
>              throw (LinkageError) ex;
>          else
>              throw new LinkageError(ex.getMessage(), ex);
>      }
>      throw new LinkageError("no such method "+defc.getName()+"."+name+type);
> }
> private static MethodType fixMethodType(Class<?> callerClass, Object type) {
>      if (type instanceof MethodType)
>          return (MethodType) type;
>      else
>          return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
> }
> Thus it seems fixMethodType is not necessary. I think this is confirmed when looking at up calls to linkMethodHandleConstant and linkCallSite.

+1 - this should be a separate cleanup, though.

>> The reasoning is as follows: if callerClass.getClassLoader() is sufficient for resolving types that appear at the call site in a non-bootstrap callerClass, then bootstrap classloader should be sufficient to resolve types that appear at the call site in a bootstrap callerClass. Does anybody have any other opinion?
>> - sun.invoke.util.BytecodeDescriptor#parseMethod(java.lang.String, java.lang.ClassLoader) is only used from the newly introduced java.lang.invoke.MethodType#fromDescriptor
> Ok, i think you have things covered, thanks,

I believe you meant "Ship it!"? :-)


> Paul.

More information about the core-libs-dev mailing list