8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook

Wed, 04 Jun 2014 16:39:04 +0530

author
sundar
date
Wed, 04 Jun 2014 16:39:04 +0530
changeset 867
85ad3ce0796f
parent 866
77f0308eb2e6
child 868
f557ba467d1d

8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
Reviewed-by: attila, lagergren, hannesw

src/jdk/nashorn/internal/runtime/ScriptObject.java file | annotate | diff | comparison | revisions
test/script/basic/JDK-8044750.js file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/api/scripting/ScopeTest.java file | annotate | diff | comparison | revisions
     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       */

mercurial