# HG changeset patch # User hannesw # Date 1381743915 -7200 # Node ID 8c617a092d6841fa5fc4cdc9bae8f0971d5fbf25 # Parent 6cb4f20d971f4c30ea71f4f239d76e5e0dd7ed4d 8026016: too many relinks dominate avatar.js http benchmark Reviewed-by: sundar, jlaskey, attila diff -r 6cb4f20d971f -r 8c617a092d68 src/jdk/nashorn/internal/runtime/ScriptObject.java --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Oct 11 14:54:16 2013 +0200 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Oct 14 11:45:15 2013 +0200 @@ -37,6 +37,8 @@ import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE; import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex; +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; @@ -131,6 +133,7 @@ static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class); static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class); + static final MethodHandle MEGAMORPHIC_GET = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class); static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class); static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); @@ -388,7 +391,7 @@ return global.newDataDescriptor(getWithProperty(property), configurable, enumerable, writable); } - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -592,7 +595,7 @@ * @param value value to define */ protected final void defineOwnProperty(final int index, final Object value) { - assert ArrayIndex.isValidArrayIndex(index) : "invalid array index"; + assert isValidArrayIndex(index) : "invalid array index"; final long longIndex = ArrayIndex.toLongIndex(index); if (longIndex >= getArray().length()) { // make array big enough to hold.. @@ -602,9 +605,9 @@ } private void checkIntegerKey(final String key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { final ArrayData data = getArray(); if (data.has(index)) { @@ -614,7 +617,7 @@ } private void removeArraySlot(final String key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -717,6 +720,28 @@ } /** + * Low level property API. This is similar to {@link #findProperty(String, boolean)} but returns a + * {@code boolean} value instead of a {@link FindProperty} object. + * @param key Property key. + * @param deep Whether the search should look up proto chain. + * @return true if the property was found. + */ + boolean hasProperty(final String key, final boolean deep) { + if (getMap().findProperty(key) != null) { + return true; + } + + if (deep) { + final ScriptObject myProto = getProto(); + if (myProto != null) { + return myProto.hasProperty(key, deep); + } + } + + return false; + } + + /** * Add a new property to the object. *

