Merge
authorlana
Fri, 09 Oct 2015 10:22:19 -0700
changeset 32942 e5955eb2b3e0
parent 32938 520a68d5228d (current diff)
parent 32941 be82ab9eb287 (diff)
child 32943 ce21aface741
Merge
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/ChainedCallSite.java	Thu Oct 08 22:30:47 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/ChainedCallSite.java	Fri Oct 09 10:22:19 2015 -0700
@@ -103,27 +103,14 @@
  * handle is always at the start of the chain.
  */
 public class ChainedCallSite extends AbstractRelinkableCallSite {
-    private static final MethodHandle PRUNE_CATCHES =
-            MethodHandles.insertArguments(
-                    Lookup.findOwnSpecial(
-                            MethodHandles.lookup(),
-                            "prune",
-                            MethodHandle.class,
-                            MethodHandle.class,
-                            boolean.class),
-                    2,
-                    true);
-
-    private static final MethodHandle PRUNE_SWITCHPOINTS =
-            MethodHandles.insertArguments(
-                    Lookup.findOwnSpecial(
-                            MethodHandles.lookup(),
-                            "prune",
-                            MethodHandle.class,
-                            MethodHandle.class,
-                            boolean.class),
-                    2,
-                    false);
+    private static final MethodHandle PRUNE_CATCHES;
+    private static final MethodHandle PRUNE_SWITCHPOINTS;
+    static {
+        final MethodHandle PRUNE = Lookup.findOwnSpecial(MethodHandles.lookup(), "prune", MethodHandle.class,
+                MethodHandle.class, boolean.class);
+        PRUNE_CATCHES      = MethodHandles.insertArguments(PRUNE, 2, true);
+        PRUNE_SWITCHPOINTS = MethodHandles.insertArguments(PRUNE, 2, false);
+    }
 
     private final AtomicReference<LinkedList<GuardedInvocation>> invocations = new AtomicReference<>();
 
@@ -181,8 +168,8 @@
 
         // prune-and-invoke is used as the fallback for invalidated switchpoints. If a switchpoint gets invalidated, we
         // rebuild the chain and get rid of all invalidated switchpoints instead of letting them linger.
-        final MethodHandle pruneAndInvokeSwitchPoints = makePruneAndInvokeMethod(relink, getPruneSwitchpoints());
-        final MethodHandle pruneAndInvokeCatches      = makePruneAndInvokeMethod(relink, getPruneCatches());
+        final MethodHandle pruneAndInvokeSwitchPoints = makePruneAndInvokeMethod(relink, PRUNE_SWITCHPOINTS);
+        final MethodHandle pruneAndInvokeCatches      = makePruneAndInvokeMethod(relink, PRUNE_CATCHES);
 
         // Fold the new chain
         MethodHandle target = relink;
@@ -200,22 +187,6 @@
     }
 
     /**
-     * Get the switchpoint pruning function for a chained call site
-     * @return function that removes invalidated switchpoints tied to callsite guard chain and relinks
-     */
-    protected MethodHandle getPruneSwitchpoints() {
-        return PRUNE_SWITCHPOINTS;
-    }
-
-    /**
-     * Get the catch pruning function for a chained call site
-     * @return function that removes all catches tied to callsite guard chain and relinks
-     */
-    protected MethodHandle getPruneCatches() {
-        return PRUNE_CATCHES;
-    }
-
-    /**
      * Creates a method that rebuilds our call chain, pruning it of any invalidated switchpoints, and then invokes that
      * chain.
      * @param relink the ultimate fallback for the chain (the {@code DynamicLinker}'s relink).
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSAdapter.java	Thu Oct 08 22:30:47 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeJSAdapter.java	Fri Oct 09 10:22:19 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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
@@ -52,18 +52,18 @@
 import jdk.nashorn.internal.scripts.JO;
 
 /**
- * This class is the implementation of the Nashorn-specific global object named {@code JSAdapter}. It can be
- * thought of as the {@link java.lang.reflect.Proxy} equivalent for JavaScript. NativeJSAdapter calls specially named
+ * This class is the implementation of the Nashorn-specific global object named {@code JSAdapter}. It can be thought of
+ * as the {@link java.lang.reflect.Proxy} equivalent for JavaScript. A {@code NativeJSAdapter} calls specially named
  * JavaScript methods on an adaptee object when property access/update/call/new/delete is attempted on it. Example:
  *<pre>
  *    var y = {
- *                __get__    : function (name) { ... }
- *                __has__    : function (name) { ... }
- *                __put__    : function (name, value) {...}
- *                __call__   : function (name, arg1, arg2) {...}
- *                __new__    : function (arg1, arg2) {...}
- *                __delete__ : function (name) { ... }
- *                __getIds__ : function () { ... }
+ *                __get__     : function (name) { ... }
+ *                __has__     : function (name) { ... }
+ *                __put__     : function (name, value) {...}
+ *                __call__    : function (name, arg1, arg2) {...}
+ *                __new__     : function (arg1, arg2) {...}
+ *                __delete__  : function (name) { ... }
+ *                __getKeys__ : function () { ... }
  *            };
  *
  *    var x = new JSAdapter(y);
@@ -74,17 +74,21 @@
  *    i in x;                     // calls y.__has__
  *    x.p = 10;                   // calls y.__put__
  *    delete x.p;                 // calls y.__delete__
- *    for (i in x) { print(i); }  // calls y.__getIds__
+ *    for (i in x) { print(i); }  // calls y.__getKeys__
  * </pre>
  * <p>
- * JavaScript caller of adapter object is isolated from the fact that the property access/mutation/deletion are really
- * calls to JavaScript methods on adaptee.
+ * The {@code __getKeys__} and {@code __getIds__} properties are mapped to the same operation. Concrete
+ * {@code JSAdapter} implementations are expected to use only one of these. As {@code __getIds__} exists for
+ * compatibility reasons only, use of {@code __getKeys__} is recommended.
  * </p>
  * <p>
- * JSAdapter constructor can optionally receive an "overrides" object. Properties of overrides object is copied to
- * JSAdapter instance. When user accessed property is one of these, then adaptee's methods like {@code __get__},
- * {@code __put__} etc. are not called for those. This can be used to make certain "preferred" properties that can be
- * accessed in the usual/faster way avoiding proxy mechanism. Example:
+ * The JavaScript caller of an adapter object is oblivious of the property access/mutation/deletion's being adapted.
+ * </p>
+ * <p>
+ * The {@code JSAdapter} constructor can optionally receive an "overrides" object. The properties of overrides object
+ * are copied to the {@code JSAdapter} instance. In case user-accessed properties are among these, the adaptee's methods
+ * like {@code __get__}, {@code __put__} etc. are not called for them. This can be used to make certain "preferred"
+ * properties that can be accessed in the usual/faster way avoiding the proxy mechanism. Example:
  * </p>
  * <pre>
  *     var x = new JSAdapter({ foo: 444, bar: 6546 }) {
@@ -95,13 +99,13 @@
  *     x.bar = 'hello'; // "bar" directly set without __put__ call
  *     x.prop           // calls __get__("prop") as 'prop' is not overridden
  * </pre>
- * It is possible to pass a specific prototype for JSAdapter instance by passing three arguments to JSAdapter
- * constructor. So exact signature of JSAdapter constructor is as follows:
+ * It is possible to pass a specific prototype for the {@code JSAdapter} instance by passing three arguments to the
+ * {@code JSAdapter} constructor. The exact signature of the {@code JSAdapter} constructor is as follows:
  * <pre>
  *     JSAdapter([proto], [overrides], adaptee);
  * </pre>
- * Both proto and overrides are optional - but adaptee is not. When proto is not passed {@code JSAdapter.prototype} is
- * used.
+ * Both the {@code proto} and {@code overrides} arguments are optional - but {@code adaptee} is not. When {@code proto}
+ * is not passed, {@code JSAdapter.prototype} is used.
  */
 @ScriptClass("JSAdapter")
 public final class NativeJSAdapter extends ScriptObject {
@@ -113,7 +117,7 @@
     public static final String __call__      = "__call__";
     /** object new operation */
     public static final String __new__       = "__new__";
-    /** object getIds operation */
+    /** object getIds operation (provided for compatibility reasons; use of getKeys is preferred) */
     public static final String __getIds__    = "__getIds__";
     /** object getKeys operation */
     public static final String __getKeys__   = "__getKeys__";
@@ -142,7 +146,7 @@
     private final ScriptObject adaptee;
     private final boolean overrides;
 
-    private static final MethodHandle IS_JSADAPTOR = findOwnMH("isJSAdaptor", boolean.class, Object.class, Object.class, MethodHandle.class, Object.class, ScriptFunction.class);
+    private static final MethodHandle IS_JSADAPTER = findOwnMH("isJSAdapter", boolean.class, Object.class, Object.class, MethodHandle.class, Object.class, ScriptFunction.class);
 
     // initialized by nasgen
     private static PropertyMap $nasgenmap$;
@@ -626,7 +630,7 @@
                     // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice.
                     return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class,
                             func.createBound(this, new Object[] { name })), 0, Object.class),
