Mon, 14 Oct 2013 11:45:15 +0200
8026016: too many relinks dominate avatar.js http benchmark
Reviewed-by: sundar, jlaskey, attila
1.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Oct 11 14:54:16 2013 +0200 1.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Oct 14 11:45:15 2013 +0200 1.3 @@ -37,6 +37,8 @@ 1.4 import static jdk.nashorn.internal.runtime.PropertyDescriptor.VALUE; 1.5 import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE; 1.6 import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; 1.7 +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex; 1.8 +import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; 1.9 1.10 import java.lang.invoke.MethodHandle; 1.11 import java.lang.invoke.MethodHandles; 1.12 @@ -131,6 +133,7 @@ 1.13 1.14 static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class); 1.15 static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class); 1.16 + static final MethodHandle MEGAMORPHIC_GET = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class); 1.17 1.18 static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class); 1.19 static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); 1.20 @@ -388,7 +391,7 @@ 1.21 return global.newDataDescriptor(getWithProperty(property), configurable, enumerable, writable); 1.22 } 1.23 1.24 - final int index = ArrayIndex.getArrayIndex(key); 1.25 + final int index = getArrayIndex(key); 1.26 final ArrayData array = getArray(); 1.27 1.28 if (array.has(index)) { 1.29 @@ -592,7 +595,7 @@ 1.30 * @param value value to define 1.31 */ 1.32 protected final void defineOwnProperty(final int index, final Object value) { 1.33 - assert ArrayIndex.isValidArrayIndex(index) : "invalid array index"; 1.34 + assert isValidArrayIndex(index) : "invalid array index"; 1.35 final long longIndex = ArrayIndex.toLongIndex(index); 1.36 if (longIndex >= getArray().length()) { 1.37 // make array big enough to hold.. 1.38 @@ -602,9 +605,9 @@ 1.39 } 1.40 1.41 private void checkIntegerKey(final String key) { 1.42 - final int index = ArrayIndex.getArrayIndex(key); 1.43 - 1.44 - if (ArrayIndex.isValidArrayIndex(index)) { 1.45 + final int index = getArrayIndex(key); 1.46 + 1.47 + if (isValidArrayIndex(index)) { 1.48 final ArrayData data = getArray(); 1.49 1.50 if (data.has(index)) { 1.51 @@ -614,7 +617,7 @@ 1.52 } 1.53 1.54 private void removeArraySlot(final String key) { 1.55 - final int index = ArrayIndex.getArrayIndex(key); 1.56 + final int index = getArrayIndex(key); 1.57 final ArrayData array = getArray(); 1.58 1.59 if (array.has(index)) { 1.60 @@ -717,6 +720,28 @@ 1.61 } 1.62 1.63 /** 1.64 + * Low level property API. This is similar to {@link #findProperty(String, boolean)} but returns a 1.65 + * {@code boolean} value instead of a {@link FindProperty} object. 1.66 + * @param key Property key. 1.67 + * @param deep Whether the search should look up proto chain. 1.68 + * @return true if the property was found. 1.69 + */ 1.70 + boolean hasProperty(final String key, final boolean deep) { 1.71 + if (getMap().findProperty(key) != null) { 1.72 + return true; 1.73 + } 1.74 + 1.75 + if (deep) { 1.76 + final ScriptObject myProto = getProto(); 1.77 + if (myProto != null) { 1.78 + return myProto.hasProperty(key, deep); 1.79 + } 1.80 + } 1.81 + 1.82 + return false; 1.83 + } 1.84 + 1.85 + /** 1.86 * Add a new property to the object. 1.87 * <p> 1.88 * This a more "low level" way that doesn't involve {@link PropertyDescriptor}s 1.89 @@ -1708,8 +1733,11 @@ 1.90 */ 1.91 protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) { 1.92 final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); 1.93 + if (request.isCallSiteUnstable()) { 1.94 + return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator)); 1.95 + } 1.96 + 1.97 final FindProperty find = findProperty(name, true); 1.98 - 1.99 MethodHandle methodHandle; 1.100 1.101 if (find == null) { 1.102 @@ -1727,10 +1755,6 @@ 1.103 throw new AssertionError(); // never invoked with any other operation 1.104 } 1.105 1.106 - if (request.isCallSiteUnstable()) { 1.107 - return findMegaMorphicGetMethod(desc, name); 1.108 - } 1.109 - 1.110 final Class<?> returnType = desc.getMethodType().returnType(); 1.111 final Property property = find.getProperty(); 1.112 methodHandle = find.getGetter(returnType); 1.113 @@ -1757,11 +1781,21 @@ 1.114 return new GuardedInvocation(Lookup.emptyGetter(returnType), getMap().getProtoGetSwitchPoint(proto, name), guard); 1.115 } 1.116 1.117 - private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name) { 1.118 - final MethodType mhType = desc.getMethodType().insertParameterTypes(1, Object.class); 1.119 - final GuardedInvocation inv = findGetIndexMethod(mhType); 1.120 - 1.121 - return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard()); 1.122 + private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name, final boolean isMethod) { 1.123 + final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod); 1.124 + final MethodHandle guard = getScriptObjectGuard(desc.getMethodType()); 1.125 + return new GuardedInvocation(invoker, guard); 1.126 + } 1.127 + 1.128 + @SuppressWarnings("unused") 1.129 + private Object megamorphicGet(final String key, final boolean isMethod) { 1.130 + final FindProperty find = findProperty(key, true); 1.131 + 1.132 + if (find != null) { 1.133 + return getObjectValue(find); 1.134 + } 1.135 + 1.136 + return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key); 1.137 } 1.138 1.139 /** 1.140 @@ -1810,7 +1844,7 @@ 1.141 */ 1.142 protected GuardedInvocation findSetMethod(final CallSiteDescriptor desc, final LinkRequest request) { 1.143 final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); 1.144 - if(request.isCallSiteUnstable()) { 1.145 + if (request.isCallSiteUnstable()) { 1.146 return findMegaMorphicSetMethod(desc, name); 1.147 } 1.148 1.149 @@ -2045,6 +2079,26 @@ 1.150 return UNDEFINED; 1.151 } 1.152 1.153 + /** 1.154 + * Get __noSuchMethod__ as a function bound to this object and {@code name} if it is defined. 1.155 + * @param name the method name 1.156 + * @return the bound function, or undefined 1.157 + */ 1.158 + private Object getNoSuchMethod(final String name) { 1.159 + final FindProperty find = findProperty(NO_SUCH_METHOD_NAME, true); 1.160 + 1.161 + if (find == null) { 1.162 + return invokeNoSuchProperty(name); 1.163 + } 1.164 + 1.165 + final Object value = getObjectValue(find); 1.166 + if (! (value instanceof ScriptFunction)) { 1.167 + return UNDEFINED; 1.168 + } 1.169 + 1.170 + return ((ScriptFunction)value).makeBoundFunction(this, new Object[] {name}); 1.171 + } 1.172 + 1.173 private GuardedInvocation createEmptyGetter(final CallSiteDescriptor desc, final String name) { 1.174 return new GuardedInvocation(Lookup.emptyGetter(desc.getMethodType().returnType()), getMap().getProtoGetSwitchPoint(proto, name), NashornGuards.getMapGuard(getMap())); 1.175 } 1.176 @@ -2308,7 +2362,7 @@ 1.177 } 1.178 1.179 private int getInt(final int index, final String key) { 1.180 - if (ArrayIndex.isValidArrayIndex(index)) { 1.181 + if (isValidArrayIndex(index)) { 1.182 for (ScriptObject object = this; ; ) { 1.183 final FindProperty find = object.findProperty(key, false, false, this); 1.184 1.185 @@ -2339,7 +2393,7 @@ 1.186 1.187 @Override 1.188 public int getInt(final Object key) { 1.189 - final int index = ArrayIndex.getArrayIndex(key); 1.190 + final int index = getArrayIndex(key); 1.191 final ArrayData array = getArray(); 1.192 1.193 if (array.has(index)) { 1.194 @@ -2351,7 +2405,7 @@ 1.195 1.196 @Override 1.197 public int getInt(final double key) { 1.198 - final int index = ArrayIndex.getArrayIndex(key); 1.199 + final int index = getArrayIndex(key); 1.200 final ArrayData array = getArray(); 1.201 1.202 if (array.has(index)) { 1.203 @@ -2363,7 +2417,7 @@ 1.204 1.205 @Override 1.206 public int getInt(final long key) { 1.207 - final int index = ArrayIndex.getArrayIndex(key); 1.208 + final int index = getArrayIndex(key); 1.209 final ArrayData array = getArray(); 1.210 1.211 if (array.has(index)) { 1.212 @@ -2385,7 +2439,7 @@ 1.213 } 1.214 1.215 private long getLong(final int index, final String key) { 1.216 - if (ArrayIndex.isValidArrayIndex(index)) { 1.217 + if (isValidArrayIndex(index)) { 1.218 for (ScriptObject object = this; ; ) { 1.219 final FindProperty find = object.findProperty(key, false, false, this); 1.220 1.221 @@ -2416,7 +2470,7 @@ 1.222 1.223 @Override 1.224 public long getLong(final Object key) { 1.225 - final int index = ArrayIndex.getArrayIndex(key); 1.226 + final int index = getArrayIndex(key); 1.227 final ArrayData array = getArray(); 1.228 1.229 if (array.has(index)) { 1.230 @@ -2428,7 +2482,7 @@ 1.231 1.232 @Override 1.233 public long getLong(final double key) { 1.234 - final int index = ArrayIndex.getArrayIndex(key); 1.235 + final int index = getArrayIndex(key); 1.236 final ArrayData array = getArray(); 1.237 1.238 if (array.has(index)) { 1.239 @@ -2440,7 +2494,7 @@ 1.240 1.241 @Override 1.242 public long getLong(final long key) { 1.243 - final int index = ArrayIndex.getArrayIndex(key); 1.244 + final int index = getArrayIndex(key); 1.245 final ArrayData array = getArray(); 1.246 1.247 if (array.has(index)) { 1.248 @@ -2462,7 +2516,7 @@ 1.249 } 1.250 1.251 private double getDouble(final int index, final String key) { 1.252 - if (ArrayIndex.isValidArrayIndex(index)) { 1.253 + if (isValidArrayIndex(index)) { 1.254 for (ScriptObject object = this; ; ) { 1.255 final FindProperty find = object.findProperty(key, false, false, this); 1.256 1.257 @@ -2493,7 +2547,7 @@ 1.258 1.259 @Override 1.260 public double getDouble(final Object key) { 1.261 - final int index = ArrayIndex.getArrayIndex(key); 1.262 + final int index = getArrayIndex(key); 1.263 final ArrayData array = getArray(); 1.264 1.265 if (array.has(index)) { 1.266 @@ -2505,7 +2559,7 @@ 1.267 1.268 @Override 1.269 public double getDouble(final double key) { 1.270 - final int index = ArrayIndex.getArrayIndex(key); 1.271 + final int index = getArrayIndex(key); 1.272 final ArrayData array = getArray(); 1.273 1.274 if (array.has(index)) { 1.275 @@ -2517,7 +2571,7 @@ 1.276 1.277 @Override 1.278 public double getDouble(final long key) { 1.279 - final int index = ArrayIndex.getArrayIndex(key); 1.280 + final int index = getArrayIndex(key); 1.281 final ArrayData array = getArray(); 1.282 1.283 if (array.has(index)) { 1.284 @@ -2539,7 +2593,7 @@ 1.285 } 1.286 1.287 private Object get(final int index, final String key) { 1.288 - if (ArrayIndex.isValidArrayIndex(index)) { 1.289 + if (isValidArrayIndex(index)) { 1.290 for (ScriptObject object = this; ; ) { 1.291 final FindProperty find = object.findProperty(key, false, false, this); 1.292 1.293 @@ -2570,7 +2624,7 @@ 1.294 1.295 @Override 1.296 public Object get(final Object key) { 1.297 - final int index = ArrayIndex.getArrayIndex(key); 1.298 + final int index = getArrayIndex(key); 1.299 final ArrayData array = getArray(); 1.300 1.301 if (array.has(index)) { 1.302 @@ -2582,7 +2636,7 @@ 1.303 1.304 @Override 1.305 public Object get(final double key) { 1.306 - final int index = ArrayIndex.getArrayIndex(key); 1.307 + final int index = getArrayIndex(key); 1.308 final ArrayData array = getArray(); 1.309 1.310 if (array.has(index)) { 1.311 @@ -2594,7 +2648,7 @@ 1.312 1.313 @Override 1.314 public Object get(final long key) { 1.315 - final int index = ArrayIndex.getArrayIndex(key); 1.316 + final int index = getArrayIndex(key); 1.317 final ArrayData array = getArray(); 1.318 1.319 if (array.has(index)) { 1.320 @@ -2710,9 +2764,9 @@ 1.321 1.322 @Override 1.323 public void set(final Object key, final int value, final boolean strict) { 1.324 - final int index = ArrayIndex.getArrayIndex(key); 1.325 - 1.326 - if (ArrayIndex.isValidArrayIndex(index)) { 1.327 + final int index = getArrayIndex(key); 1.328 + 1.329 + if (isValidArrayIndex(index)) { 1.330 if (getArray().has(index)) { 1.331 setArray(getArray().set(index, value, strict)); 1.332 } else { 1.333 @@ -2722,14 +2776,15 @@ 1.334 return; 1.335 } 1.336 1.337 - set(key, JSType.toObject(value), strict); 1.338 + final String propName = JSType.toString(key); 1.339 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.340 } 1.341 1.342 @Override 1.343 public void set(final Object key, final long value, final boolean strict) { 1.344 - final int index = ArrayIndex.getArrayIndex(key); 1.345 - 1.346 - if (ArrayIndex.isValidArrayIndex(index)) { 1.347 + final int index = getArrayIndex(key); 1.348 + 1.349 + if (isValidArrayIndex(index)) { 1.350 if (getArray().has(index)) { 1.351 setArray(getArray().set(index, value, strict)); 1.352 } else { 1.353 @@ -2739,14 +2794,15 @@ 1.354 return; 1.355 } 1.356 1.357 - set(key, JSType.toObject(value), strict); 1.358 + final String propName = JSType.toString(key); 1.359 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.360 } 1.361 1.362 @Override 1.363 public void set(final Object key, final double value, final boolean strict) { 1.364 - final int index = ArrayIndex.getArrayIndex(key); 1.365 - 1.366 - if (ArrayIndex.isValidArrayIndex(index)) { 1.367 + final int index = getArrayIndex(key); 1.368 + 1.369 + if (isValidArrayIndex(index)) { 1.370 if (getArray().has(index)) { 1.371 setArray(getArray().set(index, value, strict)); 1.372 } else { 1.373 @@ -2756,14 +2812,15 @@ 1.374 return; 1.375 } 1.376 1.377 - set(key, JSType.toObject(value), strict); 1.378 + final String propName = JSType.toString(key); 1.379 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.380 } 1.381 1.382 @Override 1.383 public void set(final Object key, final Object value, final boolean strict) { 1.384 - final int index = ArrayIndex.getArrayIndex(key); 1.385 - 1.386 - if (ArrayIndex.isValidArrayIndex(index)) { 1.387 + final int index = getArrayIndex(key); 1.388 + 1.389 + if (isValidArrayIndex(index)) { 1.390 if (getArray().has(index)) { 1.391 setArray(getArray().set(index, value, strict)); 1.392 } else { 1.393 @@ -2773,17 +2830,15 @@ 1.394 return; 1.395 } 1.396 1.397 - final String propName = JSType.toString(key); 1.398 - final FindProperty find = findProperty(propName, true); 1.399 - 1.400 - setObject(find, strict, propName, value); 1.401 + final String propName = JSType.toString(key); 1.402 + setObject(findProperty(propName, true), strict, propName, value); 1.403 } 1.404 1.405 @Override 1.406 public void set(final double key, final int value, final boolean strict) { 1.407 - final int index = ArrayIndex.getArrayIndex(key); 1.408 - 1.409 - if (ArrayIndex.isValidArrayIndex(index)) { 1.410 + final int index = getArrayIndex(key); 1.411 + 1.412 + if (isValidArrayIndex(index)) { 1.413 if (getArray().has(index)) { 1.414 setArray(getArray().set(index, value, strict)); 1.415 } else { 1.416 @@ -2793,14 +2848,15 @@ 1.417 return; 1.418 } 1.419 1.420 - set(JSType.toObject(key), JSType.toObject(value), strict); 1.421 + final String propName = JSType.toString(key); 1.422 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.423 } 1.424 1.425 @Override 1.426 public void set(final double key, final long value, final boolean strict) { 1.427 - final int index = ArrayIndex.getArrayIndex(key); 1.428 - 1.429 - if (ArrayIndex.isValidArrayIndex(index)) { 1.430 + final int index = getArrayIndex(key); 1.431 + 1.432 + if (isValidArrayIndex(index)) { 1.433 if (getArray().has(index)) { 1.434 setArray(getArray().set(index, value, strict)); 1.435 } else { 1.436 @@ -2810,14 +2866,15 @@ 1.437 return; 1.438 } 1.439 1.440 - set(JSType.toObject(key), JSType.toObject(value), strict); 1.441 + final String propName = JSType.toString(key); 1.442 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.443 } 1.444 1.445 @Override 1.446 public void set(final double key, final double value, final boolean strict) { 1.447 - final int index = ArrayIndex.getArrayIndex(key); 1.448 - 1.449 - if (ArrayIndex.isValidArrayIndex(index)) { 1.450 + final int index = getArrayIndex(key); 1.451 + 1.452 + if (isValidArrayIndex(index)) { 1.453 if (getArray().has(index)) { 1.454 setArray(getArray().set(index, value, strict)); 1.455 } else { 1.456 @@ -2827,14 +2884,15 @@ 1.457 return; 1.458 } 1.459 1.460 - set(JSType.toObject(key), JSType.toObject(value), strict); 1.461 + final String propName = JSType.toString(key); 1.462 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.463 } 1.464 1.465 @Override 1.466 public void set(final double key, final Object value, final boolean strict) { 1.467 - final int index = ArrayIndex.getArrayIndex(key); 1.468 - 1.469 - if (ArrayIndex.isValidArrayIndex(index)) { 1.470 + final int index = getArrayIndex(key); 1.471 + 1.472 + if (isValidArrayIndex(index)) { 1.473 if (getArray().has(index)) { 1.474 setArray(getArray().set(index, value, strict)); 1.475 } else { 1.476 @@ -2844,14 +2902,15 @@ 1.477 return; 1.478 } 1.479 1.480 - set(JSType.toObject(key), value, strict); 1.481 + final String propName = JSType.toString(key); 1.482 + setObject(findProperty(propName, true), strict, propName, value); 1.483 } 1.484 1.485 @Override 1.486 public void set(final long key, final int value, final boolean strict) { 1.487 - final int index = ArrayIndex.getArrayIndex(key); 1.488 - 1.489 - if (ArrayIndex.isValidArrayIndex(index)) { 1.490 + final int index = getArrayIndex(key); 1.491 + 1.492 + if (isValidArrayIndex(index)) { 1.493 if (getArray().has(index)) { 1.494 setArray(getArray().set(index, value, strict)); 1.495 } else { 1.496 @@ -2861,14 +2920,15 @@ 1.497 return; 1.498 } 1.499 1.500 - set(JSType.toObject(key), JSType.toObject(value), strict); 1.501 + final String propName = JSType.toString(key); 1.502 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.503 } 1.504 1.505 @Override 1.506 public void set(final long key, final long value, final boolean strict) { 1.507 - final int index = ArrayIndex.getArrayIndex(key); 1.508 - 1.509 - if (ArrayIndex.isValidArrayIndex(index)) { 1.510 + final int index = getArrayIndex(key); 1.511 + 1.512 + if (isValidArrayIndex(index)) { 1.513 if (getArray().has(index)) { 1.514 setArray(getArray().set(index, value, strict)); 1.515 } else { 1.516 @@ -2878,14 +2938,15 @@ 1.517 return; 1.518 } 1.519 1.520 - set(JSType.toObject(key), JSType.toObject(value), strict); 1.521 + final String propName = JSType.toString(key); 1.522 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.523 } 1.524 1.525 @Override 1.526 public void set(final long key, final double value, final boolean strict) { 1.527 - final int index = ArrayIndex.getArrayIndex(key); 1.528 - 1.529 - if (ArrayIndex.isValidArrayIndex(index)) { 1.530 + final int index = getArrayIndex(key); 1.531 + 1.532 + if (isValidArrayIndex(index)) { 1.533 if (getArray().has(index)) { 1.534 setArray(getArray().set(index, value, strict)); 1.535 } else { 1.536 @@ -2895,14 +2956,15 @@ 1.537 return; 1.538 } 1.539 1.540 - set(JSType.toObject(key), JSType.toObject(value), strict); 1.541 + final String propName = JSType.toString(key); 1.542 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.543 } 1.544 1.545 @Override 1.546 public void set(final long key, final Object value, final boolean strict) { 1.547 - final int index = ArrayIndex.getArrayIndex(key); 1.548 - 1.549 - if (ArrayIndex.isValidArrayIndex(index)) { 1.550 + final int index = getArrayIndex(key); 1.551 + 1.552 + if (isValidArrayIndex(index)) { 1.553 if (getArray().has(index)) { 1.554 setArray(getArray().set(index, value, strict)); 1.555 } else { 1.556 @@ -2912,14 +2974,15 @@ 1.557 return; 1.558 } 1.559 1.560 - set(JSType.toObject(key), value, strict); 1.561 + final String propName = JSType.toString(key); 1.562 + setObject(findProperty(propName, true), strict, propName, value); 1.563 } 1.564 1.565 @Override 1.566 public void set(final int key, final int value, final boolean strict) { 1.567 - final int index = ArrayIndex.getArrayIndex(key); 1.568 - 1.569 - if (ArrayIndex.isValidArrayIndex(index)) { 1.570 + final int index = getArrayIndex(key); 1.571 + 1.572 + if (isValidArrayIndex(index)) { 1.573 if (getArray().has(index)) { 1.574 setArray(getArray().set(index, value, strict)); 1.575 } else { 1.576 @@ -2929,14 +2992,15 @@ 1.577 return; 1.578 } 1.579 1.580 - set(JSType.toObject(key), JSType.toObject(value), strict); 1.581 + final String propName = JSType.toString(key); 1.582 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.583 } 1.584 1.585 @Override 1.586 public void set(final int key, final long value, final boolean strict) { 1.587 - final int index = ArrayIndex.getArrayIndex(key); 1.588 - 1.589 - if (ArrayIndex.isValidArrayIndex(index)) { 1.590 + final int index = getArrayIndex(key); 1.591 + 1.592 + if (isValidArrayIndex(index)) { 1.593 if (getArray().has(index)) { 1.594 setArray(getArray().set(index, value, strict)); 1.595 } else { 1.596 @@ -2946,14 +3010,15 @@ 1.597 return; 1.598 } 1.599 1.600 - set(JSType.toObject(key), JSType.toObject(value), strict); 1.601 + final String propName = JSType.toString(key); 1.602 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.603 } 1.604 1.605 @Override 1.606 public void set(final int key, final double value, final boolean strict) { 1.607 - final int index = ArrayIndex.getArrayIndex(key); 1.608 - 1.609 - if (ArrayIndex.isValidArrayIndex(index)) { 1.610 + final int index = getArrayIndex(key); 1.611 + 1.612 + if (isValidArrayIndex(index)) { 1.613 if (getArray().has(index)) { 1.614 setArray(getArray().set(index, value, strict)); 1.615 } else { 1.616 @@ -2963,14 +3028,15 @@ 1.617 return; 1.618 } 1.619 1.620 - set(JSType.toObject(key), JSType.toObject(value), strict); 1.621 + final String propName = JSType.toString(key); 1.622 + setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 1.623 } 1.624 1.625 @Override 1.626 public void set(final int key, final Object value, final boolean strict) { 1.627 - final int index = ArrayIndex.getArrayIndex(key); 1.628 - 1.629 - if (ArrayIndex.isValidArrayIndex(index)) { 1.630 + final int index = getArrayIndex(key); 1.631 + 1.632 + if (isValidArrayIndex(index)) { 1.633 if (getArray().has(index)) { 1.634 setArray(getArray().set(index, value, strict)); 1.635 } else { 1.636 @@ -2980,14 +3046,15 @@ 1.637 return; 1.638 } 1.639 1.640 - set(JSType.toObject(key), value, strict); 1.641 + final String propName = JSType.toString(key); 1.642 + setObject(findProperty(propName, true), strict, propName, value); 1.643 } 1.644 1.645 @Override 1.646 public boolean has(final Object key) { 1.647 - final int index = ArrayIndex.getArrayIndex(key); 1.648 - 1.649 - if (ArrayIndex.isValidArrayIndex(index)) { 1.650 + final int index = getArrayIndex(key); 1.651 + 1.652 + if (isValidArrayIndex(index)) { 1.653 for (ScriptObject self = this; self != null; self = self.getProto()) { 1.654 if (self.getArray().has(index)) { 1.655 return true; 1.656 @@ -2995,16 +3062,14 @@ 1.657 } 1.658 } 1.659 1.660 - final FindProperty find = findProperty(JSType.toString(key), true); 1.661 - 1.662 - return find != null; 1.663 + return hasProperty(JSType.toString(key), true); 1.664 } 1.665 1.666 @Override 1.667 public boolean has(final double key) { 1.668 - final int index = ArrayIndex.getArrayIndex(key); 1.669 - 1.670 - if (ArrayIndex.isValidArrayIndex(index)) { 1.671 + final int index = getArrayIndex(key); 1.672 + 1.673 + if (isValidArrayIndex(index)) { 1.674 for (ScriptObject self = this; self != null; self = self.getProto()) { 1.675 if (self.getArray().has(index)) { 1.676 return true; 1.677 @@ -3012,16 +3077,14 @@ 1.678 } 1.679 } 1.680 1.681 - final FindProperty find = findProperty(JSType.toString(key), true); 1.682 - 1.683 - return find != null; 1.684 + return hasProperty(JSType.toString(key), true); 1.685 } 1.686 1.687 @Override 1.688 public boolean has(final long key) { 1.689 - final int index = ArrayIndex.getArrayIndex(key); 1.690 - 1.691 - if (ArrayIndex.isValidArrayIndex(index)) { 1.692 + final int index = getArrayIndex(key); 1.693 + 1.694 + if (isValidArrayIndex(index)) { 1.695 for (ScriptObject self = this; self != null; self = self.getProto()) { 1.696 if (self.getArray().has(index)) { 1.697 return true; 1.698 @@ -3029,16 +3092,14 @@ 1.699 } 1.700 } 1.701 1.702 - final FindProperty find = findProperty(JSType.toString(key), true); 1.703 - 1.704 - return find != null; 1.705 + return hasProperty(JSType.toString(key), true); 1.706 } 1.707 1.708 @Override 1.709 public boolean has(final int key) { 1.710 - final int index = ArrayIndex.getArrayIndex(key); 1.711 - 1.712 - if (ArrayIndex.isValidArrayIndex(index)) { 1.713 + final int index = getArrayIndex(key); 1.714 + 1.715 + if (isValidArrayIndex(index)) { 1.716 for (ScriptObject self = this; self != null; self = self.getProto()) { 1.717 if (self.getArray().has(index)) { 1.718 return true; 1.719 @@ -3046,66 +3107,32 @@ 1.720 } 1.721 } 1.722 1.723 - final FindProperty find = findProperty(JSType.toString(key), true); 1.724 - 1.725 - return find != null; 1.726 + return hasProperty(JSType.toString(key), true); 1.727 } 1.728 1.729 @Override 1.730 public boolean hasOwnProperty(final Object key) { 1.731 - final int index = ArrayIndex.getArrayIndex(key); 1.732 - 1.733 - if (getArray().has(index)) { 1.734 - return true; 1.735 - } 1.736 - 1.737 - final FindProperty find = findProperty(JSType.toString(key), false); 1.738 - 1.739 - return find != null; 1.740 + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); 1.741 } 1.742 1.743 @Override 1.744 public boolean hasOwnProperty(final int key) { 1.745 - final int index = ArrayIndex.getArrayIndex(key); 1.746 - 1.747 - if (getArray().has(index)) { 1.748 - return true; 1.749 - } 1.750 - 1.751 - final FindProperty find = findProperty(JSType.toString(key), false); 1.752 - 1.753 - return find != null; 1.754 + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); 1.755 } 1.756 1.757 @Override 1.758 public boolean hasOwnProperty(final long key) { 1.759 - final int index = ArrayIndex.getArrayIndex(key); 1.760 - 1.761 - if (getArray().has(index)) { 1.762 - return true; 1.763 - } 1.764 - 1.765 - final FindProperty find = findProperty(JSType.toString(key), false); 1.766 - 1.767 - return find != null; 1.768 + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); 1.769 } 1.770 1.771 @Override 1.772 public boolean hasOwnProperty(final double key) { 1.773 - final int index = ArrayIndex.getArrayIndex(key); 1.774 - 1.775 - if (getArray().has(index)) { 1.776 - return true; 1.777 - } 1.778 - 1.779 - final FindProperty find = findProperty(JSType.toString(key), false); 1.780 - 1.781 - return find != null; 1.782 + return getArray().has(getArrayIndex(key)) || hasProperty(JSType.toString(key), false); 1.783 } 1.784 1.785 @Override 1.786 public boolean delete(final int key, final boolean strict) { 1.787 - final int index = ArrayIndex.getArrayIndex(key); 1.788 + final int index = getArrayIndex(key); 1.789 final ArrayData array = getArray(); 1.790 1.791 if (array.has(index)) { 1.792 @@ -3121,7 +3148,7 @@ 1.793 1.794 @Override 1.795 public boolean delete(final long key, final boolean strict) { 1.796 - final int index = ArrayIndex.getArrayIndex(key); 1.797 + final int index = getArrayIndex(key); 1.798 final ArrayData array = getArray(); 1.799 1.800 if (array.has(index)) { 1.801 @@ -3137,7 +3164,7 @@ 1.802 1.803 @Override 1.804 public boolean delete(final double key, final boolean strict) { 1.805 - final int index = ArrayIndex.getArrayIndex(key); 1.806 + final int index = getArrayIndex(key); 1.807 final ArrayData array = getArray(); 1.808 1.809 if (array.has(index)) { 1.810 @@ -3153,7 +3180,7 @@ 1.811 1.812 @Override 1.813 public boolean delete(final Object key, final boolean strict) { 1.814 - final int index = ArrayIndex.getArrayIndex(key); 1.815 + final int index = getArrayIndex(key); 1.816 final ArrayData array = getArray(); 1.817 1.818 if (array.has(index)) {
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/script/basic/JDK-8026016.js Mon Oct 14 11:45:15 2013 +0200 2.3 @@ -0,0 +1,68 @@ 2.4 +/* 2.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + */ 2.26 + 2.27 +/** 2.28 + * JDK-8026016: too many relinks dominate avatar.js http benchmark 2.29 + * 2.30 + * @test 2.31 + * @run 2.32 + */ 2.33 + 2.34 +function accessMegamorphic() { 2.35 + for (var i = 0; i < 26; i++) { 2.36 + var o = {}; 2.37 + o[String.fromCharCode(i + 97)] = 1; 2.38 + o._; 2.39 + } 2.40 +} 2.41 + 2.42 +function invokeMegamorphic() { 2.43 + for (var i = 0; i < 26; i++) { 2.44 + var o = {}; 2.45 + o[String.fromCharCode(i + 97)] = 1; 2.46 + try { 2.47 + o._(i); 2.48 + } catch (e) { 2.49 + print(e); 2.50 + } 2.51 + } 2.52 +} 2.53 + 2.54 +Object.prototype.__noSuchProperty__ = function() { 2.55 + print("no such property", Array.prototype.slice.call(arguments)); 2.56 +}; 2.57 + 2.58 +invokeMegamorphic(); 2.59 +accessMegamorphic(); 2.60 + 2.61 +Object.prototype.__noSuchMethod__ = function() { 2.62 + print("no such method", Array.prototype.slice.call(arguments)); 2.63 +}; 2.64 + 2.65 +invokeMegamorphic(); 2.66 +accessMegamorphic(); 2.67 + 2.68 +Object.prototype.__noSuchMethod__ = "nofunction"; 2.69 + 2.70 +invokeMegamorphic(); 2.71 +accessMegamorphic();
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/script/basic/JDK-8026016.js.EXPECTED Mon Oct 14 11:45:15 2013 +0200 3.3 @@ -0,0 +1,182 @@ 3.4 +no such property _ 3.5 +TypeError: Cannot call undefined 3.6 +no such property _ 3.7 +TypeError: Cannot call undefined 3.8 +no such property _ 3.9 +TypeError: Cannot call undefined 3.10 +no such property _ 3.11 +TypeError: Cannot call undefined 3.12 +no such property _ 3.13 +TypeError: Cannot call undefined 3.14 +no such property _ 3.15 +TypeError: Cannot call undefined 3.16 +no such property _ 3.17 +TypeError: Cannot call undefined 3.18 +no such property _ 3.19 +TypeError: Cannot call undefined 3.20 +no such property _ 3.21 +TypeError: Cannot call undefined 3.22 +no such property _ 3.23 +TypeError: Cannot call undefined 3.24 +no such property _ 3.25 +TypeError: Cannot call undefined 3.26 +no such property _ 3.27 +TypeError: Cannot call undefined 3.28 +no such property _ 3.29 +TypeError: Cannot call undefined 3.30 +no such property _ 3.31 +TypeError: Cannot call undefined 3.32 +no such property _ 3.33 +TypeError: Cannot call undefined 3.34 +no such property _ 3.35 +TypeError: Cannot call undefined 3.36 +no such property _ 3.37 +TypeError: Cannot call undefined 3.38 +no such property _ 3.39 +TypeError: Cannot call undefined 3.40 +no such property _ 3.41 +TypeError: Cannot call undefined 3.42 +no such property _ 3.43 +TypeError: Cannot call undefined 3.44 +no such property _ 3.45 +TypeError: Cannot call undefined 3.46 +no such property _ 3.47 +TypeError: Cannot call undefined 3.48 +no such property _ 3.49 +TypeError: Cannot call undefined 3.50 +no such property _ 3.51 +TypeError: Cannot call undefined 3.52 +no such property _ 3.53 +TypeError: Cannot call undefined 3.54 +no such property _ 3.55 +TypeError: Cannot call undefined 3.56 +no such property _ 3.57 +no such property _ 3.58 +no such property _ 3.59 +no such property _ 3.60 +no such property _ 3.61 +no such property _ 3.62 +no such property _ 3.63 +no such property _ 3.64 +no such property _ 3.65 +no such property _ 3.66 +no such property _ 3.67 +no such property _ 3.68 +no such property _ 3.69 +no such property _ 3.70 +no such property _ 3.71 +no such property _ 3.72 +no such property _ 3.73 +no such property _ 3.74 +no such property _ 3.75 +no such property _ 3.76 +no such property _ 3.77 +no such property _ 3.78 +no such property _ 3.79 +no such property _ 3.80 +no such property _ 3.81 +no such property _ 3.82 +no such method _,0 3.83 +no such method _,1 3.84 +no such method _,2 3.85 +no such method _,3 3.86 +no such method _,4 3.87 +no such method _,5 3.88 +no such method _,6 3.89 +no such method _,7 3.90 +no such method _,8 3.91 +no such method _,9 3.92 +no such method _,10 3.93 +no such method _,11 3.94 +no such method _,12 3.95 +no such method _,13 3.96 +no such method _,14 3.97 +no such method _,15 3.98 +no such method _,16 3.99 +no such method _,17 3.100 +no such method _,18 3.101 +no such method _,19 3.102 +no such method _,20 3.103 +no such method _,21 3.104 +no such method _,22 3.105 +no such method _,23 3.106 +no such method _,24 3.107 +no such method _,25 3.108 +no such property _ 3.109 +no such property _ 3.110 +no such property _ 3.111 +no such property _ 3.112 +no such property _ 3.113 +no such property _ 3.114 +no such property _ 3.115 +no such property _ 3.116 +no such property _ 3.117 +no such property _ 3.118 +no such property _ 3.119 +no such property _ 3.120 +no such property _ 3.121 +no such property _ 3.122 +no such property _ 3.123 +no such property _ 3.124 +no such property _ 3.125 +no such property _ 3.126 +no such property _ 3.127 +no such property _ 3.128 +no such property _ 3.129 +no such property _ 3.130 +no such property _ 3.131 +no such property _ 3.132 +no such property _ 3.133 +no such property _ 3.134 +TypeError: Cannot call undefined 3.135 +TypeError: Cannot call undefined 3.136 +TypeError: Cannot call undefined 3.137 +TypeError: Cannot call undefined 3.138 +TypeError: Cannot call undefined 3.139 +TypeError: Cannot call undefined 3.140 +TypeError: Cannot call undefined 3.141 +TypeError: Cannot call undefined 3.142 +TypeError: Cannot call undefined 3.143 +TypeError: Cannot call undefined 3.144 +TypeError: Cannot call undefined 3.145 +TypeError: Cannot call undefined 3.146 +TypeError: Cannot call undefined 3.147 +TypeError: Cannot call undefined 3.148 +TypeError: Cannot call undefined 3.149 +TypeError: Cannot call undefined 3.150 +TypeError: Cannot call undefined 3.151 +TypeError: Cannot call undefined 3.152 +TypeError: Cannot call undefined 3.153 +TypeError: Cannot call undefined 3.154 +TypeError: Cannot call undefined 3.155 +TypeError: Cannot call undefined 3.156 +TypeError: Cannot call undefined 3.157 +TypeError: Cannot call undefined 3.158 +TypeError: Cannot call undefined 3.159 +TypeError: Cannot call undefined 3.160 +no such property _ 3.161 +no such property _ 3.162 +no such property _ 3.163 +no such property _ 3.164 +no such property _ 3.165 +no such property _ 3.166 +no such property _ 3.167 +no such property _ 3.168 +no such property _ 3.169 +no such property _ 3.170 +no such property _ 3.171 +no such property _ 3.172 +no such property _ 3.173 +no such property _ 3.174 +no such property _ 3.175 +no such property _ 3.176 +no such property _ 3.177 +no such property _ 3.178 +no such property _ 3.179 +no such property _ 3.180 +no such property _ 3.181 +no such property _ 3.182 +no such property _ 3.183 +no such property _ 3.184 +no such property _ 3.185 +no such property _