Fri, 26 Apr 2013 09:48:41 -0300
8013208: Octane performance regression
Reviewed-by: hannesw, sundar
Contributed-by: james.laskey@oracle.com
1.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Apr 26 09:20:37 2013 +0200 1.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Apr 26 09:48:41 2013 -0300 1.3 @@ -2265,17 +2265,29 @@ 1.4 } 1.5 1.6 private int getInt(final int index, final String key) { 1.7 - for (ScriptObject object = this; object != null; object = object.getProto()) { 1.8 - final ArrayData array = object.getArray(); 1.9 - 1.10 - if (array.has(index)) { 1.11 - return array.getInt(index); 1.12 - } 1.13 - 1.14 - final FindProperty find = object.findProperty(key, false); 1.15 + if (isValidArrayIndex(index)) { 1.16 + for (ScriptObject object = this; ; ) { 1.17 + final FindProperty find = object.findProperty(key, false, false, this); 1.18 + 1.19 + if (find != null) { 1.20 + return getIntValue(find); 1.21 + } 1.22 + 1.23 + if ((object = object.getProto()) == null) { 1.24 + break; 1.25 + } 1.26 + 1.27 + final ArrayData array = object.getArray(); 1.28 + 1.29 + if (array.has(index)) { 1.30 + return array.getInt(index); 1.31 + } 1.32 + } 1.33 + } else { 1.34 + final FindProperty find = findProperty(key, true); 1.35 1.36 if (find != null) { 1.37 - return getIntValue(new FindProperty(this, find.getOwner(), find.getProperty())); 1.38 + return getIntValue(find); 1.39 } 1.40 } 1.41 1.42 @@ -2284,36 +2296,75 @@ 1.43 1.44 @Override 1.45 public int getInt(final Object key) { 1.46 - return getInt(getArrayIndexNoThrow(key), convertKey(key)); 1.47 + final int index = getArrayIndexNoThrow(key); 1.48 + final ArrayData array = getArray(); 1.49 + 1.50 + if (array.has(index)) { 1.51 + return array.getInt(index); 1.52 + } 1.53 + 1.54 + return getInt(index, convertKey(key)); 1.55 } 1.56 1.57 @Override 1.58 public int getInt(final double key) { 1.59 - return getInt(getArrayIndexNoThrow(key), convertKey(key)); 1.60 + final int index = getArrayIndexNoThrow(key); 1.61 + final ArrayData array = getArray(); 1.62 + 1.63 + if (array.has(index)) { 1.64 + return array.getInt(index); 1.65 + } 1.66 + 1.67 + return getInt(index, convertKey(key)); 1.68 } 1.69 1.70 @Override 1.71 public int getInt(final long key) { 1.72 - return getInt(getArrayIndexNoThrow(key), convertKey(key)); 1.73 + final int index = getArrayIndexNoThrow(key); 1.74 + final ArrayData array = getArray(); 1.75 + 1.76 + if (array.has(index)) { 1.77 + return array.getInt(index); 1.78 + } 1.79 + 1.80 + return getInt(index, convertKey(key)); 1.81 } 1.82 1.83 @Override 1.84 public int getInt(final int key) { 1.85 - return getInt(getArrayIndexNoThrow(key), convertKey(key)); 1.86 + final ArrayData array = getArray(); 1.87 + 1.88 + if (array.has(key)) { 1.89 + return array.getInt(key); 1.90 + } 1.91 + 1.92 + return getInt(key, convertKey(key)); 1.93 } 1.94 1.95 private long getLong(final int index, final String key) { 1.96 - for (ScriptObject object = this; object != null; object = object.getProto()) { 1.97 - final ArrayData array = object.getArray(); 1.98 - 1.99 - if (array.has(index)) { 1.100 - return array.getLong(index); 1.101 - } 1.102 - 1.103 - final FindProperty find = object.findProperty(key, false); 1.104 + if (isValidArrayIndex(index)) { 1.105 + for (ScriptObject object = this; ; ) { 1.106 + final FindProperty find = object.findProperty(key, false, false, this); 1.107 + 1.108 + if (find != null) { 1.109 + return getLongValue(find); 1.110 + } 1.111 + 1.112 + if ((object = object.getProto()) == null) { 1.113 + break; 1.114 + } 1.115 + 1.116 + final ArrayData array = object.getArray(); 1.117 + 1.118 + if (array.has(index)) { 1.119 + return array.getLong(index); 1.120 + } 1.121 + } 1.122 + } else { 1.123 + final FindProperty find = findProperty(key, true); 1.124 1.125 if (find != null) { 1.126 - return getLongValue(new FindProperty(this, find.getOwner(), find.getProperty())); 1.127 + return getLongValue(find); 1.128 } 1.129 } 1.130 1.131 @@ -2322,36 +2373,75 @@ 1.132 1.133 @Override 1.134 public long getLong(final Object key) { 1.135 - return getLong(getArrayIndexNoThrow(key), convertKey(key)); 1.136 + final int index = getArrayIndexNoThrow(key); 1.137 + final ArrayData array = getArray(); 1.138 + 1.139 + if (array.has(index)) { 1.140 + return array.getLong(index); 1.141 + } 1.142 + 1.143 + return getLong(index, convertKey(key)); 1.144 } 1.145 1.146 @Override 1.147 public long getLong(final double key) { 1.148 - return getLong(getArrayIndexNoThrow(key), convertKey(key)); 1.149 + final int index = getArrayIndexNoThrow(key); 1.150 + final ArrayData array = getArray(); 1.151 + 1.152 + if (array.has(index)) { 1.153 + return array.getLong(index); 1.154 + } 1.155 + 1.156 + return getLong(index, convertKey(key)); 1.157 } 1.158 1.159 @Override 1.160 public long getLong(final long key) { 1.161 - return getLong(getArrayIndexNoThrow(key), convertKey(key)); 1.162 + final int index = getArrayIndexNoThrow(key); 1.163 + final ArrayData array = getArray(); 1.164 + 1.165 + if (array.has(index)) { 1.166 + return array.getLong(index); 1.167 + } 1.168 + 1.169 + return getLong(index, convertKey(key)); 1.170 } 1.171 1.172 @Override 1.173 public long getLong(final int key) { 1.174 - return getLong(getArrayIndexNoThrow(key), convertKey(key)); 1.175 + final ArrayData array = getArray(); 1.176 + 1.177 + if (array.has(key)) { 1.178 + return array.getLong(key); 1.179 + } 1.180 + 1.181 + return getLong(key, convertKey(key)); 1.182 } 1.183 1.184 private double getDouble(final int index, final String key) { 1.185 - for (ScriptObject object = this; object != null; object = object.getProto()) { 1.186 - final ArrayData array = object.getArray(); 1.187 - 1.188 - if (array.has(index)) { 1.189 - return array.getDouble(index); 1.190 - } 1.191 - 1.192 - final FindProperty find = object.findProperty(key, false); 1.193 + if (isValidArrayIndex(index)) { 1.194 + for (ScriptObject object = this; ; ) { 1.195 + final FindProperty find = object.findProperty(key, false, false, this); 1.196 + 1.197 + if (find != null) { 1.198 + return getDoubleValue(find); 1.199 + } 1.200 + 1.201 + if ((object = object.getProto()) == null) { 1.202 + break; 1.203 + } 1.204 + 1.205 + final ArrayData array = object.getArray(); 1.206 + 1.207 + if (array.has(index)) { 1.208 + return array.getDouble(index); 1.209 + } 1.210 + } 1.211 + } else { 1.212 + final FindProperty find = findProperty(key, true); 1.213 1.214 if (find != null) { 1.215 - return getDoubleValue(new FindProperty(this, find.getOwner(), find.getProperty())); 1.216 + return getDoubleValue(find); 1.217 } 1.218 } 1.219 1.220 @@ -2360,36 +2450,75 @@ 1.221 1.222 @Override 1.223 public double getDouble(final Object key) { 1.224 - return getDouble(getArrayIndexNoThrow(key), convertKey(key)); 1.225 + final int index = getArrayIndexNoThrow(key); 1.226 + final ArrayData array = getArray(); 1.227 + 1.228 + if (array.has(index)) { 1.229 + return array.getDouble(index); 1.230 + } 1.231 + 1.232 + return getDouble(index, convertKey(key)); 1.233 } 1.234 1.235 @Override 1.236 public double getDouble(final double key) { 1.237 - return getDouble(getArrayIndexNoThrow(key), convertKey(key)); 1.238 + final int index = getArrayIndexNoThrow(key); 1.239 + final ArrayData array = getArray(); 1.240 + 1.241 + if (array.has(index)) { 1.242 + return array.getDouble(index); 1.243 + } 1.244 + 1.245 + return getDouble(index, convertKey(key)); 1.246 } 1.247 1.248 @Override 1.249 public double getDouble(final long key) { 1.250 - return getDouble(getArrayIndexNoThrow(key), convertKey(key)); 1.251 + final int index = getArrayIndexNoThrow(key); 1.252 + final ArrayData array = getArray(); 1.253 + 1.254 + if (array.has(index)) { 1.255 + return array.getDouble(index); 1.256 + } 1.257 + 1.258 + return getDouble(index, convertKey(key)); 1.259 } 1.260 1.261 @Override 1.262 public double getDouble(final int key) { 1.263 - return getDouble(getArrayIndexNoThrow(key), convertKey(key)); 1.264 + final ArrayData array = getArray(); 1.265 + 1.266 + if (array.has(key)) { 1.267 + return array.getDouble(key); 1.268 + } 1.269 + 1.270 + return getDouble(key, convertKey(key)); 1.271 } 1.272 1.273 private Object get(final int index, final String key) { 1.274 - for (ScriptObject object = this; object != null; object = object.getProto()) { 1.275 - final ArrayData array = object.getArray(); 1.276 - 1.277 - if (array.has(index)) { 1.278 - return array.getObject(index); 1.279 + if (isValidArrayIndex(index)) { 1.280 + for (ScriptObject object = this; ; ) { 1.281 + final FindProperty find = object.findProperty(key, false, false, this); 1.282 + 1.283 + if (find != null) { 1.284 + return getObjectValue(find); 1.285 + } 1.286 + 1.287 + if ((object = object.getProto()) == null) { 1.288 + break; 1.289 + } 1.290 + 1.291 + final ArrayData array = object.getArray(); 1.292 + 1.293 + if (array.has(index)) { 1.294 + return array.getObject(index); 1.295 + } 1.296 } 1.297 - 1.298 - final FindProperty find = object.findProperty(key, false); 1.299 + } else { 1.300 + final FindProperty find = findProperty(key, true); 1.301 1.302 if (find != null) { 1.303 - return getObjectValue(new FindProperty(this, find.getOwner(), find.getProperty())); 1.304 + return getObjectValue(find); 1.305 } 1.306 } 1.307 1.308 @@ -2398,22 +2527,49 @@ 1.309 1.310 @Override 1.311 public Object get(final Object key) { 1.312 - return get(getArrayIndexNoThrow(key), convertKey(key)); 1.313 + final int index = getArrayIndexNoThrow(key); 1.314 + final ArrayData array = getArray(); 1.315 + 1.316 + if (array.has(index)) { 1.317 + return array.getObject(index); 1.318 + } 1.319 + 1.320 + return get(index, convertKey(key)); 1.321 } 1.322 1.323 @Override 1.324 public Object get(final double key) { 1.325 - return get(getArrayIndexNoThrow(key), convertKey(key)); 1.326 + final int index = getArrayIndexNoThrow(key); 1.327 + final ArrayData array = getArray(); 1.328 + 1.329 + if (array.has(index)) { 1.330 + return array.getObject(index); 1.331 + } 1.332 + 1.333 + return get(index, convertKey(key)); 1.334 } 1.335 1.336 @Override 1.337 public Object get(final long key) { 1.338 - return get(getArrayIndexNoThrow(key), convertKey(key)); 1.339 + final int index = getArrayIndexNoThrow(key); 1.340 + final ArrayData array = getArray(); 1.341 + 1.342 + if (array.has(index)) { 1.343 + return array.getObject(index); 1.344 + } 1.345 + 1.346 + return get(index, convertKey(key)); 1.347 } 1.348 1.349 @Override 1.350 public Object get(final int key) { 1.351 - return get(getArrayIndexNoThrow(key), convertKey(key)); 1.352 + final ArrayData array = getArray(); 1.353 + 1.354 + if (array.has(key)) { 1.355 + return array.getObject(key); 1.356 + } 1.357 + 1.358 + return get(key, convertKey(key)); 1.359 } 1.360 1.361 /**
2.1 --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java Fri Apr 26 09:20:37 2013 +0200 2.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayIndex.java Fri Apr 26 09:48:41 2013 -0300 2.3 @@ -84,7 +84,9 @@ 2.4 * @return valid array index, or negative value if not valid 2.5 */ 2.6 public static int getArrayIndexNoThrow(final Object key) { 2.7 - if (key instanceof Number) { 2.8 + if (key instanceof Integer) { 2.9 + return getArrayIndexNoThrow(((Integer)key).intValue()); 2.10 + } else if (key instanceof Number) { 2.11 return getArrayIndexNoThrow(((Number)key).doubleValue()); 2.12 } else if (key instanceof String) { 2.13 return (int)fromString((String)key);