-                            testJSAdaptor(adaptee, null, null, null),
+                            testJSAdapter(adaptee, null, null, null),
                             adaptee.getProtoSwitchPoints(__call__, find.getOwner()), null);
                 }
             }
@@ -697,7 +701,7 @@
                 if (methodHandle != null) {
                     return new GuardedInvocation(
                             methodHandle,
-                            testJSAdaptor(adaptee, findData.getGetter(Object.class, INVALID_PROGRAM_POINT, null), findData.getOwner(), func),
+                            testJSAdapter(adaptee, findData.getGetter(Object.class, INVALID_PROGRAM_POINT, null), findData.getOwner(), func),
                             adaptee.getProtoSwitchPoints(hook, findData.getOwner()), null);
                 }
              }
@@ -710,16 +714,16 @@
             final MethodHandle methodHandle = hook.equals(__put__) ?
             MH.asType(Lookup.EMPTY_SETTER, type) :
             Lookup.emptyGetter(type.returnType());
-            return new GuardedInvocation(methodHandle, testJSAdaptor(adaptee, null, null, null), adaptee.getProtoSwitchPoints(hook, null), null);
+            return new GuardedInvocation(methodHandle, testJSAdapter(adaptee, null, null, null), adaptee.getProtoSwitchPoints(hook, null), null);
         }
     }
 
