Wed, 04 Jun 2014 16:39:04 +0530
8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
Reviewed-by: attila, lagergren, hannesw
1.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Tue Jun 03 17:04:23 2014 +0530 1.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Jun 04 16:39:04 2014 +0530 1.3 @@ -132,7 +132,7 @@ 1.4 1.5 /** Method handle to retrive prototype of this object */ 1.6 public static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class); 1.7 - static final MethodHandle MEGAMORPHIC_GET = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class, boolean.class); 1.8 + static final MethodHandle MEGAMORPHIC_GET = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class); 1.9 static final MethodHandle GLOBALFILTER = findOwnMH("globalFilter", Object.class, Object.class); 1.10 1.11 static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class); 1.12 @@ -1745,7 +1745,7 @@ 1.13 protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) { 1.14 final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); 1.15 if (request.isCallSiteUnstable() || hasWithScope()) { 1.16 - return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator), isScope() && NashornCallSiteDescriptor.isScope(desc)); 1.17 + return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator)); 1.18 } 1.19 1.20 final FindProperty find = findProperty(name, true); 1.21 @@ -1788,22 +1788,19 @@ 1.22 } 1.23 1.24 private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, 1.25 - final boolean isMethod, final boolean isScope) { 1.26 - final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, isScope); 1.27 + final boolean isMethod) { 1.28 + final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod); 1.29 final MethodHandle guard = getScriptObjectGuard(desc.getMethodType()); 1.30 return new GuardedInvocation(invoker, guard); 1.31 } 1.32 1.33 @SuppressWarnings("unused") 1.34 - private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) { 1.35 + private Object megamorphicGet(final String key, final boolean isMethod) { 1.36 final FindProperty find = findProperty(key, true); 1.37 1.38 if (find != null) { 1.39 return find.getObjectValue(); 1.40 } 1.41 - if (isScope) { 1.42 - throw referenceError("not.defined", key); 1.43 - } 1.44 1.45 return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key); 1.46 }
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/script/basic/JDK-8044750.js Wed Jun 04 16:39:04 2014 +0530 2.3 @@ -0,0 +1,53 @@ 2.4 +/* 2.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/** 2.28 + * JDK-8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook 2.29 + * 2.30 + * @test 2.31 + * @run 2.32 + */ 2.33 + 2.34 +__noSuchProperty__ = function(name) { 2.35 + return 1; 2.36 +} 2.37 + 2.38 +function func(obj) { 2.39 + with(obj) { 2.40 + // this "foo" getter site becomes megamorphic 2.41 + // due to different 'with' scope objects. 2.42 + foo; 2.43 + } 2.44 +} 2.45 + 2.46 +for (var i = 0; i < 20; i++) { 2.47 + var obj = {}; 2.48 + obj.foo = i; 2.49 + obj[i] = i; 2.50 + func(obj); 2.51 +} 2.52 + 2.53 +// pass a 'with' scope object that does not have 'foo'. 2.54 +// callsite inside func should see __noSuchProperty__ 2.55 +// hook on global scope object. 2.56 +func({});
3.1 --- a/test/src/jdk/nashorn/api/scripting/ScopeTest.java Tue Jun 03 17:04:23 2014 +0530 3.2 +++ b/test/src/jdk/nashorn/api/scripting/ScopeTest.java Wed Jun 04 16:39:04 2014 +0530 3.3 @@ -510,6 +510,23 @@ 3.4 assertEquals(e.eval("x", newCtxt), 2); 3.5 } 3.6 3.7 + // @bug 8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook 3.8 + @Test 3.9 + public static void testMegamorphicGetInGlobal() throws Exception { 3.10 + final ScriptEngineManager m = new ScriptEngineManager(); 3.11 + final ScriptEngine engine = m.getEngineByName("nashorn"); 3.12 + final String script = "foo"; 3.13 + // "foo" is megamorphic because of different global scopes. 3.14 + // Make sure ScriptContext variable search works even after 3.15 + // it becomes megamorphic. 3.16 + for (int index = 0; index < 25; index++) { 3.17 + final Bindings bindings = new SimpleBindings(); 3.18 + bindings.put("foo", index); 3.19 + final Number value = (Number)engine.eval(script, bindings); 3.20 + assertEquals(index, value.intValue()); 3.21 + } 3.22 + } 3.23 + 3.24 /** 3.25 * Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals. 3.26 */