8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
Reviewed-by: attila, lagergren, hannesw
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Tue Jun 03 12:05:59 2014 +0200
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Jun 04 13:55:21 2014 +0530
@@ -156,7 +156,7 @@
/** Method handle to retrieve prototype of this object */
public static final MethodHandle GETPROTO = findOwnMH_V("getProto", ScriptObject.class);
- static final MethodHandle MEGAMORPHIC_GET = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class, boolean.class);
+ static final MethodHandle MEGAMORPHIC_GET = findOwnMH_V("megamorphicGet", Object.class, String.class, boolean.class);
static final MethodHandle GLOBALFILTER = findOwnMH_S("globalFilter", Object.class, Object.class);
private static final MethodHandle TRUNCATINGFILTER = findOwnMH_S("truncatingFilter", Object[].class, int.class, Object[].class);
@@ -1924,7 +1924,7 @@
}
if (request.isCallSiteUnstable() || hasWithScope()) {
- return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator), isScope() && NashornCallSiteDescriptor.isScope(desc));
+ return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator));
}
final FindProperty find = findProperty(name, true);
@@ -1983,22 +1983,19 @@
return inv.addSwitchPoint(reservedNameSwitchPoint);
}
- private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod, final boolean isScope) {
+ private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) {
Context.getContextTrusted().getLogger(ObjectClassGenerator.class).warning("Megamorphic getter: " + desc + " " + name + " " +isMethod);
- final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, isScope);
+ final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod);
final MethodHandle guard = getScriptObjectGuard(desc.getMethodType(), true);
return new GuardedInvocation(invoker, guard);
}
@SuppressWarnings("unused")
- private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) {
+ private Object megamorphicGet(final String key, final boolean isMethod) {
final FindProperty find = findProperty(key, true);
if (find != null) {
return find.getObjectValue();
}
- if (isScope) {
- throw referenceError("not.defined", key);
- }
return isMethod ? getNoSuchMethod(key, INVALID_PROGRAM_POINT) : invokeNoSuchProperty(key, INVALID_PROGRAM_POINT);
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8044750.js Wed Jun 04 13:55:21 2014 +0530
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+/**
+ * JDK-8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
+ *
+ * @test
+ * @run
+ */
+
+__noSuchProperty__ = function(name) {
+ return 1;
+}
+
+function func(obj) {
+ with(obj) {
+ // this "foo" getter site becomes megamorphic
+ // due to different 'with' scope objects.
+ foo;
+ }
+}
+
+for (var i = 0; i < 20; i++) {
+ var obj = {};
+ obj.foo = i;
+ obj[i] = i;
+ func(obj);
+}
+
+// pass a 'with' scope object that does not have 'foo'.
+// callsite inside func should see __noSuchProperty__
+// hook on global scope object.
+func({});
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java Tue Jun 03 12:05:59 2014 +0200
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java Wed Jun 04 13:55:21 2014 +0530
@@ -512,6 +512,23 @@
assertEquals(e.eval("x", newCtxt), 2);
}
+ // @bug 8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
+ @Test
+ public static void testMegamorphicGetInGlobal() throws Exception {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine engine = m.getEngineByName("nashorn");
+ final String script = "foo";
+ // "foo" is megamorphic because of different global scopes.
+ // Make sure ScriptContext variable search works even after
+ // it becomes megamorphic.
+ for (int index = 0; index < 25; index++) {
+ final Bindings bindings = new SimpleBindings();
+ bindings.put("foo", index);
+ final Number value = (Number)engine.eval(script, bindings);
+ assertEquals(index, value.intValue());
+ }
+ }
+
/**
* Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals.
*/