-    private static MethodHandle testJSAdaptor(final Object adaptee, final MethodHandle getter, final Object where, final ScriptFunction func) {
-        return MH.insertArguments(IS_JSADAPTOR, 1, adaptee, getter, where, func);
+    private static MethodHandle testJSAdapter(final Object adaptee, final MethodHandle getter, final Object where, final ScriptFunction func) {
+        return MH.insertArguments(IS_JSADAPTER, 1, adaptee, getter, where, func);
     }
 
     @SuppressWarnings("unused")
-    private static boolean isJSAdaptor(final Object self, final Object adaptee, final MethodHandle getter, final Object where, final ScriptFunction func) {
+    private static boolean isJSAdapter(final Object self, final Object adaptee, final MethodHandle getter, final Object where, final ScriptFunction func) {
         final boolean res = self instanceof NativeJSAdapter && ((NativeJSAdapter)self).getAdaptee() == adaptee;
         if (res && getter != null) {
             try {
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java	Thu Oct 08 22:30:47 2015 -0700
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java	Fri Oct 09 10:22:19 2015 -0700
@@ -64,9 +64,6 @@
     private static final String PROFILEFILE = Options.getStringProperty("nashorn.profilefile", "NashornProfile.txt");
 
     private static final MethodHandle INCREASE_MISS_COUNTER = MH.findStatic(MethodHandles.lookup(), LinkerCallSite.class, "increaseMissCount", MH.type(Object.class, String.class, Object.class));
-    private static final MethodHandle ON_CATCH_INVALIDATION = MH.findStatic(MethodHandles.lookup(), LinkerCallSite.class, "onCatchInvalidation", MH.type(ChainedCallSite.class, LinkerCallSite.class));
-
-    private int catchInvalidations;
 
     LinkerCallSite(final NashornCallSiteDescriptor descriptor) {
         super(descriptor);
@@ -75,34 +72,6 @@
         }
     }
 
-    @Override
-    protected MethodHandle getPruneCatches() {
-        return MH.filterArguments(super.getPruneCatches(), 0, ON_CATCH_INVALIDATION);
-    }
-
-    /**
-     * Action to perform when a catch guard around a callsite triggers. Increases
-     * catch invalidation counter
-     * @param callSite callsite
-     * @return the callsite, so this can be used as argument filter
-     */
-    @SuppressWarnings("unused")
-    private static ChainedCallSite onCatchInvalidation(final LinkerCallSite callSite) {
-        ++callSite.catchInvalidations;
-        return callSite;
-    }
-
-    /**
-     * Get the number of catch invalidations that have happened at this call site so far
-     * @param callSiteToken call site token, unique to the callsite.
-     * @return number of catch invalidations, i.e. thrown exceptions caught by the linker
-     */
-    public static int getCatchInvalidationCount(final Object callSiteToken) {
-        if (callSiteToken instanceof LinkerCallSite) {
-            return ((LinkerCallSite)callSiteToken).catchInvalidations;
-        }
-        return 0;
-    }
     /**
      * Construct a new linker call site.
      * @param name     Name of method.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/jsadapter-ids.js	Fri Oct 09 10:22:19 2015 -0700
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015, 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Verify that JSAdapter __getIds__ works as expected.
+ *
+ * @test
+ * @run
+ */
+
+var obj = new JSAdapter() {
+    __getIds__: function() {
+        print("__getIds__ called");
+        return [ "foo", "bar" ];
+    }
+};
+
+// calls __getIds__
+for (i in obj) {
+    print(i);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/jsadapter-ids.js.EXPECTED	Fri Oct 09 10:22:19 2015 -0700
@@ -0,0 +1,3 @@
+__getIds__ called
+foo
+bar
--- a/nashorn/test/script/basic/jsadapter.js	Thu Oct 08 22:30:47 2015 -0700
+++ b/nashorn/test/script/basic/jsadapter.js	Fri Oct 09 10:22:19 2015 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, 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
@@ -45,8 +45,8 @@
         print("new with " + arg1 + ", " + arg2);
     },
 
-    __getIds__: function() {
-        print("__getIds__ called");
+    __getKeys__: function() {
+        print("__getKeys__ called");
         return [ "foo", "bar" ];
     },
 
@@ -78,22 +78,28 @@
 // calls __new__
 new obj("hey!", "it works!");
 
+// calls __getKeys__
 for (i in obj) {
     print(i);
 }
 
+// calls __getValues__
 for each (i in obj) {
     print(i);
 }
 
+// calls __has__
 var x = "foo" in obj;
 print(x);
 
+// calls __has__
 var y = "js" in obj;
 print(y);
 
+// calls __delete__
 print(delete obj.prop);
 
+// call __get__ and __set__
 print(obj["js"]);
 obj["js"] = "javascript";
 print(obj["javascript"]);
--- a/nashorn/test/script/basic/jsadapter.js.EXPECTED	Thu Oct 08 22:30:47 2015 -0700
+++ b/nashorn/test/script/basic/jsadapter.js.EXPECTED	Fri Oct 09 10:22:19 2015 -0700
@@ -3,7 +3,7 @@
 setter called for 'foo' with 33
 method 'func' called with hello, world
 new with hey!, it works!
-__getIds__ called
+__getKeys__ called
 foo
 bar
 __getValues__ called