1 /*
   2  * Copyright (c) 2010, 2015, 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 
  26 package jdk.nashorn.internal.objects.annotations;
  27 
  28 import java.lang.annotation.ElementType;
  29 import java.lang.annotation.Retention;
  30 import java.lang.annotation.RetentionPolicy;
  31 import java.lang.annotation.Target;
  32 import java.lang.invoke.MethodHandle;
  33 import jdk.dynalink.CallSiteDescriptor;
  34 import jdk.dynalink.linker.LinkRequest;
  35 import jdk.nashorn.internal.runtime.ScriptFunction;
  36 import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
  37 
  38 /**
  39  * The SpecializedFunction annotation is used to flag more type specific
  40  * functions than the standard one in the native objects.
  41  */
  42 @Retention(RetentionPolicy.RUNTIME)
  43 @Target(ElementType.METHOD)
  44 public @interface SpecializedFunction {
  45 
  46     /**
  47      * Functionality for testing if we are allowed to link a specialized
  48      * function the first time we encounter it. Then the guard will handle the
  49      * rest of the invocations.
  50      *
  51      * This is the same for all callsites in Nashorn; the first time a callsite is
  52      * linked, we have to manually check that the linkage is OK. Even if we add
  53      * a guard and it fails upon the first try, this is not good enough.
  54      * (Symmetrical to how it works everywhere else in the Nashorn runtime.)
  55      *
  56      * Here we abstract out a few of the most common link guard checks.
  57      */
  58     public static abstract class LinkLogic {
  59         /**
  60          * Empty link logic instance - this is the default.
  61          * "no special linking or runtime guard behavior"
  62          */
  63         public static final LinkLogic EMPTY_INSTANCE = new Empty();
  64 
  65         /** Empty link logic class - allow all linking, no guards. */
  66         private static final class Empty extends LinkLogic {
  67             @Override
  68             public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
  69                 return true;
  70             }
  71 
  72             @Override
  73             public boolean isEmpty() {
  74                 return true;
  75             }
  76         }
  77 
  78         /**
  79          * Get the class representing the empty link logic.
  80          *
  81          * @return class representing empty link logic
  82          */
  83         public static Class<? extends LinkLogic> getEmptyLinkLogicClass() {
  84             return Empty.class;
  85         }
  86 
  87         /**
  88          * Should this callsite relink when an exception is thrown?
  89          *
  90          * @return the relink exception, or {@code null} if none
  91          */
  92         public Class<? extends Throwable> getRelinkException() {
  93             return null;
  94         }
  95 
  96         /**
  97          * Is this link logic class empty - i.e., no special linking logic
  98          * supplied?
  99          *
 100          * @param clazz class to check
 101          *
 102          * @return {@code true} if this link logic is empty
 103          */
 104         public static boolean isEmpty(final Class<? extends LinkLogic> clazz) {
 105             return clazz == Empty.class;
 106         }
 107 
 108         /**
 109          * Is this link logic instance empty - i.e., no special linking logic
 110          * supplied?
 111          *
 112          * @return {@code true} if this link logic instance is empty
 113          */
 114         public boolean isEmpty() {
 115             return false;
 116         }
 117 
 118         /**
 119          * Given a callsite, can we link this method based on the receiver and
 120          * parameters?
 121          *
 122          * @param self    receiver
 123          * @param desc    callsite descriptor
 124          * @param request link request
 125          *
 126          * @return {@code true} if we can link this callsite at this time
 127          */
 128         public abstract boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request);
 129 
 130         /**
 131          * Given a callsite, do we require an extra guard for specialization to
 132          * go through?
 133          *
 134          * @param self receiver
 135          *
 136          * @return {@code true} if a guard is to be woven into the callsite
 137          */
 138         public boolean needsGuard(final Object self) {
 139             return true;
 140         }
 141 
 142         /**
 143          * Given a callsite, and optional arguments, do we need an extra guard
 144          * for specialization to go through? This guard can be a function of
 145          * the arguments too.
 146          *
 147          * @param self receiver
 148          * @param args arguments
 149          *
 150          * @return {@code true} if a guard is to be woven into the callsite
 151          */
 152         public boolean needsGuard(final Object self, final Object... args) {
 153             return true;
 154         }
 155 
 156         /**
 157          * Given a callsite, and optional arguments, return any extra guard we
 158          * might need for specialization as a method handle.
 159          *
 160          * @return methodhandle for guard, or null if no guard is needed
 161          */
 162         public MethodHandle getGuard() {
 163             return null;
 164         }
 165 
 166         /**
 167          * Check, given a link request and a receiver, if this specialization
 168          * fits This is used by the linker in {@link ScriptFunction} to figure
 169          * out if an optimistic builtin can be linked when first discovered
 170          *
 171          * @param self receiver
 172          * @param desc callsite descriptor
 173          * @param request link request
 174          *
 175          * @return {@code true} if we can link, {@code false} otherwise - that
 176          *         means we have to pick a non specialized target
 177          */
 178         public boolean checkLinkable(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
 179             // check the link guard, if it says we can link, go ahead
 180             return canLink(self, desc, request);
 181         }
 182     }
 183 
 184     /**
 185      * Name override for return value polymorphism, for example we can't have
 186      * pop(V)I and pop(V)D in the same Java class, so they need to be named,
 187      * e.g., popInt(V)I and popDouble(V)D for disambiguation, however, their
 188      * names still need to resolve to "pop" to JavaScript so we can still
 189      * specialize on return values and so that the linker can find them.
 190      *
 191      * @return name, "" means no override, use the Java function name, e.g.
 192      *         "push"
 193      */
 194     String name() default "";
 195 
 196     /**
 197      * Return the guard for this specialized function. The default is no guard.
 198      *
 199      * @return guard
 200      */
 201     Class<?> linkLogic() default LinkLogic.Empty.class;
 202 
 203     /**
 204      * @return whether this is a specialized constructor.
 205      */
 206     boolean isConstructor() default false;
 207 
 208     /**
 209      * Can this function throw {@link UnwarrantedOptimismException}s? This works
 210      * just like the normal functions, but we need the function to be
 211      * immutable/non-state modifying, as we can't generate continuations for
 212      * native code. Luckily a lot of the methods we want to specialize have this
 213      * property.
 214      *
 215      * @return whether this function can throw {@link UnwarrantedOptimismException}.
 216      */
 217     boolean isOptimistic() default false;
 218 
 219     /**
 220      * Is it safe to convert non-numeric arguments to numbers for this function's primitive numeric parameters?
 221      * This is true for many built-in functions which expect numeric arguments, but not for those that
 222      * expect generic arguments and just have specializations with numeric params to avoid boxing overhead.
 223      * The default value is {@code true} because that is by far the most common case.
 224      *
 225      * @return true if it is safe to convert arguments to numbers
 226      */
 227     boolean convertsNumericArgs() default true;
 228 }