src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java
changeset 48354 c96d4c720995
parent 47738 e4d7a32e6a91
equal deleted inserted replaced
48353:315c690bb90b 48354:c96d4c720995
    27 
    27 
    28 import static jdk.dynalink.StandardNamespace.ELEMENT;
    28 import static jdk.dynalink.StandardNamespace.ELEMENT;
    29 import static jdk.dynalink.StandardNamespace.METHOD;
    29 import static jdk.dynalink.StandardNamespace.METHOD;
    30 import static jdk.dynalink.StandardNamespace.PROPERTY;
    30 import static jdk.dynalink.StandardNamespace.PROPERTY;
    31 import static jdk.dynalink.StandardOperation.GET;
    31 import static jdk.dynalink.StandardOperation.GET;
       
    32 import static jdk.dynalink.StandardOperation.REMOVE;
    32 import static jdk.dynalink.StandardOperation.SET;
    33 import static jdk.dynalink.StandardOperation.SET;
    33 
    34 
    34 import java.lang.invoke.MethodHandles;
    35 import java.lang.invoke.MethodHandles;
    35 import java.lang.invoke.MethodHandles.Lookup;
    36 import java.lang.invoke.MethodHandles.Lookup;
    36 import java.lang.invoke.MethodType;
    37 import java.lang.invoke.MethodType;
    61  * The reason we have our own subclass is that we're storing flags in an
    62  * The reason we have our own subclass is that we're storing flags in an
    62  * additional primitive field. The class also exposes some useful utilities in
    63  * additional primitive field. The class also exposes some useful utilities in
    63  * form of static methods.
    64  * form of static methods.
    64  */
    65  */
    65 public final class NashornCallSiteDescriptor extends CallSiteDescriptor {
    66 public final class NashornCallSiteDescriptor extends CallSiteDescriptor {
    66     // Lowest three bits describe the operation
    67     // Lowest four bits describe the operation
    67     /** Property getter operation {@code obj.prop} */
    68     /** Property getter operation {@code obj.prop} */
    68     public static final int GET_PROPERTY        = 0;
    69     public static final int GET_PROPERTY        = 0;
    69     /** Element getter operation {@code obj[index]} */
    70     /** Element getter operation {@code obj[index]} */
    70     public static final int GET_ELEMENT         = 1;
    71     public static final int GET_ELEMENT         = 1;
    71     /** Property getter operation, subsequently invoked {@code obj.prop()} */
    72     /** Property getter operation, subsequently invoked {@code obj.prop()} */
    74     public static final int GET_METHOD_ELEMENT  = 3;
    75     public static final int GET_METHOD_ELEMENT  = 3;
    75     /** Property setter operation {@code obj.prop = value} */
    76     /** Property setter operation {@code obj.prop = value} */
    76     public static final int SET_PROPERTY        = 4;
    77     public static final int SET_PROPERTY        = 4;
    77     /** Element setter operation {@code obj[index] = value} */
    78     /** Element setter operation {@code obj[index] = value} */
    78     public static final int SET_ELEMENT         = 5;
    79     public static final int SET_ELEMENT         = 5;
       
    80     /** Property remove operation {@code delete obj.prop} */
       
    81     public static final int REMOVE_PROPERTY     = 6;
       
    82     /** Element remove operation {@code delete obj[index]} */
       
    83     public static final int REMOVE_ELEMENT      = 7;
    79     /** Call operation {@code fn(args...)} */
    84     /** Call operation {@code fn(args...)} */
    80     public static final int CALL                = 6;
    85     public static final int CALL                = 8;
    81     /** New operation {@code new Constructor(args...)} */
    86     /** New operation {@code new Constructor(args...)} */
    82     public static final int NEW                 = 7;
    87     public static final int NEW                 = 9;
    83 
    88 
    84     private static final int OPERATION_MASK = 7;
    89     private static final int OPERATION_MASK = 15;
    85 
    90 
    86     // Correspond to the operation indices above.
    91     // Correspond to the operation indices above.
    87     private static final Operation[] OPERATIONS = new Operation[] {
    92     private static final Operation[] OPERATIONS = new Operation[] {
    88         GET.withNamespaces(PROPERTY, ELEMENT, METHOD),
    93         GET.withNamespaces(PROPERTY, ELEMENT, METHOD),
    89         GET.withNamespaces(ELEMENT, PROPERTY, METHOD),
    94         GET.withNamespaces(ELEMENT, PROPERTY, METHOD),
    90         GET.withNamespaces(METHOD, PROPERTY, ELEMENT),
    95         GET.withNamespaces(METHOD, PROPERTY, ELEMENT),
    91         GET.withNamespaces(METHOD, ELEMENT, PROPERTY),
    96         GET.withNamespaces(METHOD, ELEMENT, PROPERTY),
    92         SET.withNamespaces(PROPERTY, ELEMENT),
    97         SET.withNamespaces(PROPERTY, ELEMENT),
    93         SET.withNamespaces(ELEMENT, PROPERTY),
    98         SET.withNamespaces(ELEMENT, PROPERTY),
       
    99         REMOVE.withNamespaces(PROPERTY, ELEMENT),
       
   100         REMOVE.withNamespaces(ELEMENT, PROPERTY),
    94         StandardOperation.CALL,
   101         StandardOperation.CALL,
    95         StandardOperation.NEW
   102         StandardOperation.NEW
    96     };
   103     };
    97 
   104 
    98     /** Flags that the call site references a scope variable (it's an identifier reference or a var declaration, not a
   105     /** Flags that the call site references a scope variable (it's an identifier reference or a var declaration, not a
    99      * property access expression. */
   106      * property access expression. */
   100     public static final int CALLSITE_SCOPE         = 1 << 3;
   107     public static final int CALLSITE_SCOPE         = 1 << 4;
   101     /** Flags that the call site is in code that uses ECMAScript strict mode. */
   108     /** Flags that the call site is in code that uses ECMAScript strict mode. */
   102     public static final int CALLSITE_STRICT        = 1 << 4;
   109     public static final int CALLSITE_STRICT        = 1 << 5;
   103     /** Flags that a property getter or setter call site references a scope variable that is located at a known distance
   110     /** Flags that a property getter or setter call site references a scope variable that is located at a known distance
   104      * in the scope chain. Such getters and setters can often be linked more optimally using these assumptions. */
   111      * in the scope chain. Such getters and setters can often be linked more optimally using these assumptions. */
   105     public static final int CALLSITE_FAST_SCOPE    = 1 << 5;
   112     public static final int CALLSITE_FAST_SCOPE    = 1 << 6;
   106     /** Flags that a callsite type is optimistic, i.e. we might get back a wider return value than encoded in the
   113     /** Flags that a callsite type is optimistic, i.e. we might get back a wider return value than encoded in the
   107      * descriptor, and in that case we have to throw an UnwarrantedOptimismException */
   114      * descriptor, and in that case we have to throw an UnwarrantedOptimismException */
   108     public static final int CALLSITE_OPTIMISTIC    = 1 << 6;
   115     public static final int CALLSITE_OPTIMISTIC    = 1 << 7;
   109     /** Is this really an apply that we try to call as a call? */
   116     /** Is this really an apply that we try to call as a call? */
   110     public static final int CALLSITE_APPLY_TO_CALL = 1 << 7;
   117     public static final int CALLSITE_APPLY_TO_CALL = 1 << 8;
   111     /** Does this a callsite for a variable declaration? */
   118     /** Does this a callsite for a variable declaration? */
   112     public static final int CALLSITE_DECLARE       = 1 << 8;
   119     public static final int CALLSITE_DECLARE       = 1 << 9;
   113 
   120 
   114     /** Flags that the call site is profiled; Contexts that have {@code "profile.callsites"} boolean property set emit
   121     /** Flags that the call site is profiled; Contexts that have {@code "profile.callsites"} boolean property set emit
   115      * code where call sites have this flag set. */
   122      * code where call sites have this flag set. */
   116     public static final int CALLSITE_PROFILE         = 1 << 9;
   123     public static final int CALLSITE_PROFILE         = 1 << 10;
   117     /** Flags that the call site is traced; Contexts that have {@code "trace.callsites"} property set emit code where
   124     /** Flags that the call site is traced; Contexts that have {@code "trace.callsites"} property set emit code where
   118      * call sites have this flag set. */
   125      * call sites have this flag set. */
   119     public static final int CALLSITE_TRACE           = 1 << 10;
   126     public static final int CALLSITE_TRACE           = 1 << 11;
   120     /** Flags that the call site linkage miss (and thus, relinking) is traced; Contexts that have the keyword
   127     /** Flags that the call site linkage miss (and thus, relinking) is traced; Contexts that have the keyword
   121      * {@code "miss"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
   128      * {@code "miss"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
   122     public static final int CALLSITE_TRACE_MISSES    = 1 << 11;
   129     public static final int CALLSITE_TRACE_MISSES    = 1 << 12;
   123     /** Flags that entry/exit to/from the method linked at call site are traced; Contexts that have the keyword
   130     /** Flags that entry/exit to/from the method linked at call site are traced; Contexts that have the keyword
   124      * {@code "enterexit"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
   131      * {@code "enterexit"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
   125     public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 12;
   132     public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 13;
   126     /** Flags that values passed as arguments to and returned from the method linked at call site are traced; Contexts
   133     /** Flags that values passed as arguments to and returned from the method linked at call site are traced; Contexts
   127      * that have the keyword {@code "values"} in their {@code "trace.callsites"} property emit code where call sites
   134      * that have the keyword {@code "values"} in their {@code "trace.callsites"} property emit code where call sites
   128      * have this flag set. */
   135      * have this flag set. */
   129     public static final int CALLSITE_TRACE_VALUES    = 1 << 13;
   136     public static final int CALLSITE_TRACE_VALUES    = 1 << 14;
   130 
   137 
   131     //we could have more tracing flags here, for example CALLSITE_TRACE_SCOPE, but bits are a bit precious
   138     //we could have more tracing flags here, for example CALLSITE_TRACE_SCOPE, but bits are a bit precious
   132     //right now given the program points
   139     //right now given the program points
   133 
   140 
   134     /**
   141     /**
   136      * Always one larger than the largest flag shift. Note that introducing a new flag halves the number of program
   143      * Always one larger than the largest flag shift. Note that introducing a new flag halves the number of program
   137      * points we can have.
   144      * points we can have.
   138      * TODO: rethink if we need the various profile/trace flags or the linker can use the Context instead to query its
   145      * TODO: rethink if we need the various profile/trace flags or the linker can use the Context instead to query its
   139      * trace/profile settings.
   146      * trace/profile settings.
   140      */
   147      */
   141     public static final int CALLSITE_PROGRAM_POINT_SHIFT = 14;
   148     public static final int CALLSITE_PROGRAM_POINT_SHIFT = 15;
   142 
   149 
   143     /**
   150     /**
   144      * Maximum program point value. We have 18 bits left over after flags, and
   151      * Maximum program point value. We have 17 bits left over after flags, and
   145      * it should be plenty. Program points are local to a single function. Every
   152      * it should be plenty. Program points are local to a single function. Every
   146      * function maps to a single JVM bytecode method that can have at most 65535
   153      * function maps to a single JVM bytecode method that can have at most 65535
   147      * bytes. (Large functions are synthetically split into smaller functions.)
   154      * bytes. (Large functions are synthetically split into smaller functions.)
   148      * A single invokedynamic is 5 bytes; even if a method consists of only
   155      * A single invokedynamic is 5 bytes; even if a method consists of only
   149      * invokedynamic instructions that leaves us with at most 65535/5 = 13107
   156      * invokedynamic instructions that leaves us with at most 65535/5 = 13107
   220         case 1: return "GET_ELEMENT";
   227         case 1: return "GET_ELEMENT";
   221         case 2: return "GET_METHOD_PROPERTY";
   228         case 2: return "GET_METHOD_PROPERTY";
   222         case 3: return "GET_METHOD_ELEMENT";
   229         case 3: return "GET_METHOD_ELEMENT";
   223         case 4: return "SET_PROPERTY";
   230         case 4: return "SET_PROPERTY";
   224         case 5: return "SET_ELEMENT";
   231         case 5: return "SET_ELEMENT";
   225         case 6: return "CALL";
   232         case 6: return "REMOVE_PROPERTY";
   226         case 7: return "NEW";
   233         case 7: return "REMOVE_ELEMENT";
       
   234         case 8: return "CALL";
       
   235         case 9: return "NEW";
   227         default: throw new AssertionError();
   236         default: throw new AssertionError();
   228         }
   237         }
   229     }
   238     }
   230 
   239 
   231     /**
   240     /**