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.