jdk/src/share/classes/sun/dyn/CallSiteImpl.java
changeset 5722 4ada807383c8
parent 4537 7c3c7f8d5195
child 5725 16c1792b2ee6
equal deleted inserted replaced
5371:ff9031a745d9 5722:4ada807383c8
    24  */
    24  */
    25 
    25 
    26 package sun.dyn;
    26 package sun.dyn;
    27 
    27 
    28 import java.dyn.*;
    28 import java.dyn.*;
    29 import java.util.logging.Level;
       
    30 import java.util.logging.Logger;
       
    31 
    29 
    32 /**
    30 /**
    33  * Parts of CallSite known to the JVM.
    31  * Parts of CallSite known to the JVM.
    34  * FIXME: Merge all this into CallSite proper.
       
    35  * @author jrose
    32  * @author jrose
    36  */
    33  */
    37 public class CallSiteImpl {
    34 public class CallSiteImpl {
    38     // Field used only by the JVM.  Do not use or change.
    35     // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
    39     private Object vmmethod;
    36     static CallSite makeSite(MethodHandle bootstrapMethod,
    40 
    37                              // Callee information:
    41     // Values supplied by the JVM:
    38                              String name, MethodType type,
    42     protected int callerMID, callerBCI;
    39                              // Call-site attributes, if any:
    43 
    40                              Object info,
    44     private MethodHandle target;
    41                              // Caller information:
    45     protected final Object caller;  // usually a class
    42                              MemberName callerMethod, int callerBCI) {
    46     protected final String name;
    43         Class<?> caller = callerMethod.getDeclaringClass();
    47     protected final MethodType type;
    44         if (bootstrapMethod == null) {
    48 
    45             // If there is no bootstrap method, throw IncompatibleClassChangeError.
    49     /** called only directly from CallSite() */
    46             // This is a valid generic error type for resolution (JLS 12.3.3).
    50     protected CallSiteImpl(Access token, Object caller, String name, MethodType type) {
    47             throw new IncompatibleClassChangeError
    51         Access.check(token);
    48                 ("Class "+caller.getName()+" has not declared a bootstrap method for invokedynamic");
    52         this.caller = caller;
    49         }
    53         this.name = name;
       
    54         this.type = type;
       
    55     }
       
    56 
       
    57     /** native version of setTarget */
       
    58     protected void setTarget(MethodHandle mh) {
       
    59         //System.out.println("setTarget "+this+" := "+mh);
       
    60         // XXX I don't know how to fix this properly.
       
    61 //         if (false && MethodHandleNatives.JVM_SUPPORT) // FIXME: enable this
       
    62 //             MethodHandleNatives.linkCallSite(this, mh);
       
    63 //         else
       
    64             this.target = mh;
       
    65     }
       
    66 
       
    67     protected MethodHandle getTarget() {
       
    68         return target;
       
    69     }
       
    70 
       
    71     private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE =
       
    72             MethodHandleImpl.IMPL_LOOKUP.findStatic(CallSite.class, "privateInitializeCallSite",
       
    73                 MethodType.methodType(void.class, CallSite.class, int.class, int.class));
       
    74 
       
    75     // this is the up-call from the JVM:
       
    76     static CallSite makeSite(Class<?> caller, String name, MethodType type,
       
    77                              int callerMID, int callerBCI) {
       
    78         MethodHandle bsm = Linkage.getBootstrapMethod(caller);
       
    79         if (bsm == null)
       
    80             throw new InvokeDynamicBootstrapError("class has no bootstrap method: "+caller);
       
    81         CallSite site;
    50         CallSite site;
    82         try {
    51         try {
    83             site = bsm.<CallSite>invoke(caller, name, type);
    52             if (bootstrapMethod.type().parameterCount() == 3)
       
    53                 site = bootstrapMethod.<CallSite>invokeExact(caller, name, type);
       
    54             else if (bootstrapMethod.type().parameterCount() == 4)
       
    55                 site = bootstrapMethod.<CallSite>invokeExact(caller, name, type,
       
    56                                                              !(info instanceof java.lang.annotation.Annotation[]) ? null
       
    57                                                              : (java.lang.annotation.Annotation[]) info);
       
    58             else
       
    59                 throw new InternalError("bad BSM: "+bootstrapMethod);
       
    60             if (!(site instanceof CallSite))
       
    61                 throw new InvokeDynamicBootstrapError("class bootstrap method failed to create a call site: "+caller);
       
    62             PRIVATE_INITIALIZE_CALL_SITE.<void>invokeExact(site,
       
    63                                                            name, type,
       
    64                                                            callerMethod, callerBCI);
       
    65             assert(site.getTarget() != null);
       
    66             assert(site.getTarget().type().equals(type));
    84         } catch (Throwable ex) {
    67         } catch (Throwable ex) {
    85             throw new InvokeDynamicBootstrapError("exception thrown while linking", ex);
    68             InvokeDynamicBootstrapError bex;
    86         }
    69             if (ex instanceof InvokeDynamicBootstrapError)
    87         if (site == null)
    70                 bex = (InvokeDynamicBootstrapError) ex;
    88             throw new InvokeDynamicBootstrapError("class bootstrap method failed to create a call site: "+caller);
    71             else
    89         if (site.type() != type)
    72                 bex = new InvokeDynamicBootstrapError("call site initialization exception", ex);
    90             throw new InvokeDynamicBootstrapError("call site type not initialized correctly: "+site);
    73             throw bex;
    91         if (site.callerClass() != caller)
       
    92             throw new InvokeDynamicBootstrapError("call site caller not initialized correctly: "+site);
       
    93         if ((Object)site.name() != name)
       
    94             throw new InvokeDynamicBootstrapError("call site name not initialized correctly: "+site);
       
    95         try {
       
    96             PRIVATE_INITIALIZE_CALL_SITE.<void>invoke(site, callerMID, callerBCI);
       
    97         } catch (Throwable ex) {
       
    98             throw new InvokeDynamicBootstrapError("call site initialization exception", ex);
       
    99         }
    74         }
   100         return site;
    75         return site;
   101     }
    76     }
       
    77 
       
    78     // This method is private in CallSite because it touches private fields in CallSite.
       
    79     // These private fields (vmmethod, vmindex) are specific to the JVM.
       
    80     private static final MethodHandle PRIVATE_INITIALIZE_CALL_SITE =
       
    81             MethodHandleImpl.IMPL_LOOKUP.findVirtual(CallSite.class, "initializeFromJVM",
       
    82                 MethodType.methodType(void.class,
       
    83                                       String.class, MethodType.class,
       
    84                                       MemberName.class, int.class));
       
    85 
       
    86     public static void setCallSiteTarget(Access token, CallSite site, MethodHandle target) {
       
    87         Access.check(token);
       
    88         MethodHandleNatives.setCallSiteTarget(site, target);
       
    89     }
   102 }
    90 }