NashornCallSiteDescriptor.java revision 1645:15d52fdd9168
1/*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
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
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
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
26package jdk.nashorn.internal.runtime.linker;
27
28import java.lang.invoke.MethodHandles;
29import java.lang.invoke.MethodHandles.Lookup;
30import java.lang.invoke.MethodType;
31import java.lang.ref.Reference;
32import java.lang.ref.WeakReference;
33import java.security.AccessControlContext;
34import java.security.AccessController;
35import java.security.PrivilegedAction;
36import java.util.Collections;
37import java.util.Map;
38import java.util.WeakHashMap;
39import java.util.concurrent.ConcurrentHashMap;
40import java.util.concurrent.ConcurrentMap;
41import java.util.stream.Stream;
42import jdk.dynalink.CallSiteDescriptor;
43import jdk.dynalink.CompositeOperation;
44import jdk.dynalink.NamedOperation;
45import jdk.dynalink.Operation;
46import jdk.dynalink.SecureLookupSupplier;
47import jdk.dynalink.StandardOperation;
48import jdk.nashorn.internal.ir.debug.NashornTextifier;
49import jdk.nashorn.internal.runtime.AccessControlContextFactory;
50import jdk.nashorn.internal.runtime.ScriptRuntime;
51
52/**
53 * Nashorn-specific implementation of Dynalink's {@link CallSiteDescriptor}.
54 * The reason we have our own subclass is that we're storing flags in an
55 * additional primitive field. The class also exposes some useful utilities in
56 * form of static methods.
57 */
58public final class NashornCallSiteDescriptor extends CallSiteDescriptor {
59    // Lowest three bits describe the operation
60    /** Property getter operation {@code obj.prop} */
61    public static final int GET_PROPERTY        = 0;
62    /** Element getter operation {@code obj[index]} */
63    public static final int GET_ELEMENT         = 1;
64    /** Property getter operation, subsequently invoked {@code obj.prop()} */
65    public static final int GET_METHOD_PROPERTY = 2;
66    /** Element getter operation, subsequently invoked {@code obj[index]()} */
67    public static final int GET_METHOD_ELEMENT  = 3;
68    /** Property setter operation {@code obj.prop = value} */
69    public static final int SET_PROPERTY        = 4;
70    /** Element setter operation {@code obj[index] = value} */
71    public static final int SET_ELEMENT         = 5;
72    /** Call operation {@code fn(args...)} */
73    public static final int CALL                = 6;
74    /** New operation {@code new Constructor(args...)} */
75    public static final int NEW                 = 7;
76
77    private static final int OPERATION_MASK = 7;
78
79    // Correspond to the operation indices above.
80    private static final Operation[] OPERATIONS = new Operation[] {
81        new CompositeOperation(StandardOperation.GET_PROPERTY, StandardOperation.GET_ELEMENT, StandardOperation.GET_METHOD),
82        new CompositeOperation(StandardOperation.GET_ELEMENT, StandardOperation.GET_PROPERTY, StandardOperation.GET_METHOD),
83        new CompositeOperation(StandardOperation.GET_METHOD, StandardOperation.GET_PROPERTY, StandardOperation.GET_ELEMENT),
84        new CompositeOperation(StandardOperation.GET_METHOD, StandardOperation.GET_ELEMENT, StandardOperation.GET_PROPERTY),
85        new CompositeOperation(StandardOperation.SET_PROPERTY, StandardOperation.SET_ELEMENT),
86        new CompositeOperation(StandardOperation.SET_ELEMENT, StandardOperation.SET_PROPERTY),
87        StandardOperation.CALL,
88        StandardOperation.NEW
89    };
90
91    /** Flags that the call site references a scope variable (it's an identifier reference or a var declaration, not a
92     * property access expression. */
93    public static final int CALLSITE_SCOPE         = 1 << 3;
94    /** Flags that the call site is in code that uses ECMAScript strict mode. */
95    public static final int CALLSITE_STRICT        = 1 << 4;
96    /** Flags that a property getter or setter call site references a scope variable that is located at a known distance
97     * in the scope chain. Such getters and setters can often be linked more optimally using these assumptions. */
98    public static final int CALLSITE_FAST_SCOPE    = 1 << 5;
99    /** Flags that a callsite type is optimistic, i.e. we might get back a wider return value than encoded in the
100     * descriptor, and in that case we have to throw an UnwarrantedOptimismException */
101    public static final int CALLSITE_OPTIMISTIC    = 1 << 6;
102    /** Is this really an apply that we try to call as a call? */
103    public static final int CALLSITE_APPLY_TO_CALL = 1 << 7;
104    /** Does this a callsite for a variable declaration? */
105    public static final int CALLSITE_DECLARE       = 1 << 8;
106
107    /** Flags that the call site is profiled; Contexts that have {@code "profile.callsites"} boolean property set emit
108     * code where call sites have this flag set. */
109    public static final int CALLSITE_PROFILE         = 1 << 9;
110    /** Flags that the call site is traced; Contexts that have {@code "trace.callsites"} property set emit code where
111     * call sites have this flag set. */
112    public static final int CALLSITE_TRACE           = 1 << 10;
113    /** Flags that the call site linkage miss (and thus, relinking) is traced; Contexts that have the keyword
114     * {@code "miss"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
115    public static final int CALLSITE_TRACE_MISSES    = 1 << 11;
116    /** Flags that entry/exit to/from the method linked at call site are traced; Contexts that have the keyword
117     * {@code "enterexit"} in their {@code "trace.callsites"} property emit code where call sites have this flag set. */
118    public static final int CALLSITE_TRACE_ENTEREXIT = 1 << 12;
119    /** Flags that values passed as arguments to and returned from the method linked at call site are traced; Contexts
120     * that have the keyword {@code "values"} in their {@code "trace.callsites"} property emit code where call sites
121     * have this flag set. */
122    public static final int CALLSITE_TRACE_VALUES    = 1 << 13;
123
124    //we could have more tracing flags here, for example CALLSITE_TRACE_SCOPE, but bits are a bit precious
125    //right now given the program points
126
127    /**
128     * Number of bits the program point is shifted to the left in the flags (lowest bit containing a program point).
129     * Always one larger than the largest flag shift. Note that introducing a new flag halves the number of program
130     * points we can have.
131     * TODO: rethink if we need the various profile/trace flags or the linker can use the Context instead to query its
132     * trace/profile settings.
133     */
134    public static final int CALLSITE_PROGRAM_POINT_SHIFT = 14;
135
136    /**
137     * Maximum program point value. We have 18 bits left over after flags, and
138     * it should be plenty. Program points are local to a single function. Every
139     * function maps to a single JVM bytecode method that can have at most 65535
140     * bytes. (Large functions are synthetically split into smaller functions.)
141     * A single invokedynamic is 5 bytes; even if a method consists of only
142     * invokedynamic instructions that leaves us with at most 65535/5 = 13107
143     * program points for the largest single method; those can be expressed on
144     * 14 bits. It is true that numbering of program points is independent of
145     * bytecode representation, but if a function would need more than ~14 bits
146     * for the program points, then it is reasonable to presume splitter
147     * would've split it into several smaller functions already.
148     */
149    public static final int MAX_PROGRAM_POINT_VALUE = (1 << 32 - CALLSITE_PROGRAM_POINT_SHIFT) - 1;
150
151    /**
152     * Flag mask to get the program point flags
153     */
154    public static final int FLAGS_MASK = (1 << CALLSITE_PROGRAM_POINT_SHIFT) - 1;
155
156    private static final ClassValue<ConcurrentMap<NashornCallSiteDescriptor, NashornCallSiteDescriptor>> canonicals =
157            new ClassValue<ConcurrentMap<NashornCallSiteDescriptor,NashornCallSiteDescriptor>>() {
158        @Override
159        protected ConcurrentMap<NashornCallSiteDescriptor, NashornCallSiteDescriptor> computeValue(final Class<?> type) {
160            return new ConcurrentHashMap<>();
161        }
162    };
163
164    private static final AccessControlContext GET_LOOKUP_PERMISSION_CONTEXT =
165            AccessControlContextFactory.createAccessControlContext(SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME);
166
167    @SuppressWarnings("unchecked")
168    private static final Map<String, Reference<NamedOperation>>[] NAMED_OPERATIONS =
169            Stream.generate(() -> Collections.synchronizedMap(new WeakHashMap<>()))
170            .limit(OPERATIONS.length).toArray(Map[]::new);
171
172    private final int flags;
173
174    /**
175     * Function used by {@link NashornTextifier} to represent call site flags in
176     * human readable form
177     * @param flags call site flags
178     * @param sb the string builder
179     */
180    public static void appendFlags(final int flags, final StringBuilder sb) {
181        final int pp = flags >> CALLSITE_PROGRAM_POINT_SHIFT;
182        if (pp != 0) {
183            sb.append(" pp=").append(pp);
184        }
185        if ((flags & CALLSITE_SCOPE) != 0) {
186            if ((flags & CALLSITE_FAST_SCOPE) != 0) {
187                sb.append(" fastscope");
188            } else {
189                sb.append(" scope");
190            }
191            if ((flags & CALLSITE_DECLARE) != 0) {
192                sb.append(" declare");
193            }
194        } else {
195            assert (flags & CALLSITE_FAST_SCOPE) == 0 : "can't be fastscope without scope";
196        }
197        if ((flags & CALLSITE_APPLY_TO_CALL) != 0) {
198            sb.append(" apply2call");
199        }
200        if ((flags & CALLSITE_STRICT) != 0) {
201            sb.append(" strict");
202        }
203    }
204
205    /**
206     * Given call site flags, returns the operation name encoded in them.
207     * @param flags flags
208     * @return the operation name
209     */
210    public static String getOperationName(final int flags) {
211        switch(flags & OPERATION_MASK) {
212        case 0: return "GET_PROPERTY";
213        case 1: return "GET_ELEMENT";
214        case 2: return "GET_METHOD_PROPERTY";
215        case 3: return "GET_METHOD_ELEMENT";
216        case 4: return "SET_PROPERTY";
217        case 5: return "SET_ELEMENT";
218        case 6: return "CALL";
219        case 7: return "NEW";
220        default: throw new AssertionError();
221        }
222    }
223
224    /**
225     * Retrieves a Nashorn call site descriptor with the specified values. Since call site descriptors are immutable
226     * this method is at liberty to retrieve canonicalized instances (although it is not guaranteed it will do so).
227     * @param lookup the lookup describing the script
228     * @param name the name at the call site. Can not be null, but it can be empty.
229     * @param methodType the method type at the call site
230     * @param flags Nashorn-specific call site flags
231     * @return a call site descriptor with the specified values.
232     */
233    public static NashornCallSiteDescriptor get(final MethodHandles.Lookup lookup, final String name,
234            final MethodType methodType, final int flags) {
235        final int opIndex = flags & OPERATION_MASK;
236        final Operation baseOp = OPERATIONS[opIndex];
237        final String decodedName = NameCodec.decode(name);
238        final Operation op = decodedName.isEmpty() ? baseOp : getNamedOperation(decodedName, opIndex, baseOp);
239        return get(lookup, op, methodType, flags);
240    }
241
242    private static NamedOperation getNamedOperation(final String name, final int opIndex, final Operation baseOp) {
243        final Map<String, Reference<NamedOperation>> namedOps = NAMED_OPERATIONS[opIndex];
244        final Reference<NamedOperation> ref = namedOps.get(name);
245        if (ref != null) {
246            final NamedOperation existing = ref.get();
247            if (existing != null) {
248                return existing;
249            }
250        }
251        final NamedOperation newOp = new NamedOperation(baseOp, name);
252        namedOps.put(name, new WeakReference<>(newOp));
253        return newOp;
254    }
255
256    private static NashornCallSiteDescriptor get(final MethodHandles.Lookup lookup, final Operation operation, final MethodType methodType, final int flags) {
257        final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(lookup, operation, methodType, flags);
258        // Many of these call site descriptors are identical (e.g. every getter for a property color will be
259        // "GET_PROPERTY:color(Object)Object", so it makes sense canonicalizing them. Make an exception for
260        // optimistic call site descriptors, as they also carry a program point making them unique.
261        if (csd.isOptimistic()) {
262            return csd;
263        }
264        final NashornCallSiteDescriptor canonical = canonicals.get(lookup.lookupClass()).putIfAbsent(csd, csd);
265        return canonical != null ? canonical : csd;
266    }
267
268    private NashornCallSiteDescriptor(final MethodHandles.Lookup lookup, final Operation operation, final MethodType methodType, final int flags) {
269        super(lookup, operation, methodType);
270        this.flags = flags;
271    }
272
273    static Lookup getLookupInternal(final CallSiteDescriptor csd) {
274        if (csd instanceof NashornCallSiteDescriptor) {
275            return ((NashornCallSiteDescriptor)csd).getLookupPrivileged();
276        }
277        return AccessController.doPrivileged((PrivilegedAction<Lookup>)()->csd.getLookup(), GET_LOOKUP_PERMISSION_CONTEXT);
278    }
279
280    @Override
281    public boolean equals(final Object obj) {
282        return super.equals(obj) && flags == ((NashornCallSiteDescriptor)obj).flags;
283    }
284
285    @Override
286    public int hashCode() {
287        return super.hashCode() ^ flags;
288    }
289
290    /**
291     * Returns the named operand in this descriptor's operation. Equivalent to
292     * {@code ((NamedOperation)getOperation()).getName().toString()} for call
293     * sites with a named operand. For call sites without named operands returns null.
294     * @return the named operand in this descriptor's operation.
295     */
296    public String getOperand() {
297        return getOperand(this);
298    }
299
300    /**
301     * Returns the named operand in the passed descriptor's operation.
302     * Equivalent to
303     * {@code ((NamedOperation)desc.getOperation()).getName().toString()} for
304     * descriptors with a named operand. For descriptors without named operands
305     * returns null.
306     * @param desc the call site descriptors
307     * @return the named operand in this descriptor's operation.
308     */
309    public static String getOperand(final CallSiteDescriptor desc) {
310        final Operation operation = desc.getOperation();
311        return operation instanceof NamedOperation ? ((NamedOperation)operation).getName().toString() : null;
312    }
313
314    /**
315     * Returns the first operation in this call site descriptor's potentially
316     * composite operation. E.g. if this call site descriptor has a composite
317     * operation {@code GET_PROPERTY|GET_METHOD|GET_ELEM}, it will return
318     * {@code GET_PROPERTY}. Nashorn - being a ECMAScript engine - does not
319     * distinguish between property, element, and method namespace; ECMAScript
320     * objects just have one single property namespace for all these, therefore
321     * it is largely irrelevant what the composite operation is structured like;
322     * if the first operation can't be satisfied, neither can the others. The
323     * first operation is however sometimes used to slightly alter the
324     * semantics; for example, a distinction between {@code GET_PROPERTY} and
325     * {@code GET_METHOD} being the first operation can translate into whether
326     * {@code "__noSuchProperty__"} or {@code "__noSuchMethod__"} will be
327     * executed in case the property is not found. Note that if a call site
328     * descriptor comes from outside of Nashorn, its class will be different,
329     * and there is no guarantee about the way it composes its operations. For
330     * that reason, for potentially foreign call site descriptors you should use
331     * {@link #getFirstStandardOperation(CallSiteDescriptor)} instead.
332     * @return the first operation in this call site descriptor. Note this will
333     * always be a {@code StandardOperation} as Nashorn internally only uses
334     * standard operations.
335     */
336    public StandardOperation getFirstOperation() {
337        final Operation base = NamedOperation.getBaseOperation(getOperation());
338        if (base instanceof CompositeOperation) {
339            return (StandardOperation)((CompositeOperation)base).getOperation(0);
340        }
341        return (StandardOperation)base;
342    }
343
344    /**
345     * Returns the first standard operation in the (potentially composite)
346     * operation of the passed call site descriptor.
347     * @param desc the call site descriptor.
348     * @return Returns the first standard operation in the (potentially
349     * composite) operation of the passed call site descriptor. Can return null
350     * if the call site contains no standard operations.
351     */
352    public static StandardOperation getFirstStandardOperation(final CallSiteDescriptor desc) {
353        final Operation base = NamedOperation.getBaseOperation(desc.getOperation());
354        if (base instanceof StandardOperation) {
355            return (StandardOperation)base;
356        } else if (base instanceof CompositeOperation) {
357            final CompositeOperation cop = (CompositeOperation)base;
358            for(int i = 0; i < cop.getOperationCount(); ++i) {
359                final Operation op = cop.getOperation(i);
360                if (op instanceof StandardOperation) {
361                    return (StandardOperation)op;
362                }
363            }
364        }
365        return null;
366    }
367
368    /**
369     * Returns true if the passed call site descriptor's operation contains (or
370     * is) the specified standard operation.
371     * @param desc the call site descriptor.
372     * @param operation the operation whose presence is tested.
373     * @return Returns true if the call site descriptor's operation contains (or
374     * is) the specified standard operation.
375     */
376    public static boolean contains(final CallSiteDescriptor desc, final StandardOperation operation) {
377        return CompositeOperation.contains(NamedOperation.getBaseOperation(desc.getOperation()), operation);
378    }
379
380    /**
381     * Returns the error message to be used when CALL or NEW is used on a non-function.
382     *
383     * @param obj object on which CALL or NEW is used
384     * @return error message
385     */
386    public String getFunctionErrorMessage(final Object obj) {
387        final String funcDesc = getOperand();
388        return funcDesc != null? funcDesc : ScriptRuntime.safeToString(obj);
389    }
390
391    /**
392     * Returns the error message to be used when CALL or NEW is used on a non-function.
393     *
394     * @param desc call site descriptor
395     * @param obj object on which CALL or NEW is used
396     * @return error message
397     */
398    public static String getFunctionErrorMessage(final CallSiteDescriptor desc, final Object obj) {
399        return desc instanceof NashornCallSiteDescriptor ?
400                ((NashornCallSiteDescriptor)desc).getFunctionErrorMessage(obj) :
401                ScriptRuntime.safeToString(obj);
402    }
403
404    /**
405     * Returns the Nashorn-specific flags for this call site descriptor.
406     * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
407     * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
408     * generated outside of Nashorn.
409     * @return the Nashorn-specific flags for the call site, or 0 if the passed descriptor is not a Nashorn call site
410     * descriptor.
411     */
412    public static int getFlags(final CallSiteDescriptor desc) {
413        return desc instanceof NashornCallSiteDescriptor ? ((NashornCallSiteDescriptor)desc).flags : 0;
414    }
415
416    /**
417     * Returns true if this descriptor has the specified flag set, see {@code CALLSITE_*} constants in this class.
418     * @param flag the tested flag
419     * @return true if the flag is set, false otherwise
420     */
421    private boolean isFlag(final int flag) {
422        return (flags & flag) != 0;
423    }
424
425    /**
426     * Returns true if this descriptor has the specified flag set, see {@code CALLSITE_*} constants in this class.
427     * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
428     * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
429     * generated outside of Nashorn.
430     * @param flag the tested flag
431     * @return true if the flag is set, false otherwise (it will be false if the descriptor is not a Nashorn call site
432     * descriptor).
433     */
434    private static boolean isFlag(final CallSiteDescriptor desc, final int flag) {
435        return (getFlags(desc) & flag) != 0;
436    }
437
438    /**
439     * Returns true if this descriptor is a Nashorn call site descriptor and has the {@link  #CALLSITE_SCOPE} flag set.
440     * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
441     * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
442     * generated outside of Nashorn.
443     * @return true if the descriptor is a Nashorn call site descriptor, and the flag is set, false otherwise.
444     */
445    public static boolean isScope(final CallSiteDescriptor desc) {
446        return isFlag(desc, CALLSITE_SCOPE);
447    }
448
449    /**
450     * Returns true if this descriptor is a Nashorn call site descriptor and has the {@link  #CALLSITE_FAST_SCOPE} flag set.
451     * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
452     * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
453     * generated outside of Nashorn.
454     * @return true if the descriptor is a Nashorn call site descriptor, and the flag is set, false otherwise.
455     */
456    public static boolean isFastScope(final CallSiteDescriptor desc) {
457        return isFlag(desc, CALLSITE_FAST_SCOPE);
458    }
459
460    /**
461     * Returns true if this descriptor is a Nashorn call site descriptor and has the {@link  #CALLSITE_STRICT} flag set.
462     * @param desc the descriptor. It can be any kind of a call site descriptor, not necessarily a
463     * {@code NashornCallSiteDescriptor}. This allows for graceful interoperability when linking Nashorn with code
464     * generated outside of Nashorn.
465     * @return true if the descriptor is a Nashorn call site descriptor, and the flag is set, false otherwise.
466     */
467    public static boolean isStrict(final CallSiteDescriptor desc) {
468        return isFlag(desc, CALLSITE_STRICT);
469    }
470
471    /**
472     * Returns true if this is an apply call that we try to call as
473     * a "call"
474     * @param desc descriptor
475     * @return true if apply to call
476     */
477    public static boolean isApplyToCall(final CallSiteDescriptor desc) {
478        return isFlag(desc, CALLSITE_APPLY_TO_CALL);
479    }
480
481    /**
482     * Is this an optimistic call site
483     * @param desc descriptor
484     * @return true if optimistic
485     */
486    public static boolean isOptimistic(final CallSiteDescriptor desc) {
487        return isFlag(desc, CALLSITE_OPTIMISTIC);
488    }
489
490    /**
491     * Does this callsite contain a declaration for its target?
492     * @param desc descriptor
493     * @return true if contains declaration
494     */
495    public static boolean isDeclaration(final CallSiteDescriptor desc) {
496        return isFlag(desc, CALLSITE_DECLARE);
497    }
498
499    /**
500     * Returns true if {@code flags} has the {@link  #CALLSITE_STRICT} bit set.
501     * @param flags the flags
502     * @return true if the flag is set, false otherwise.
503     */
504    public static boolean isStrictFlag(final int flags) {
505        return (flags & CALLSITE_STRICT) != 0;
506    }
507
508    /**
509     * Returns true if {@code flags} has the {@link  #CALLSITE_SCOPE} bit set.
510     * @param flags the flags
511     * @return true if the flag is set, false otherwise.
512     */
513    public static boolean isScopeFlag(final int flags) {
514        return (flags & CALLSITE_SCOPE) != 0;
515    }
516
517    /**
518     * Get a program point from a descriptor (must be optimistic)
519     * @param desc descriptor
520     * @return program point
521     */
522    public static int getProgramPoint(final CallSiteDescriptor desc) {
523        assert isOptimistic(desc) : "program point requested from non-optimistic descriptor " + desc;
524        return getFlags(desc) >> CALLSITE_PROGRAM_POINT_SHIFT;
525    }
526
527    boolean isProfile() {
528        return isFlag(CALLSITE_PROFILE);
529    }
530
531    boolean isTrace() {
532        return isFlag(CALLSITE_TRACE);
533    }
534
535    boolean isTraceMisses() {
536        return isFlag(CALLSITE_TRACE_MISSES);
537    }
538
539    boolean isTraceEnterExit() {
540        return isFlag(CALLSITE_TRACE_ENTEREXIT);
541    }
542
543    boolean isTraceObjects() {
544        return isFlag(CALLSITE_TRACE_VALUES);
545    }
546
547    boolean isOptimistic() {
548        return isFlag(CALLSITE_OPTIMISTIC);
549    }
550
551    @Override
552    public CallSiteDescriptor changeMethodTypeInternal(final MethodType newMethodType) {
553        return get(getLookupPrivileged(), getOperation(), newMethodType, flags);
554    }
555}
556