aboutsummaryrefslogtreecommitdiff
path: root/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java')
-rw-r--r--src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java186
1 files changed, 177 insertions, 9 deletions
diff --git a/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java b/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java
index 1e75d2a7..62e6e99f 100644
--- a/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java
+++ b/src/jdk/nashorn/internal/objects/annotations/SpecializedFunction.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,18 +29,186 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
+import java.lang.invoke.MethodHandle;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.nashorn.internal.runtime.ScriptFunction;
/**
- * The SpecializedFunction annotation is used to flag more type specific functions than the standard one in
- * Native objects. For example {@link jdk.nashorn.internal.objects.NativeMath#max} takes an arbitrary number of
- * Object elements as an array. Call this function, including the varargs collector that allocates the array
- * upon each invocation, is much more expensive than calling a specialized function that takes two arguments
- * of, e.g. int type from the call site, such as {@link jdk.nashorn.internal.objects.NativeMath#max(Object, int, int)}.
- * {@link jdk.nashorn.internal.runtime.ScriptFunction} will try to look up the most specific function when
- * linking the callsite.
+ * The SpecializedFunction annotation is used to flag more type specific
+ * functions than the standard one in the native objects
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface SpecializedFunction {
- //empty
+
+ /**
+ * Functionality for testing if we are allowed to link a specialized
+ * function the first time we encounter it. Then the guard will handle the
+ * rest of the invocations
+ *
+ * This is the same for all callsites in Nashorn, the first time callsite is
+ * linked, we have to manually check that the linkage is OK. Even if we add
+ * a guard and it fails upon the first try, this is not good enough.
+ * (Symmetrical to how it works everywhere else in the Nashorn runtime).
+ *
+ * Here we abstract out a few of the most common link guard checks.
+ */
+ public static abstract class LinkLogic {
+ /**
+ * Empty link logic instance - this is the default
+ * "no special linking or runtime guard behavior"
+ */
+ public static final LinkLogic EMPTY_INSTANCE = new Empty();
+
+ /** Empty link logic class - allow all linking, no guards */
+ private static final class Empty extends LinkLogic {
+ @Override
+ public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
+ return true;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return true;
+ }
+ }
+
+ /**
+ * Get the class representing the empty link logic
+ * @return class representing empty link logic
+ */
+ public static Class<? extends LinkLogic> getEmptyLinkLogicClass() {
+ return Empty.class;
+ }
+
+ /**
+ * Should this callsite relink when an exception is thrown
+ *
+ * @return the relink exception, or null if none
+ */
+ public Class<? extends Throwable> getRelinkException() {
+ return null;
+ }
+
+ /**
+ * Is this link logic class empty - i.e. no special linking logic
+ * supplied
+ *
+ * @param clazz class to check
+ *
+ * @return true if this link logic is empty
+ */
+ public static boolean isEmpty(final Class<? extends LinkLogic> clazz) {
+ return clazz == Empty.class;
+ }
+
+ /**
+ * Is this link logic instance empty - i.e. no special linking logic
+ * supplied
+ *
+ * @return true if this link logic instance is empty
+ */
+ public boolean isEmpty() {
+ return false;
+ }
+
+ /**
+ * Given a callsite, can we link this method based on the receiver and
+ * parameters?
+ *
+ * @param self receiver
+ * @param desc callsite descriptor
+ * @param request link request
+ *
+ * @return true if we can link this callsite at this time
+ */
+ public abstract boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request);
+
+ /**
+ * Given a callsite, do we require an extra guard for specialization to
+ * go through?
+ *
+ * @param self receiver
+ *
+ * @return true if a guard is to be woven into the callsite
+ */
+ public boolean needsGuard(final Object self) {
+ return true;
+ }
+
+ /**
+ * Given a callsite, and optional arguments, do we need an extra guard
+ * for specialization to go through - this guard can be a function of
+ * the arguments too
+ *
+ * @param self receiver
+ * @param args arguments
+ *
+ * @return true if a guard is to be woven into the callsite
+ */
+ public boolean needsGuard(final Object self, final Object... args) {
+ return true;
+ }
+
+ /**
+ * Given a callsite, and optional arguments, return any extra guard we
+ * might need for specialization as a method handle.
+ *
+ * @return methodhandle for guard, or null if no guard is needed
+ */
+ public MethodHandle getGuard() {
+ return null;
+ }
+
+ /**
+ * Check, given a link request and a receiver, if this specialization
+ * fits This is used by the linker in {@link ScriptFunction} to figure
+ * out if an optimistic builtin can be linked when first discovered
+ *
+ * @param self receiver
+ * @param desc callsite descriptor
+ * @param request link request
+
+ * @return true if we can link, false otherwise - that means we have to
+ * pick a non specialized target
+ */
+ public boolean checkLinkable(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
+ // check the link guard, if it says we can link, go ahead
+ return canLink(self, desc, request);
+ }
+ }
+
+ /**
+ * name override for return value polymorphism, for example we can't have
+ * pop(V)I and pop(V)D in the same Java class, so they need to be named,
+ * e.g. popInt(V)I and popDouble(V)D for disambiguation, however, their
+ * names still need to resolve to "pop" to JavaScript so we can still
+ * specialize on return values and so that the linker can find them
+ *
+ * @return name, "" means no override, use the Java function name, e.g.
+ * "push"
+ */
+ String name() default "";
+
+ /**
+ * Return the guard for this specialized function. The default is no guard.
+ *
+ * @return guard
+ */
+ Class<?> linkLogic() default LinkLogic.Empty.class;
+
+ /**
+ * Is this a specialized constructor?
+ */
+ boolean isConstructor() default false;
+
+ /**
+ * Can this function throw UnwarrantedOptimismExceptions? This works just
+ * like the normal functions, but we need the function to be
+ * immutable/non-state modifying, as we can't generate continuations for
+ * native code. Luckily a lot of the methods we want to specialize have this
+ * property
+ */
+ boolean isOptimistic() default false;
}