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 9490 : 8037210: Get rid of char-based descriptions 'J' of basic types
Reviewed-by: jrose, ?
rev 9491 : [mq]: meth-btype.1


  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import sun.misc.Unsafe;
  29 import java.lang.reflect.Method;
  30 import java.util.Arrays;
  31 import sun.invoke.util.VerifyAccess;
  32 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  33 import static java.lang.invoke.LambdaForm.*;

  34 import static java.lang.invoke.MethodTypeForm.*;
  35 import static java.lang.invoke.MethodHandleStatics.*;
  36 import java.lang.ref.WeakReference;
  37 import java.lang.reflect.Field;
  38 import sun.invoke.util.ValueConversions;
  39 import sun.invoke.util.VerifyType;
  40 import sun.invoke.util.Wrapper;
  41 
  42 /**
  43  * The flavor of method handle which implements a constant reference
  44  * to a class member.
  45  * @author jrose
  46  */
  47 class DirectMethodHandle extends MethodHandle {
  48     final MemberName member;
  49 
  50     // Constructors and factory methods in this class *must* be package scoped or private.
  51     private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
  52         super(mtype, form);
  53         if (!member.isResolved())  throw new InternalError();


 108     }
 109     static DirectMethodHandle make(Method method) {
 110         return make(method.getDeclaringClass(), new MemberName(method));
 111     }
 112     static DirectMethodHandle make(Field field) {
 113         return make(field.getDeclaringClass(), new MemberName(field));
 114     }
 115     private static DirectMethodHandle makeAllocator(MemberName ctor) {
 116         assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
 117         Class<?> instanceClass = ctor.getDeclaringClass();
 118         ctor = ctor.asConstructor();
 119         assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
 120         MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
 121         LambdaForm lform = preparedLambdaForm(ctor);
 122         MemberName init = ctor.asSpecial();
 123         assert(init.getMethodType().returnType() == void.class);
 124         return new Constructor(mtype, lform, ctor, init, instanceClass);
 125     }
 126 
 127     @Override
 128     MethodHandle copyWith(MethodType mt, LambdaForm lf) {
 129         return new DirectMethodHandle(mt, lf, member);
 130     }
 131 
 132     @Override
 133     String internalProperties() {
 134         return "/DMH="+member.toString();
 135     }
 136 
 137     //// Implementation methods.
 138     @Override
 139     MethodHandle viewAsType(MethodType newType) {
 140         return new DirectMethodHandle(newType, form, member);
 141     }
 142     @Override
 143     @ForceInline
 144     MemberName internalMemberName() {
 145         return member;
 146     }
 147 
 148     @Override
 149     MethodHandle bindArgument(int pos, char basicType, Object value) {
 150         // If the member needs dispatching, do so.
 151         if (pos == 0 && basicType == 'L') {
 152             DirectMethodHandle concrete = maybeRebind(value);
 153             if (concrete != null)
 154                 return concrete.bindReceiver(value);
 155         }
 156         return super.bindArgument(pos, basicType, value);
 157     }
 158 
 159     @Override
 160     MethodHandle bindReceiver(Object receiver) {
 161         // If the member needs dispatching, do so.
 162         DirectMethodHandle concrete = maybeRebind(receiver);
 163         if (concrete != null)
 164             return concrete.bindReceiver(receiver);
 165         return super.bindReceiver(receiver);
 166     }
 167 
 168     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
 169 
 170     private DirectMethodHandle maybeRebind(Object receiver) {
 171         if (receiver != null) {


 257         assert(names.length == nameCursor);
 258         if (doesAlloc) {
 259             // names = { argx,y,z,... new C, init method }
 260             names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
 261             names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
 262         } else if (needsInit) {
 263             names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
 264         } else {
 265             names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
 266         }
 267         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
 268         assert(outArgs[outArgs.length-1] == names[GET_MEMBER]);  // look, shifted args!
 269         int result = LambdaForm.LAST_RESULT;
 270         if (doesAlloc) {
 271             assert(outArgs[outArgs.length-2] == names[NEW_OBJ]);  // got to move this one
 272             System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
 273             outArgs[0] = names[NEW_OBJ];
 274             result = NEW_OBJ;
 275         }
 276         names[LINKER_CALL] = new Name(linker, outArgs);
 277         lambdaName += "_" + LambdaForm.basicTypeSignature(mtype);
 278         LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
 279         // This is a tricky bit of code.  Don't send it through the LF interpreter.
 280         lform.compileToBytecode();
 281         return lform;
 282     }
 283 
 284     private static void maybeCompile(LambdaForm lform, MemberName m) {
 285         if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
 286             // Help along bootstrapping...
 287             lform.compileToBytecode();
 288     }
 289 
 290     /** Static wrapper for DirectMethodHandle.internalMemberName. */
 291     @ForceInline
 292     /*non-public*/ static Object internalMemberName(Object mh) {
 293         return ((DirectMethodHandle)mh).member;
 294     }
 295 
 296     /** Static wrapper for DirectMethodHandle.internalMemberName.
 297      * This one also forces initialization.




  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import sun.misc.Unsafe;
  29 import java.lang.reflect.Method;
  30 import java.util.Arrays;
  31 import sun.invoke.util.VerifyAccess;
  32 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  33 import static java.lang.invoke.LambdaForm.*;
  34 import static java.lang.invoke.LambdaForm.BasicType.*;
  35 import static java.lang.invoke.MethodTypeForm.*;
  36 import static java.lang.invoke.MethodHandleStatics.*;
  37 import java.lang.ref.WeakReference;
  38 import java.lang.reflect.Field;
  39 import sun.invoke.util.ValueConversions;
  40 import sun.invoke.util.VerifyType;
  41 import sun.invoke.util.Wrapper;
  42 
  43 /**
  44  * The flavor of method handle which implements a constant reference
  45  * to a class member.
  46  * @author jrose
  47  */
  48 class DirectMethodHandle extends MethodHandle {
  49     final MemberName member;
  50 
  51     // Constructors and factory methods in this class *must* be package scoped or private.
  52     private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
  53         super(mtype, form);
  54         if (!member.isResolved())  throw new InternalError();


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





 129     String internalProperties() {
 130         return "/DMH="+member.toString();
 131     }
 132 
 133     //// Implementation methods.
 134     @Override
 135     MethodHandle viewAsType(MethodType newType) {
 136         return new DirectMethodHandle(newType, form, member);
 137     }
 138     @Override
 139     @ForceInline
 140     MemberName internalMemberName() {
 141         return member;
 142     }
 143 
 144     @Override
 145     MethodHandle bindArgument(int pos, BasicType basicType, Object value) {
 146         // If the member needs dispatching, do so.
 147         if (pos == 0 && basicType == L_TYPE) {
 148             DirectMethodHandle concrete = maybeRebind(value);
 149             if (concrete != null)
 150                 return concrete.bindReceiver(value);
 151         }
 152         return super.bindArgument(pos, basicType, value);
 153     }
 154 
 155     @Override
 156     MethodHandle bindReceiver(Object receiver) {
 157         // If the member needs dispatching, do so.
 158         DirectMethodHandle concrete = maybeRebind(receiver);
 159         if (concrete != null)
 160             return concrete.bindReceiver(receiver);
 161         return super.bindReceiver(receiver);
 162     }
 163 
 164     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
 165 
 166     private DirectMethodHandle maybeRebind(Object receiver) {
 167         if (receiver != null) {


 253         assert(names.length == nameCursor);
 254         if (doesAlloc) {
 255             // names = { argx,y,z,... new C, init method }
 256             names[NEW_OBJ] = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
 257             names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
 258         } else if (needsInit) {
 259             names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
 260         } else {
 261             names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
 262         }
 263         Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
 264         assert(outArgs[outArgs.length-1] == names[GET_MEMBER]);  // look, shifted args!
 265         int result = LambdaForm.LAST_RESULT;
 266         if (doesAlloc) {
 267             assert(outArgs[outArgs.length-2] == names[NEW_OBJ]);  // got to move this one
 268             System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
 269             outArgs[0] = names[NEW_OBJ];
 270             result = NEW_OBJ;
 271         }
 272         names[LINKER_CALL] = new Name(linker, outArgs);
 273         lambdaName += "_" + shortenSignature(basicTypeSignature(mtype));
 274         LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
 275         // This is a tricky bit of code.  Don't send it through the LF interpreter.
 276         lform.compileToBytecode();
 277         return lform;
 278     }
 279 
 280     private static void maybeCompile(LambdaForm lform, MemberName m) {
 281         if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
 282             // Help along bootstrapping...
 283             lform.compileToBytecode();
 284     }
 285 
 286     /** Static wrapper for DirectMethodHandle.internalMemberName. */
 287     @ForceInline
 288     /*non-public*/ static Object internalMemberName(Object mh) {
 289         return ((DirectMethodHandle)mh).member;
 290     }
 291 
 292     /** Static wrapper for DirectMethodHandle.internalMemberName.
 293      * This one also forces initialization.


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