CallSite.java 9.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
/*
 * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package java.dyn;

import sun.dyn.util.BytecodeName;

/**
31 32 33 34 35 36 37 38
 * An {@code invokedynamic} call site, as reified by the
 * containing class's bootstrap method.
 * Every call site object corresponds to a distinct instance
 * of the <code>invokedynamic</code> instruction, and vice versa.
 * Every call site has one state variable, called the {@code target}.
 * It is typed as a {@link MethodHandle}.  This state is never null, and
 * it is the responsibility of the bootstrap method to produce call sites
 * which have been pre-linked to an initial target method.
39
 * <p>
40 41 42 43
 * (Note:  The bootstrap method may elect to produce call sites of a
 * language-specific subclass of {@code CallSite}.  In such a case,
 * the subclass may claim responsibility for initializing its target to
 * a non-null value, by overriding {@link #initialTarget}.)
44
 * <p>
45 46 47 48 49 50 51 52
 * An {@code invokedynamic} instruction which has not yet been executed
 * is said to be <em>unlinked</em>.  When an unlinked call site is executed,
 * the containing class's bootstrap method is called to manufacture a call site,
 * for the instruction.  If the bootstrap method does not assign a non-null
 * value to the new call site's target variable, the method {@link #initialTarget}
 * is called to produce the new call site's first target method.
 * <p>
 * @see Linkage#registerBootstrapMethod(java.lang.Class, java.dyn.MethodHandle)
53 54 55 56 57 58 59 60 61 62 63 64
 * @author John Rose, JSR 292 EG
 */
public class CallSite {
    // Fields used only by the JVM.  Do not use or change.
    private Object vmmethod;
    int callerMID, callerBCI;  // supplied by the JVM

    MethodHandle target;
    final Object caller;  // usually a class
    final String name;
    final MethodType type;

65 66 67 68 69 70 71 72 73
    /**
     * Make a call site given the parameters from a call to the bootstrap method.
     * The resulting call site is in an unlinked state, which means that before
     * it is returned from a bootstrap method call it must be provided with
     * a target method via a call to {@link CallSite#setTarget}.
     * @param caller the class in which the relevant {@code invokedynamic} instruction occurs
     * @param name the name specified by the {@code invokedynamic} instruction
     * @param type the method handle type derived from descriptor of the {@code invokedynamic} instruction
     */
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
    public CallSite(Object caller, String name, MethodType type) {
        this.caller = caller;
        this.name = name;
        this.type = type;
    }

    private static void privateInitializeCallSite(CallSite site, int callerMID, int callerBCI) {
        site.callerMID = callerMID;
        site.callerBCI = callerBCI;
        if (site.target == null)
            site.setTarget(site.initialTarget());
    }

    /**
     * Just after a call site is created by a bootstrap method handle,
     * if the target has not been initialized by the factory method itself,
     * the method {@code initialTarget} is called to produce an initial
     * non-null target.  (Live call sites must never have null targets.)
     * <p>
     * If the bootstrap method itself does not initialize the call site,
     * this method must be overridden, because it just raises an
95 96 97
     * {@code InvokeDynamicBootstrapError}, which in turn causes the
     * linkage of the {@code invokedynamic} instruction to terminate
     * abnormally.
98 99 100 101 102 103 104
     */
    protected MethodHandle initialTarget() {
        throw new InvokeDynamicBootstrapError("target must be initialized before call site is linked: "+this);
    }

    /**
     * Report the current linkage state of the call site.  (This is mutable.)
105
     * The value maybe null only if the call site is currently unlinked.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
     * When a linked call site is invoked, the target method is used directly.
     * When an unlinked call site is invoked, its bootstrap method receives
     * the call, as if via {@link Linkage#bootstrapInvokeDynamic}.
     * <p>
     * The interactions of {@code getTarget} with memory are the same
     * as of a read from an ordinary variable, such as an array element or a
     * non-volatile, non-final field.
     * <p>
     * In particular, the current thread may choose to reuse the result
     * of a previous read of the target from memory, and may fail to see
     * a recent update to the target by another thread.
     * @return the current linkage state of the call site
     * @see #setTarget
     */
    public MethodHandle getTarget() {
        return target;
    }