* This a more "low level" way that doesn't involve {@link PropertyDescriptor}s @@ -1708,8 +1733,11 @@ */ protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) { final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); + if (request.isCallSiteUnstable()) { + return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator)); + } + final FindProperty find = findProperty(name, true); - MethodHandle methodHandle; if (find == null) { @@ -1727,10 +1755,6 @@ throw new AssertionError(); // never invoked with any other operation } - if (request.isCallSiteUnstable()) { - return findMegaMorphicGetMethod(desc, name); - } - final Class returnType = desc.getMethodType().returnType(); final Property property = find.getProperty(); methodHandle = find.getGetter(returnType); @@ -1757,11 +1781,21 @@ return new GuardedInvocation(Lookup.emptyGetter(returnType), getMap().getProtoGetSwitchPoint(proto, name), guard); } - private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name) { - final MethodType mhType = desc.getMethodType().insertParameterTypes(1, Object.class); - final GuardedInvocation inv = findGetIndexMethod(mhType); - - return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard()); + private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) { + final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod); + final MethodHandle guard = getScriptObjectGuard(desc.getMethodType()); + return new GuardedInvocation(invoker, guard); + } + + @SuppressWarnings("unused") + private Object megamorphicGet(final String key, final boolean isMethod) { + final FindProperty find = findProperty(key, true); + + if (find != null) { + return getObjectValue(find); + } + + return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key); } /** @@ -1810,7 +1844,7 @@ */ protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) { final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); - if(request.isCallSiteUnstable()) { + if (request.isCallSiteUnstable()) { return findMegaMorphicSetMethod(desc, name); } @@ -2045,6 +2079,26 @@ return UNDEFINED; } + /** + * Get __noSuchMethod__ as a function bound to this object and {@code name} if it is defined. + * @param name the method name + * @return the bound function, or undefined + */ + private Object getNoSuchMethod(final String name) { + final FindProperty find = findProperty(NO_SUCH_METHOD_NAME, true); + + if (find == null) { + return invokeNoSuchProperty(name); + } + + final Object value = getObjectValue(find); + if (! (value instanceof ScriptFunction)) { + return UNDEFINED; + } + + return ((ScriptFunction)value).makeBoundFunction(this, new Object[] {name}); + } + private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final String name) { return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()), getMap().getProtoGetSwitchPoint(proto, name), NashornGuards.getMapGuard(getMap())); } @@ -2308,7 +2362,7 @@ } private int getInt(final int index, final String key) { - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject object = this; ; ) { final FindProperty find = object.findProperty(key, false, false, this); @@ -2339,7 +2393,7 @@ @Override public int getInt(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2351,7 +2405,7 @@ @Override public int getInt(final double key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2363,7 +2417,7 @@ @Override public int getInt(final long key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2385,7 +2439,7 @@ } private long getLong(final int index, final String key) { - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject object = this; ; ) { final FindProperty find = object.findProperty(key, false, false, this); @@ -2416,7 +2470,7 @@ @Override public long getLong(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2428,7 +2482,7 @@ @Override public long getLong(final double key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2440,7 +2494,7 @@ @Override public long getLong(final long key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2462,7 +2516,7 @@ } private double getDouble(final int index, final String key) { - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject object = this; ; ) { final FindProperty find = object.findProperty(key, false, false, this); @@ -2493,7 +2547,7 @@ @Override public double getDouble(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2505,7 +2559,7 @@ @Override public double getDouble(final double key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2517,7 +2571,7 @@ @Override public double getDouble(final long key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2539,7 +2593,7 @@ } private Object get(final int index, final String key) { - if (ArrayIndex.isValidArrayIndex(index)) { + if (isValidArrayIndex(index)) { for (ScriptObject object = this; ; ) { final FindProperty find = object.findProperty(key, false, false, this); @@ -2570,7 +2624,7 @@ @Override public Object get(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2582,7 +2636,7 @@ @Override public Object get(final double key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2594,7 +2648,7 @@ @Override public Object get(final long key) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -2710,9 +2764,9 @@ @Override public void set(final Object key, final int value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2722,14 +2776,15 @@ return; } - set(key, JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final Object key, final long value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2739,14 +2794,15 @@ return; } - set(key, JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final Object key, final double value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2756,14 +2812,15 @@ return; } - set(key, JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final Object key, final Object value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2773,17 +2830,15 @@ return; } - final String propName = JSType.toString(key); - final FindProperty find = findProperty(propName, true); - - setObject(find, strict, propName, value); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, value); } @Override public void set(final double key, final int value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2793,14 +2848,15 @@ return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final double key, final long value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2810,14 +2866,15 @@ return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final double key, final double value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2827,14 +2884,15 @@ return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final double key, final Object value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2844,14 +2902,15 @@ return; } - set(JSType.toObject(key), value, strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, value); } @Override public void set(final long key, final int value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2861,31 +2920,15 @@ return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override public void set(final long key, final long value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { - if (getArray().has(index)) { - setArray(getArray().set(index, value, strict)); - } else { - doesNotHave(index, value, strict); - } - - return; - } - - set(JSType.toObject(key), JSType.toObject(value), strict); - } - - @Override - public void set(final long key, final double value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2895,14 +2938,15 @@ return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override - public void set(final long key, final Object value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + public void set(final long key, final double value, final boolean strict) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2912,14 +2956,15 @@ return; } - set(JSType.toObject(key), value, strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override - public void set(final int key, final int value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + public void set(final long key, final Object value, final boolean strict) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2929,14 +2974,15 @@ return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, value); } @Override - public void set(final int key, final long value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + public void set(final int key, final int value, final boolean strict) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2946,14 +2992,15 @@ return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override - public void set(final int key, final double value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + public void set(final int key, final long value, final boolean strict) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2963,14 +3010,15 @@ return; } - set(JSType.toObject(key), JSType.toObject(value), strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); } @Override - public void set(final int key, final Object value, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + public void set(final int key, final double value, final boolean strict) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { if (getArray().has(index)) { setArray(getArray().set(index, value, strict)); } else { @@ -2980,14 +3028,33 @@ return; } - set(JSType.toObject(key), value, strict); + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); + } + + @Override + public void set(final int key, final Object value, final boolean strict) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { + if (getArray().has(index)) { + setArray(getArray().set(index, value, strict)); + } else { + doesNotHave(index, value, strict); + } + + return; + } + + final String propName = JSType.toString(key); + setObject(findProperty(propName, true), strict, propName, value); } @Override public boolean has(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { for (ScriptObject self = this; self != null; self = self.getProto()) { if (self.getArray().has(index)) { return true; @@ -2995,33 +3062,14 @@ } } - final FindProperty find = findProperty(JSType.toString(key), true); - - return find != null; + return hasProperty(JSType.toString(key), true); } @Override public boolean has(final double key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { - for (ScriptObject self = this; self != null; self = self.getProto()) { - if (self.getArray().has(index)) { - return true; - } - } - } - - final FindProperty find = findProperty(JSType.toString(key), true); - - return find != null; - } - - @Override - public boolean has(final long key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { for (ScriptObject self = this; self != null; self = self.getProto()) { if (self.getArray().has(index)) { return true; @@ -3029,16 +3077,14 @@ } } - final FindProperty find = findProperty(JSType.toString(key), true); - - return find != null; + return hasProperty(JSType.toString(key), true); } @Override - public boolean has(final int key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (ArrayIndex.isValidArrayIndex(index)) { + public boolean has(final long key) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { for (ScriptObject self = this; self != null; self = self.getProto()) { if (self.getArray().has(index)) { return true; @@ -3046,66 +3092,47 @@ } } - final FindProperty find = findProperty(JSType.toString(key), true); - - return find != null; + return hasProperty(JSType.toString(key), true); + } + + @Override + public boolean has(final int key) { + final int index = getArrayIndex(key); + + if (isValidArrayIndex(index)) { + for (ScriptObject self = this; self != null; self = self.getProto()) { + if (self.getArray().has(index)) { + return true; + } + } + } + + return hasProperty(JSType.toString(key), true); } @Override public boolean hasOwnProperty(final Object key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (getArray().has(index)) { - return true; - } - - final FindProperty find = findProperty(JSType.toString(key), false); - - return find != null; + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); } @Override public boolean hasOwnProperty(final int key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (getArray().has(index)) { - return true; - } - - final FindProperty find = findProperty(JSType.toString(key), false); - - return find != null; + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); } @Override public boolean hasOwnProperty(final long key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (getArray().has(index)) { - return true; - } - - final FindProperty find = findProperty(JSType.toString(key), false); - - return find != null; + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); } @Override public boolean hasOwnProperty(final double key) { - final int index = ArrayIndex.getArrayIndex(key); - - if (getArray().has(index)) { - return true; - } - - final FindProperty find = findProperty(JSType.toString(key), false); - - return find != null; + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); } @Override public boolean delete(final int key, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -3121,7 +3148,7 @@ @Override public boolean delete(final long key, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -3137,7 +3164,7 @@ @Override public boolean delete(final double key, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { @@ -3153,7 +3180,7 @@ @Override public boolean delete(final Object key, final boolean strict) { - final int index = ArrayIndex.getArrayIndex(key); + final int index = getArrayIndex(key); final ArrayData array = getArray(); if (array.has(index)) { diff -r 6cb4f20d971f -r 8c617a092d68 test/script/basic/JDK-8026016.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026016.js Mon Oct 14 11:45:15 2013 +0200 @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2010, 2013, 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-8026016: too many relinks dominate avatar.js http benchmark + * + * @test + * @run + */ + +function accessMegamorphic() { + for (var i = 0; i < 26; i++) { + var o = {}; + o[String.fromCharCode(i + 97)] = 1; + o._; + } +} + +function invokeMegamorphic() { + for (var i = 0; i < 26; i++) { + var o = {}; + o[String.fromCharCode(i + 97)] = 1; + try { + o._(i); + } catch (e) { + print(e); + } + } +} + +Object.prototype.__noSuchProperty__ = function() { + print("no such property", Array.prototype.slice.call(arguments)); +}; + +invokeMegamorphic(); +accessMegamorphic(); + +Object.prototype.__noSuchMethod__ = function() { + print("no such method", Array.prototype.slice.call(arguments)); +}; + +invokeMegamorphic(); +accessMegamorphic(); + +Object.prototype.__noSuchMethod__ = "nofunction"; + +invokeMegamorphic(); +accessMegamorphic(); diff -r 6cb4f20d971f -r 8c617a092d68 test/script/basic/JDK-8026016.js.EXPECTED --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026016.js.EXPECTED Mon Oct 14 11:45:15 2013 +0200 @@ -0,0 +1,182 @@ +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +TypeError: Cannot call undefined +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such method _,0 +no such method _,1 +no such method _,2 +no such method _,3 +no such method _,4 +no such method _,5 +no such method _,6 +no such method _,7 +no such method _,8 +no such method _,9 +no such method _,10 +no such method _,11 +no such method _,12 +no such method _,13 +no such method _,14 +no such method _,15 +no such method _,16 +no such method _,17 +no such method _,18 +no such method _,19 +no such method _,20 +no such method _,21 +no such method _,22 +no such method _,23 +no such method _,24 +no such method _,25 +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +TypeError: Cannot call undefined +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _ +no such property _