8026016: too many relinks dominate avatar.js http benchmark

Reviewed-by: sundar, jlaskey, attila
This commit is contained in:
Hannes Wallnöfer 2013-10-14 11:45:15 +02:00
parent e0df3515ce
commit 3c50f75173
3 changed files with 419 additions and 142 deletions

View File

@ -37,6 +37,8 @@ import static jdk.nashorn.internal.runtime.PropertyDescriptor.SET;
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
* @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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
private void checkIntegerKey(final String key) {
final int index = ArrayIndex.getArrayIndex(key);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
final ArrayData data = getArray();
if (data.has(index)) {
@ -614,7 +617,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
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)) {
@ -716,6 +719,28 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
return null;
}
/**
* 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.
* <p>
@ -1708,8 +1733,11 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
*/
protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
final FindProperty find = findProperty(name, true);
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
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);
}
return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard());
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
*/
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@Override
public void set(final Object key, final int value, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2722,14 +2776,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2739,14 +2794,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2756,14 +2812,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2773,17 +2830,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2793,14 +2848,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2810,14 +2866,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2827,14 +2884,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2844,14 +2902,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2861,14 +2920,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2878,14 +2938,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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 double value, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2895,14 +2956,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2912,14 +2974,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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 int key, final int value, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2929,14 +2992,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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 long value, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2946,14 +3010,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2963,14 +3028,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
setArray(getArray().set(index, value, strict));
} else {
@ -2980,14 +3046,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
return;
}
set(JSType.toObject(key), value, strict);
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
for (ScriptObject self = this; self != null; self = self.getProto()) {
if (self.getArray().has(index)) {
return true;
@ -2995,16 +3062,14 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
}
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
for (ScriptObject self = this; self != null; self = self.getProto()) {
if (self.getArray().has(index)) {
return true;
@ -3012,16 +3077,14 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
}
final FindProperty find = findProperty(JSType.toString(key), true);
return find != null;
return hasProperty(JSType.toString(key), true);
}
@Override
public boolean has(final long key) {
final int index = ArrayIndex.getArrayIndex(key);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
for (ScriptObject self = this; self != null; self = self.getProto()) {
if (self.getArray().has(index)) {
return true;
@ -3029,16 +3092,14 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
}
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);
final int index = getArrayIndex(key);
if (ArrayIndex.isValidArrayIndex(index)) {
if (isValidArrayIndex(index)) {
for (ScriptObject self = this; self != null; self = self.getProto()) {
if (self.getArray().has(index)) {
return true;
@ -3046,66 +3107,32 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
}
final FindProperty find = findProperty(JSType.toString(key), true);
return find != null;
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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
@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)) {

View File

@ -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();

View File

@ -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 _