Hello!

On 2015-09-30 12:50, Paul Sandoz wrote:
On 25 Sep 2015, at 17:19, Peter Levart <peter.lev...@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) {
     if (!TRACE_METHOD_LINKAGE)
         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!"? :-)

/Claes

Paul.

Reply via email to