Source/JavaScriptCore/ChangeLog

 12014-04-14 Andreas Kling <akling@apple.com>
 2
 3 Array.prototype.concat should allocate output storage only once.
 4 <https://webkit.org/b/131609>
 5
 6 Do a first pass across 'this' and any arguments to compute the
 7 final size of the resulting array from Array.prototype.concat.
 8 This avoids having to grow the output incrementally as we go.
 9
 10 This also includes two other micro-optimizations:
 11
 12 - Mark getProperty() with ALWAYS_INLINE.
 13
 14 - Use JSArray::length() instead of taking the generic property
 15 lookup path when we know an argument is an Array.
 16
 17 My MBP says ~3% progression on Dromaeo/jslib-traverse-jquery.
 18
 19 Reviewed by NOBODY (OOPS!).
 20
 21 * runtime/ArrayPrototype.cpp:
 22 (JSC::getProperty):
 23 (JSC::arrayProtoFuncConcat):
 24
1252014-04-14 Commit Queue <commit-queue@webkit.org>
226
327 Unreviewed, rolling out r167249.

Source/JavaScriptCore/runtime/ArrayPrototype.cpp

@@bool ArrayPrototype::getOwnPropertySlot(JSObject* object, ExecState* exec, Prope
146146// ------------------------------ Array Functions ----------------------------
147147
148148// Helper function
149 static JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
 149static ALWAYS_INLINE JSValue getProperty(ExecState* exec, JSObject* obj, unsigned index)
150150{
151151 PropertySlot slot(obj);
152152 if (!obj->getPropertySlot(exec, index, slot))

@@EncodedJSValue JSC_HOST_CALL arrayProtoFuncJoin(ExecState* exec)
416416EncodedJSValue JSC_HOST_CALL arrayProtoFuncConcat(ExecState* exec)
417417{
418418 JSValue thisValue = exec->thisValue().toThis(exec, StrictMode);
419  JSArray* arr = constructEmptyArray(exec, nullptr);
420  unsigned n = 0;
 419 size_t argCount = exec->argumentCount();
421420 JSValue curArg = thisValue.toObject(exec);
 421 unsigned finalArraySize = 0;
 422
 423 for (size_t i = 0;;) {
 424 if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg))
 425 finalArraySize += currentArray->length();
 426 else
 427 finalArraySize++;
 428 if (i == argCount)
 429 break;
 430 curArg = exec->uncheckedArgument(i);
 431 ++i;
 432 }
 433
 434 JSArray* arr = constructEmptyArray(exec, nullptr, finalArraySize);
422435 if (exec->hadException())
423436 return JSValue::encode(jsUndefined());
424  size_t i = 0;
425  size_t argCount = exec->argumentCount();
426  while (1) {
427  if (curArg.inherits(JSArray::info())) {
428  unsigned length = curArg.get(exec, exec->propertyNames().length).toUInt32(exec);
429  JSObject* curObject = curArg.toObject(exec);
 437
 438 curArg = thisValue.toObject(exec);
 439 unsigned n = 0;
 440 for (size_t i = 0;;) {
 441 if (JSArray* currentArray = jsDynamicCast<JSArray*>(curArg)) {
 442 unsigned length = currentArray->length();
430443 for (unsigned k = 0; k < length; ++k) {
431  JSValue v = getProperty(exec, curObject, k);
 444 JSValue v = getProperty(exec, currentArray, k);
432445 if (exec->hadException())
433446 return JSValue::encode(jsUndefined());
434447 if (v)