SpecializedFunction.java revision 1101:be3f5ca1edbf
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
26package jdk.nashorn.internal.objects.annotations;
27
28import java.lang.annotation.ElementType;
29import java.lang.annotation.Retention;
30import java.lang.annotation.RetentionPolicy;
31import java.lang.annotation.Target;
32import java.lang.invoke.MethodHandle;
33import jdk.internal.dynalink.CallSiteDescriptor;
34import jdk.internal.dynalink.linker.LinkRequest;
35import 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)
43public @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}
215