    /**
     * Link or relink the call site, by setting its target method.
     * <p>
     * The interactions of {@code setTarget} with memory are the same
     * as of a write to an ordinary variable, such as an array element or a
     * non-volatile, non-final field.
     * <p>
     * In particular, unrelated threads may fail to see the updated target
     * until they perform a read from memory.
     * Stronger guarantees can be created by putting appropriate operations
     * into the bootstrap method and/or the target methods used
     * at any given call site.
     * @param target the new target, or null if it is to be unlinked
137 138 139
     * @throws NullPointerException if the proposed new target is null
     * @throws WrongMethodTypeException if the proposed new target
     *         has a method type that differs from the call site's {@link #type()}
140 141 142 143 144 145 146
     */
    public void setTarget(MethodHandle target) {
        checkTarget(target);
        this.target = target;
    }

    protected void checkTarget(MethodHandle target) {
147
        target.type();  // provoke NPE
148 149 150 151 152 153 154 155 156 157
        if (!canSetTarget(target))
            throw new WrongMethodTypeException(String.valueOf(target));
    }

    protected boolean canSetTarget(MethodHandle target) {
        return (target != null && target.type() == type());
    }

    /**
     * Report the class containing the call site.
158
     * This is an immutable property of the call site, set from the first argument to the constructor.
159 160 161 162 163 164 165 166
     * @return class containing the call site
     */
    public Class<?> callerClass() {
        return (Class) caller;
    }

    /**
     * Report the method name specified in the {@code invokedynamic} instruction.
167
     * This is an immutable property of the call site, set from the second argument to the constructor.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212
     * <p>
     * Note that the name is a JVM bytecode name, and as such can be any
     * non-empty string, as long as it does not contain certain "dangerous"
     * characters such as slash {@code '/'} and dot {@code '.'}.
     * See the Java Virtual Machine specification for more details.
     * <p>
     * Application such as a language runtimes may need to encode
     * arbitrary program element names and other configuration information
     * into the name.  A standard convention for doing this is
     * <a href="http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm">specified here</a>.
     * @return method name specified by the call site
     */
    public String name() {
        return name;
    }

    /**
     * Report the method name specified in the {@code invokedynamic} instruction,
     * as a series of components, individually demangled according to
     * the standard convention
     * <a href="http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm">specified here</a>.
     * <p>
     * Non-empty runs of characters between dangerous characters are demangled.
     * Each component is either a completely arbitrary demangled string,
     * or else a character constant for a punctuation character, typically ':'.
     * (In principle, the character can be any dangerous character that the
     * JVM lets through in a method name, such as '$' or ']'.
     * Runtime implementors are encouraged to use colon ':' for building
     * structured names.)
     * <p>
     * In the common case where the name contains no dangerous characters,
     * the result is an array whose only element array is the demangled
     * name at the call site.  Such a demangled name can be any sequence
     * of any number of any unicode characters.
     * @return method name components specified by the call site
     */
    public Object[] nameComponents() {
        return BytecodeName.parseBytecodeName(name);
    }

    /**
     * Report the resolved result and parameter types of this call site,
     * which are derived from its bytecode-level invocation descriptor.
     * The types are packaged into a {@link MethodType}.
     * Any linked target of this call site must be exactly this method type.
213
     * This is an immutable property of the call site, set from the third argument to the constructor.
214 215 216 217 218 219 220 221 222 223 224
     * @return method type specified by the call site
     */
    public MethodType type() {
        return type;
    }

    @Override
    public String toString() {
        return "CallSite#"+hashCode()+"["+name+type+" => "+target+"]";
    }
}