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