jdk/src/share/classes/java/dyn/CallSite.java
changeset 5722 4ada807383c8
parent 4537 7c3c7f8d5195
child 5725 16c1792b2ee6
equal deleted inserted replaced
5371:ff9031a745d9 5722:4ada807383c8
     1 /*
     1 /*
     2  * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
     2  * Copyright 2008-2010 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Sun designates this
     7  * published by the Free Software Foundation.  Sun designates this
    23  * have any questions.
    23  * have any questions.
    24  */
    24  */
    25 
    25 
    26 package java.dyn;
    26 package java.dyn;
    27 
    27 
    28 import sun.dyn.util.BytecodeName;
       
    29 import sun.dyn.Access;
    28 import sun.dyn.Access;
       
    29 import sun.dyn.MemberName;
    30 import sun.dyn.CallSiteImpl;
    30 import sun.dyn.CallSiteImpl;
    31 import sun.dyn.MethodHandleImpl;
       
    32 
    31 
    33 /**
    32 /**
    34  * An {@code invokedynamic} call site, as reified by the
    33  * A {@code CallSite} reifies an {@code invokedynamic} instruction from bytecode,
    35  * containing class's bootstrap method.
    34  * and controls its linkage.
    36  * Every call site object corresponds to a distinct instance
    35  * Every linked {@code CallSite} object corresponds to a distinct instance
    37  * of the <code>invokedynamic</code> instruction, and vice versa.
    36  * of the {@code invokedynamic} instruction, and vice versa.
    38  * Every call site has one state variable, called the {@code target}.
    37  * <p>
    39  * It is typed as a {@link MethodHandle}.  This state is never null, and
    38  * Every linked {@code CallSite} object has one state variable,
    40  * it is the responsibility of the bootstrap method to produce call sites
    39  * a {@link MethodHandle} reference called the {@code target}.
    41  * which have been pre-linked to an initial target method.
    40  * This reference is never null.  Though it can change its value
    42  * <p>
    41  * successive values must always have exactly the {@link MethodType method type}
    43  * (Note:  The bootstrap method may elect to produce call sites of a
    42  * called for by the bytecodes of the associated {@code invokedynamic} instruction
       
    43  * <p>
       
    44  * It is the responsibility of each class's
       
    45  * {@link Linkage#registerBootstrapMethod(Class, MethodHandle) bootstrap method}
       
    46  * to produce call sites which have been pre-linked to an initial target method.
       
    47  * The required {@link MethodType type} for the target method is a parameter
       
    48  * to each bootstrap method call.
       
    49  * <p>
       
    50  * The bootstrap method may elect to produce call sites of a
    44  * language-specific subclass of {@code CallSite}.  In such a case,
    51  * language-specific subclass of {@code CallSite}.  In such a case,
    45  * the subclass may claim responsibility for initializing its target to
    52  * the subclass may claim responsibility for initializing its target to
    46  * a non-null value, by overriding {@link #initialTarget}.)
    53  * a non-null value, by overriding {@link #initialTarget}.
    47  * <p>
    54  * <p>
    48  * An {@code invokedynamic} instruction which has not yet been executed
    55  * An {@code invokedynamic} instruction which has not yet been executed
    49  * is said to be <em>unlinked</em>.  When an unlinked call site is executed,
    56  * is said to be <em>unlinked</em>.  When an unlinked call site is executed,
    50  * the containing class's bootstrap method is called to manufacture a call site,
    57  * the containing class's bootstrap method is called to manufacture a call site,
    51  * for the instruction.  If the bootstrap method does not assign a non-null
    58  * for the instruction.  If the bootstrap method does not assign a non-null
    52  * value to the new call site's target variable, the method {@link #initialTarget}
    59  * value to the new call site's target variable, the method {@link #initialTarget}
    53  * is called to produce the new call site's first target method.
    60  * is called to produce the new call site's first target method.
    54  * <p>
    61  * <p>
       
    62  * A freshly-created {@code CallSite} object is not yet in a linked state.
       
    63  * An unlinked {@code CallSite} object reports null for its {@code callerClass}.
       
    64  * When the JVM receives a {@code CallSite} object from a bootstrap method,
       
    65  * it first ensures that its target is non-null and of the correct type.
       
    66  * The JVM then links the {@code CallSite} object to the call site instruction,
       
    67  * enabling the {@code callerClass} to return the class in which the instruction occurs.
       
    68  * <p>
       
    69  * Next, the JVM links the instruction to the {@code CallSite}, at which point
       
    70  * any further execution of the {@code invokedynamic} instruction implicitly
       
    71  * invokes the current target of the {@code CallSite} object.
       
    72  * After this two-way linkage, both the instruction and the {@code CallSite}
       
    73  * object are said to be linked.
       
    74  * <p>
       
    75  * This state of linkage continues until the method containing the
       
    76  * dynamic call site is garbage collected, or the dynamic call site
       
    77  * is invalidated by an explicit request.
       
    78  * <p>
       
    79  * Linkage happens once in the lifetime of any given {@code CallSite} object.
       
    80  * Because of call site invalidation, this linkage can be repeated for
       
    81  * a single {@code invokedynamic} instruction, with multiple {@code CallSite} objects.
       
    82  * When a {@code CallSite} is unlinked from an {@code invokedynamic} instruction,
       
    83  * the instruction is reset so that it is no longer associated with
       
    84  * the {@code CallSite} object, but the {@code CallSite} does not change
       
    85  * state.
       
    86  * <p>
       
    87  * Here is a sample use of call sites and bootstrap methods which links every
       
    88  * dynamic call site to print its arguments:
       
    89 <blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java -->
       
    90 private static void printArgs(Object... args) {
       
    91   System.out.println(java.util.Arrays.deepToString(args));
       
    92 }
       
    93 private static final MethodHandle printArgs;
       
    94 static {
       
    95   MethodHandles.Lookup lookup = MethodHandles.lookup();
       
    96   Class thisClass = lookup.lookupClass();  // (who am I?)
       
    97   printArgs = lookup.findStatic(thisClass,
       
    98       "printArgs", MethodType.methodType(void.class, Object[].class));
       
    99   Linkage.registerBootstrapMethod("bootstrapDynamic");
       
   100 }
       
   101 private static CallSite bootstrapDynamic(Class caller, String name, MethodType type) {
       
   102   // ignore caller and name, but match the type:
       
   103   return new CallSite(MethodHandles.collectArguments(printArgs, type));
       
   104 }
       
   105 </pre></blockquote>
    55  * @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
   106  * @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
    56  * @author John Rose, JSR 292 EG
   107  * @author John Rose, JSR 292 EG
    57  */
   108  */
    58 public class CallSite
   109 public class CallSite
    59         // Note: This is an implementation inheritance hack, and will be removed
       
    60         // with a JVM change which moves the required hidden state onto this class.
       
    61         extends CallSiteImpl
       
    62 {
   110 {
    63     private static final Access IMPL_TOKEN = Access.getToken();
   111     private static final Access IMPL_TOKEN = Access.getToken();
    64 
   112 
    65     /*
       
    66 
       
    67     // Fields used only by the JVM.  Do not use or change.
   113     // Fields used only by the JVM.  Do not use or change.
    68     private Object vmmethod;
   114     private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
    69     int callerMID, callerBCI;  // supplied by the JVM
   115     private int        vmindex;  // supplied by the JVM (BCI within calling method)
    70 
   116 
       
   117     // The actual payload of this call site:
    71     private MethodHandle target;
   118     private MethodHandle target;
    72 
   119 
    73     final Object caller;  // usually a class
   120     // Remove this field for PFD and delete deprecated methods:
    74     final String name;
   121     private MemberName calleeNameRemoveForPFD;
    75     final MethodType type;
   122 
    76     */
   123     /**
    77 
   124      * Make a blank call site object.
    78     /**
   125      * Before it is returned from a bootstrap method, this {@code CallSite} object
    79      * Make a call site given the parameters from a call to the bootstrap method.
   126      * must be provided with
    80      * The resulting call site is in an unlinked state, which means that before
   127      * a target method via a call to {@link CallSite#setTarget(MethodHandle) setTarget},
    81      * it is returned from a bootstrap method call it must be provided with
   128      * or by a subclass override of {@link CallSite#initialTarget(Class,String,MethodType) initialTarget}.
    82      * a target method via a call to {@link CallSite#setTarget}.
   129      */
    83      * @param caller the class in which the relevant {@code invokedynamic} instruction occurs
   130     public CallSite() {
    84      * @param name the name specified by the {@code invokedynamic} instruction
   131     }
    85      * @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
   132 
    86      */
   133     /**
    87     public CallSite(Object caller, String name, MethodType type) {
   134      * Make a blank call site object, possibly equipped with an initial target method handle.
    88         super(IMPL_TOKEN, caller, name, type);
   135      * The initial target reference may be null, in which case the {@code CallSite} object
    89     }
   136      * must be provided with a target method via a call to {@link CallSite#setTarget},
    90 
   137      * or by a subclass override of {@link CallSite#initialTarget}.
    91     private static void privateInitializeCallSite(CallSite site, int callerMID, int callerBCI) {
   138      * @param target the method handle which will be the initial target of the call site, or null if there is none yet
    92         site.callerMID = callerMID;
   139      */
    93         site.callerBCI = callerBCI;
   140     public CallSite(MethodHandle target) {
    94         site.ensureTarget();
   141         this.target = target;
    95     }
   142     }
    96     private void ensureTarget() {
   143 
    97         // Note use of super, which accesses the field directly,
   144     /** @deprecated transitional form defined in EDR but removed in PFD */
    98         // without deferring to possible subclass overrides.
   145     public CallSite(Class<?> caller, String name, MethodType type) {
    99         if (super.getTarget() == null) {
   146         this.calleeNameRemoveForPFD = new MemberName(caller, name, type);
   100             super.setTarget(this.initialTarget());
   147     }
   101             super.getTarget().type();  // provoke NPE if still null
   148     /** @deprecated transitional form defined in EDR but removed in PFD */
   102         }
   149     public Class<?> callerClass() {
       
   150         MemberName callee = this.calleeNameRemoveForPFD;
       
   151         return callee == null ? null : callee.getDeclaringClass();
       
   152     }
       
   153     /** @deprecated transitional form defined in EDR but removed in PFD */
       
   154     public String name() {
       
   155         MemberName callee = this.calleeNameRemoveForPFD;
       
   156         return callee == null ? null : callee.getName();
       
   157     }
       
   158     /** @deprecated transitional form defined in EDR but removed in PFD */
       
   159     public MethodType type() {
       
   160         MemberName callee = this.calleeNameRemoveForPFD;
       
   161         return callee == null ? (target == null ? null : target.type()) : callee.getMethodType();
       
   162     }
       
   163     /** @deprecated transitional form defined in EDR but removed in PFD */
       
   164     protected MethodHandle initialTarget() {
       
   165         return initialTarget(callerClass(), name(), type());
       
   166     }
       
   167 
       
   168     /** Report if the JVM has linked this {@code CallSite} object to a dynamic call site instruction.
       
   169      *  Once it is linked, it is never unlinked.
       
   170      */
       
   171     private boolean isLinked() {
       
   172         return vmmethod != null;
       
   173     }
       
   174 
       
   175     /** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite.
       
   176      *  The parameters are JVM-specific.
       
   177      */
       
   178     void initializeFromJVM(String name,
       
   179                            MethodType type,
       
   180                            MemberName callerMethod,
       
   181                            int        callerBCI) {
       
   182         if (this.isLinked()) {
       
   183             throw new InvokeDynamicBootstrapError("call site has already been linked to an invokedynamic instruction");
       
   184         }
       
   185         MethodHandle target = this.target;
       
   186         if (target == null) {
       
   187             this.target = target = this.initialTarget(callerMethod.getDeclaringClass(), name, type);
       
   188         }
       
   189         if (!target.type().equals(type)) {
       
   190             throw wrongTargetType(target, type);
       
   191         }
       
   192         this.vmindex  = callerBCI;
       
   193         this.vmmethod = callerMethod;
       
   194         assert(this.isLinked());
   103     }
   195     }
   104 
   196 
   105     /**
   197     /**
   106      * Just after a call site is created by a bootstrap method handle,
   198      * Just after a call site is created by a bootstrap method handle,
   107      * if the target has not been initialized by the factory method itself,
   199      * if the target has not been initialized by the factory method itself,
   108      * the method {@code initialTarget} is called to produce an initial
   200      * the method {@code initialTarget} is called to produce an initial
   109      * non-null target.  (Live call sites must never have null targets.)
   201      * non-null target.  (Live call sites must never have null targets.)
       
   202      * <p>
       
   203      * The arguments are the same as those passed to the bootstrap method.
       
   204      * Thus, a bootstrap method is free to ignore the arguments and simply
       
   205      * create a "blank" {@code CallSite} object of an appropriate subclass.
   110      * <p>
   206      * <p>
   111      * If the bootstrap method itself does not initialize the call site,
   207      * If the bootstrap method itself does not initialize the call site,
   112      * this method must be overridden, because it just raises an
   208      * this method must be overridden, because it just raises an
   113      * {@code InvokeDynamicBootstrapError}, which in turn causes the
   209      * {@code InvokeDynamicBootstrapError}, which in turn causes the
   114      * linkage of the {@code invokedynamic} instruction to terminate
   210      * linkage of the {@code invokedynamic} instruction to terminate
   115      * abnormally.
   211      * abnormally.
   116      */
   212      */
   117     protected MethodHandle initialTarget() {
   213     protected MethodHandle initialTarget(Class<?> callerClass, String name, MethodType type) {
   118         throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+this);
   214         throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+name+type);
   119     }
   215     }
   120 
   216 
   121     /**
   217     /**
   122      * Report the current linkage state of the call site.  (This is mutable.)
   218      * Report the current linkage state of the call site.  (This is mutable.)
   123      * The value may not be null after the {@code CallSite} object is returned
   219      * The value may not be null after the {@code CallSite} object is returned
   135      * a recent update to the target by another thread.
   231      * a recent update to the target by another thread.
   136      * @return the current linkage state of the call site
   232      * @return the current linkage state of the call site
   137      * @see #setTarget
   233      * @see #setTarget
   138      */
   234      */
   139     public MethodHandle getTarget() {
   235     public MethodHandle getTarget() {
   140         return super.getTarget();
   236         return target;
   141     }
   237     }
   142 
   238 
   143     /**
   239     /**
   144      * Link or relink the call site, by setting its target method.
   240      * Set the target method of this call site.
   145      * <p>
   241      * <p>
   146      * The interactions of {@code setTarget} with memory are the same
   242      * The interactions of {@code setTarget} with memory are the same
   147      * as of a write to an ordinary variable, such as an array element or a
   243      * as of a write to an ordinary variable, such as an array element or a
   148      * non-volatile, non-final field.
   244      * non-volatile, non-final field.
   149      * <p>
   245      * <p>
   150      * In particular, unrelated threads may fail to see the updated target
   246      * In particular, unrelated threads may fail to see the updated target
   151      * until they perform a read from memory.
   247      * until they perform a read from memory.
   152      * Stronger guarantees can be created by putting appropriate operations
   248      * Stronger guarantees can be created by putting appropriate operations
   153      * into the bootstrap method and/or the target methods used
   249      * into the bootstrap method and/or the target methods used
   154      * at any given call site.
   250      * at any given call site.
   155      * @param target the new target, or null if it is to be unlinked
   251      * @param newTarget the new target
   156      * @throws NullPointerException if the proposed new target is null
   252      * @throws NullPointerException if the proposed new target is null
   157      * @throws WrongMethodTypeException if the proposed new target
   253      * @throws WrongMethodTypeException if the call site is linked and the proposed new target
   158      *         has a method type that differs from the call site's {@link #type()}
   254      *         has a method type that differs from the previous target
   159      */
   255      */
   160     public void setTarget(MethodHandle target) {
   256     public void setTarget(MethodHandle newTarget) {
   161         checkTarget(target);
   257         MethodType newType = newTarget.type();  // null check!
   162         super.setTarget(target);
   258         MethodHandle oldTarget = this.target;
   163     }
   259         if (oldTarget == null) {
   164 
   260             // CallSite is not yet linked.
   165     protected void checkTarget(MethodHandle target) {
   261             assert(!isLinked());
   166         target.type();  // provoke NPE
   262             this.target = newTarget;  // might be null!
   167         if (!canSetTarget(target))
   263             return;
   168             throw new WrongMethodTypeException(String.valueOf(target)+target.type()+" should be of type "+type());
   264         }
   169     }
   265         MethodType oldType = oldTarget.type();
   170 
   266         if (!newTarget.type().equals(oldType))
   171     protected boolean canSetTarget(MethodHandle target) {
   267             throw wrongTargetType(newTarget, oldType);
   172         return (target != null && target.type() == type());
   268         if (oldTarget != newTarget)
   173     }
   269             CallSiteImpl.setCallSiteTarget(IMPL_TOKEN, this, newTarget);
   174 
   270     }
   175     /**
   271 
   176      * Report the class containing the call site.
   272     private static WrongMethodTypeException wrongTargetType(MethodHandle target, MethodType type) {
   177      * This is an immutable property of the call site, set from the first argument to the constructor.
   273         return new WrongMethodTypeException(String.valueOf(target)+target.type()+" should be of type "+type);
   178      * @return class containing the call site
   274     }
   179      */
   275 
   180     public Class<?> callerClass() {
   276     /** Produce a printed representation that displays information about this call site
   181         return (Class) caller;
   277      *  that may be useful to the human reader.
   182     }
   278      */
   183 
       
   184     /**
       
   185      * Report the method name specified in the {@code invokedynamic} instruction.
       
   186      * This is an immutable property of the call site, set from the second argument to the constructor.
       
   187      * <p>
       
   188      * Note that the name is a JVM bytecode name, and as such can be any
       
   189      * non-empty string, as long as it does not contain certain "dangerous"
       
   190      * characters such as slash {@code '/'} and dot {@code '.'}.
       
   191      * See the Java Virtual Machine specification for more details.
       
   192      * <p>
       
   193      * Application such as a language runtimes may need to encode
       
   194      * arbitrary program element names and other configuration information
       
   195      * into the name.  A standard convention for doing this is
       
   196      * <a href="http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm">specified here</a>.
       
   197      * @return method name specified by the call site
       
   198      */
       
   199     public String name() {
       
   200         return name;
       
   201     }
       
   202 
       
   203     /**
       
   204      * Report the method name specified in the {@code invokedynamic} instruction,
       
   205      * as a series of components, individually demangled according to
       
   206      * the standard convention
       
   207      * <a href="http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm">specified here</a>.
       
   208      * <p>
       
   209      * Non-empty runs of characters between dangerous characters are demangled.
       
   210      * Each component is either a completely arbitrary demangled string,
       
   211      * or else a character constant for a punctuation character, typically ':'.
       
   212      * (In principle, the character can be any dangerous character that the
       
   213      * JVM lets through in a method name, such as '$' or ']'.
       
   214      * Runtime implementors are encouraged to use colon ':' for building
       
   215      * structured names.)
       
   216      * <p>
       
   217      * In the common case where the name contains no dangerous characters,
       
   218      * the result is an array whose only element array is the demangled
       
   219      * name at the call site.  Such a demangled name can be any sequence
       
   220      * of any number of any unicode characters.
       
   221      * @return method name components specified by the call site
       
   222      */
       
   223     public Object[] nameComponents() {
       
   224         return BytecodeName.parseBytecodeName(name);
       
   225     }
       
   226 
       
   227     /**
       
   228      * Report the resolved result and parameter types of this call site,
       
   229      * which are derived from its bytecode-level invocation descriptor.
       
   230      * The types are packaged into a {@link MethodType}.
       
   231      * Any linked target of this call site must be exactly this method type.
       
   232      * This is an immutable property of the call site, set from the third argument to the constructor.
       
   233      * @return method type specified by the call site
       
   234      */
       
   235     public MethodType type() {
       
   236         return type;
       
   237     }
       
   238 
       
   239     @Override
   279     @Override
   240     public String toString() {
   280     public String toString() {
   241         return "CallSite#"+hashCode()+"["+name+type+" => "+getTarget()+"]";
   281         StringBuilder buf = new StringBuilder("CallSite#");
   242     }
   282         buf.append(hashCode());
   243 
   283         if (!isLinked())
   244     // Package-local constant:
   284             buf.append("[unlinked]");
   245     static final MethodHandle GET_TARGET = MethodHandleImpl.getLookup(IMPL_TOKEN).
   285         else
   246             findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
   286             buf.append("[")
   247 }
   287                 .append("from ").append(vmmethod.getDeclaringClass().getName())
       
   288                 .append(" : ").append(getTarget().type())
       
   289                 .append(" => ").append(getTarget())
       
   290                 .append("]");
       
   291         return buf.toString();
       
   292     }
       
   293 }