src/share/classes/java/lang/invoke/DirectMethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/share/classes/java/lang/invoke

src/share/classes/java/lang/invoke/DirectMethodHandle.java

Print this page
rev 10271 : 8037209: Improvements and cleanups to bytecode assembly for lambda forms
Reviewed-by: vlivanov, psandoz
Contributed-by: john.r.rose@oracle.com
rev 10274 : 8050052: Small cleanups in java.lang.invoke code
Reviewed-by: ?
rev 10276 : 8050166: Get rid of some package-private methods on arguments in j.l.i.MethodHandle
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10277 : 8050173: Add j.l.i.MethodHandle.copyWith(MethodType, LambdaForm)
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com


 110     }
 111     static DirectMethodHandle make(Method method) {
 112         return make(method.getDeclaringClass(), new MemberName(method));
 113     }
 114     static DirectMethodHandle make(Field field) {
 115         return make(field.getDeclaringClass(), new MemberName(field));
 116     }
 117     private static DirectMethodHandle makeAllocator(MemberName ctor) {
 118         assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
 119         Class<?> instanceClass = ctor.getDeclaringClass();
 120         ctor = ctor.asConstructor();
 121         assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
 122         MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
 123         LambdaForm lform = preparedLambdaForm(ctor);
 124         MemberName init = ctor.asSpecial();
 125         assert(init.getMethodType().returnType() == void.class);
 126         return new Constructor(mtype, lform, ctor, init, instanceClass);
 127     }
 128 
 129     @Override






 130     String internalProperties() {
 131         return "\n& DMH.MN="+internalMemberName();
 132     }
 133 
 134     //// Implementation methods.
 135     @Override
 136     MethodHandle viewAsType(MethodType newType) {
 137         return new DirectMethodHandle(newType, form, member);
 138     }
 139     @Override
 140     @ForceInline
 141     MemberName internalMemberName() {
 142         return member;
 143     }
 144 
 145     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
 146 
 147     /**
 148      * Create a LF which can invoke the given method.
 149      * Cache and share this structure among all methods with
 150      * the same basicType and refKind.
 151      */
 152     private static LambdaForm preparedLambdaForm(MemberName m) {
 153         assert(m.isInvocable()) : m;  // call preparedFieldLambdaForm instead
 154         MethodType mtype = m.getInvocationType().basicType();
 155         assert(!m.isMethodHandleInvoke() || "invokeBasic".equals(m.getName())) : m;
 156         int which;
 157         switch (m.getReferenceKind()) {
 158         case REF_invokeVirtual:    which = LF_INVVIRTUAL;    break;
 159         case REF_invokeStatic:     which = LF_INVSTATIC;     break;


 347         assert(!UNSAFE.shouldBeInitialized(defc));
 348         // put it into the final state
 349         EnsureInitialized.INSTANCE.remove(defc);
 350         return true;
 351     }
 352 
 353     /*non-public*/ static void ensureInitialized(Object mh) {
 354         ((DirectMethodHandle)mh).ensureInitialized();
 355     }
 356 
 357     /** This subclass represents invokespecial instructions. */
 358     static class Special extends DirectMethodHandle {
 359         private Special(MethodType mtype, LambdaForm form, MemberName member) {
 360             super(mtype, form, member);
 361         }
 362         @Override
 363         boolean isInvokeSpecial() {
 364             return true;
 365         }
 366         @Override
 367         MethodHandle viewAsType(MethodType newType) {
 368             return new Special(newType, form, member);
 369         }
 370     }
 371 
 372     /** This subclass handles constructor references. */
 373     static class Constructor extends DirectMethodHandle {
 374         final MemberName initMethod;
 375         final Class<?>   instanceClass;
 376 
 377         private Constructor(MethodType mtype, LambdaForm form, MemberName constructor,
 378                             MemberName initMethod, Class<?> instanceClass) {
 379             super(mtype, form, constructor);
 380             this.initMethod = initMethod;
 381             this.instanceClass = instanceClass;
 382             assert(initMethod.isResolved());
 383         }
 384         @Override
 385         MethodHandle viewAsType(MethodType newType) {
 386             return new Constructor(newType, form, member, initMethod, instanceClass);
 387         }
 388     }
 389 
 390     /*non-public*/ static Object constructorMethod(Object mh) {
 391         Constructor dmh = (Constructor)mh;
 392         return dmh.initMethod;
 393     }
 394 
 395     /*non-public*/ static Object allocateInstance(Object mh) throws InstantiationException {
 396         Constructor dmh = (Constructor)mh;
 397         return UNSAFE.allocateInstance(dmh.instanceClass);
 398     }
 399 
 400     /** This subclass handles non-static field references. */
 401     static class Accessor extends DirectMethodHandle {
 402         final Class<?> fieldType;
 403         final int      fieldOffset;
 404         private Accessor(MethodType mtype, LambdaForm form, MemberName member,
 405                          int fieldOffset) {
 406             super(mtype, form, member);
 407             this.fieldType   = member.getFieldType();
 408             this.fieldOffset = fieldOffset;
 409         }
 410 
 411         @Override Object checkCast(Object obj) {
 412             return fieldType.cast(obj);
 413         }
 414         @Override
 415         MethodHandle viewAsType(MethodType newType) {
 416             return new Accessor(newType, form, member, fieldOffset);
 417         }
 418     }
 419 
 420     @ForceInline
 421     /*non-public*/ static long fieldOffset(Object accessorObj) {
 422         // Note: We return a long because that is what Unsafe.getObject likes.
 423         // We store a plain int because it is more compact.
 424         return ((Accessor)accessorObj).fieldOffset;
 425     }
 426 
 427     @ForceInline
 428     /*non-public*/ static Object checkBase(Object obj) {
 429         // Note that the object's class has already been verified,
 430         // since the parameter type of the Accessor method handle
 431         // is either member.getDeclaringClass or a subclass.
 432         // This was verified in DirectMethodHandle.make.
 433         // Therefore, the only remaining check is for null.
 434         // Since this check is *not* guaranteed by Unsafe.getInt
 435         // and its siblings, we need to make an explicit one here.
 436         obj.getClass();  // maybe throw NPE


 438     }
 439 
 440     /** This subclass handles static field references. */
 441     static class StaticAccessor extends DirectMethodHandle {
 442         final private Class<?> fieldType;
 443         final private Object   staticBase;
 444         final private long     staticOffset;
 445 
 446         private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
 447                                Object staticBase, long staticOffset) {
 448             super(mtype, form, member);
 449             this.fieldType    = member.getFieldType();
 450             this.staticBase   = staticBase;
 451             this.staticOffset = staticOffset;
 452         }
 453 
 454         @Override Object checkCast(Object obj) {
 455             return fieldType.cast(obj);
 456         }
 457         @Override
 458         MethodHandle viewAsType(MethodType newType) {
 459             return new StaticAccessor(newType, form, member, staticBase, staticOffset);
 460         }
 461     }
 462 
 463     @ForceInline
 464     /*non-public*/ static Object nullCheck(Object obj) {
 465         obj.getClass();
 466         return obj;
 467     }
 468 
 469     @ForceInline
 470     /*non-public*/ static Object staticBase(Object accessorObj) {
 471         return ((StaticAccessor)accessorObj).staticBase;
 472     }
 473 
 474     @ForceInline
 475     /*non-public*/ static long staticOffset(Object accessorObj) {
 476         return ((StaticAccessor)accessorObj).staticOffset;
 477     }
 478 
 479     @ForceInline




 110     }
 111     static DirectMethodHandle make(Method method) {
 112         return make(method.getDeclaringClass(), new MemberName(method));
 113     }
 114     static DirectMethodHandle make(Field field) {
 115         return make(field.getDeclaringClass(), new MemberName(field));
 116     }
 117     private static DirectMethodHandle makeAllocator(MemberName ctor) {
 118         assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
 119         Class<?> instanceClass = ctor.getDeclaringClass();
 120         ctor = ctor.asConstructor();
 121         assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
 122         MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
 123         LambdaForm lform = preparedLambdaForm(ctor);
 124         MemberName init = ctor.asSpecial();
 125         assert(init.getMethodType().returnType() == void.class);
 126         return new Constructor(mtype, lform, ctor, init, instanceClass);
 127     }
 128 
 129     @Override
 130     MethodHandle copyWith(MethodType mt, LambdaForm lf) {
 131         assert(this.getClass() == DirectMethodHandle.class);  // must override in subclasses
 132         return new DirectMethodHandle(mt, lf, member);
 133     }
 134 
 135     @Override
 136     String internalProperties() {
 137         return "\n& DMH.MN="+internalMemberName();
 138     }
 139 
 140     //// Implementation methods.
 141     @Override




 142     @ForceInline
 143     MemberName internalMemberName() {
 144         return member;
 145     }
 146 
 147     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
 148 
 149     /**
 150      * Create a LF which can invoke the given method.
 151      * Cache and share this structure among all methods with
 152      * the same basicType and refKind.
 153      */
 154     private static LambdaForm preparedLambdaForm(MemberName m) {
 155         assert(m.isInvocable()) : m;  // call preparedFieldLambdaForm instead
 156         MethodType mtype = m.getInvocationType().basicType();
 157         assert(!m.isMethodHandleInvoke() || "invokeBasic".equals(m.getName())) : m;
 158         int which;
 159         switch (m.getReferenceKind()) {
 160         case REF_invokeVirtual:    which = LF_INVVIRTUAL;    break;
 161         case REF_invokeStatic:     which = LF_INVSTATIC;     break;


 349         assert(!UNSAFE.shouldBeInitialized(defc));
 350         // put it into the final state
 351         EnsureInitialized.INSTANCE.remove(defc);
 352         return true;
 353     }
 354 
 355     /*non-public*/ static void ensureInitialized(Object mh) {
 356         ((DirectMethodHandle)mh).ensureInitialized();
 357     }
 358 
 359     /** This subclass represents invokespecial instructions. */
 360     static class Special extends DirectMethodHandle {
 361         private Special(MethodType mtype, LambdaForm form, MemberName member) {
 362             super(mtype, form, member);
 363         }
 364         @Override
 365         boolean isInvokeSpecial() {
 366             return true;
 367         }
 368         @Override
 369         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
 370             return new Special(mt, lf, member);
 371         }
 372     }
 373 
 374     /** This subclass handles constructor references. */
 375     static class Constructor extends DirectMethodHandle {
 376         final MemberName initMethod;
 377         final Class<?>   instanceClass;
 378 
 379         private Constructor(MethodType mtype, LambdaForm form, MemberName constructor,
 380                             MemberName initMethod, Class<?> instanceClass) {
 381             super(mtype, form, constructor);
 382             this.initMethod = initMethod;
 383             this.instanceClass = instanceClass;
 384             assert(initMethod.isResolved());
 385         }
 386         @Override
 387         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
 388             return new Constructor(mt, lf, member, initMethod, instanceClass);
 389         }
 390     }
 391 
 392     /*non-public*/ static Object constructorMethod(Object mh) {
 393         Constructor dmh = (Constructor)mh;
 394         return dmh.initMethod;
 395     }
 396 
 397     /*non-public*/ static Object allocateInstance(Object mh) throws InstantiationException {
 398         Constructor dmh = (Constructor)mh;
 399         return UNSAFE.allocateInstance(dmh.instanceClass);
 400     }
 401 
 402     /** This subclass handles non-static field references. */
 403     static class Accessor extends DirectMethodHandle {
 404         final Class<?> fieldType;
 405         final int      fieldOffset;
 406         private Accessor(MethodType mtype, LambdaForm form, MemberName member,
 407                          int fieldOffset) {
 408             super(mtype, form, member);
 409             this.fieldType   = member.getFieldType();
 410             this.fieldOffset = fieldOffset;
 411         }
 412 
 413         @Override Object checkCast(Object obj) {
 414             return fieldType.cast(obj);
 415         }
 416         @Override
 417         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
 418             return new Accessor(mt, lf, member, fieldOffset);
 419         }
 420     }
 421 
 422     @ForceInline
 423     /*non-public*/ static long fieldOffset(Object accessorObj) {
 424         // Note: We return a long because that is what Unsafe.getObject likes.
 425         // We store a plain int because it is more compact.
 426         return ((Accessor)accessorObj).fieldOffset;
 427     }
 428 
 429     @ForceInline
 430     /*non-public*/ static Object checkBase(Object obj) {
 431         // Note that the object's class has already been verified,
 432         // since the parameter type of the Accessor method handle
 433         // is either member.getDeclaringClass or a subclass.
 434         // This was verified in DirectMethodHandle.make.
 435         // Therefore, the only remaining check is for null.
 436         // Since this check is *not* guaranteed by Unsafe.getInt
 437         // and its siblings, we need to make an explicit one here.
 438         obj.getClass();  // maybe throw NPE


 440     }
 441 
 442     /** This subclass handles static field references. */
 443     static class StaticAccessor extends DirectMethodHandle {
 444         final private Class<?> fieldType;
 445         final private Object   staticBase;
 446         final private long     staticOffset;
 447 
 448         private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
 449                                Object staticBase, long staticOffset) {
 450             super(mtype, form, member);
 451             this.fieldType    = member.getFieldType();
 452             this.staticBase   = staticBase;
 453             this.staticOffset = staticOffset;
 454         }
 455 
 456         @Override Object checkCast(Object obj) {
 457             return fieldType.cast(obj);
 458         }
 459         @Override
 460         MethodHandle copyWith(MethodType mt, LambdaForm lf) {
 461             return new StaticAccessor(mt, lf, member, staticBase, staticOffset);
 462         }
 463     }
 464 
 465     @ForceInline
 466     /*non-public*/ static Object nullCheck(Object obj) {
 467         obj.getClass();
 468         return obj;
 469     }
 470 
 471     @ForceInline
 472     /*non-public*/ static Object staticBase(Object accessorObj) {
 473         return ((StaticAccessor)accessorObj).staticBase;
 474     }
 475 
 476     @ForceInline
 477     /*non-public*/ static long staticOffset(Object accessorObj) {
 478         return ((StaticAccessor)accessorObj).staticOffset;
 479     }
 480 
 481     @ForceInline


src/share/classes/java/lang/invoke/DirectMethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File