8026016: too many relinks dominate avatar.js http benchmark

Mon, 14 Oct 2013 11:45:15 +0200

author
hannesw
date
Mon, 14 Oct 2013 11:45:15 +0200
changeset 620
8c617a092d68
parent 619
6cb4f20d971f
child 621
d155c4a7703c

8026016: too many relinks dominate avatar.js http benchmark
Reviewed-by: sundar, jlaskey, attila

src/jdk/nashorn/internal/runtime/ScriptObject.java file | annotate | diff | comparison | revisions
test/script/basic/JDK-8026016.js file | annotate | diff | comparison | revisions
test/script/basic/JDK-8026016.js.EXPECTED file | annotate | diff | comparison | revisions
     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 _

mercurial