8026016: too many relinks dominate avatar.js http benchmark
Reviewed-by: sundar, jlaskey, attila
This commit is contained in:
parent
e0df3515ce
commit
3c50f75173
@ -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)) {
|
||||
|
68
nashorn/test/script/basic/JDK-8026016.js
Normal file
68
nashorn/test/script/basic/JDK-8026016.js
Normal 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();
|
182
nashorn/test/script/basic/JDK-8026016.js.EXPECTED
Normal file
182
nashorn/test/script/basic/JDK-8026016.js.EXPECTED
Normal 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 _
|
Loading…
Reference in New Issue
Block a user