Changeset 184407 in webkit


Ignore:
Timestamp:
May 15, 2015 1:02:26 PM (9 years ago)
Author:
mark.lam@apple.com
Message:

JSArray::setLength() should reallocate instead of zero-filling if the reallocation would be small enough.
https://bugs.webkit.org/show_bug.cgi?id=144622

Reviewed by Geoffrey Garen.

When setting the array to a new length that is shorter, we now check if it is worth
just making a new butterfly instead of clearing out the slots in the old butterfly
that resides beyond the new length. If so, we will make a new butterfly instead.

There is no perf differences in the benchmark results. However, this does benefit
the perf of pathological cases where we need to shorten the length of a very large
array, as is the case in tests/mozilla/js1_5/Array/regress-101964.js. With this
patch, we can expect that test to complete in a short time again.

  • runtime/JSArray.cpp:

(JSC::JSArray::setLength):

  • runtime/JSObject.cpp:

(JSC::JSObject::reallocateAndShrinkButterfly):

  • makes a new butterfly with a new shorter length.
  • runtime/JSObject.h:
  • tests/mozilla/js1_5/Array/regress-101964.js:
  • Undo this test change since this patch will prevent us from spending a lot of time clearing a large butterfly.
Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r184405 r184407  
     12015-05-15  Mark Lam  <mark.lam@apple.com>
     2
     3        JSArray::setLength() should reallocate instead of zero-filling if the reallocation would be small enough.
     4        https://bugs.webkit.org/show_bug.cgi?id=144622
     5
     6        Reviewed by Geoffrey Garen.
     7
     8        When setting the array to a new length that is shorter, we now check if it is worth
     9        just making a new butterfly instead of clearing out the slots in the old butterfly
     10        that resides beyond the new length.  If so, we will make a new butterfly instead.
     11
     12        There is no perf differences in the benchmark results.  However, this does benefit
     13        the perf of pathological cases where we need to shorten the length of a very large
     14        array, as is the case in tests/mozilla/js1_5/Array/regress-101964.js.  With this
     15        patch, we can expect that test to complete in a short time again.
     16
     17        * runtime/JSArray.cpp:
     18        (JSC::JSArray::setLength):
     19        * runtime/JSObject.cpp:
     20        (JSC::JSObject::reallocateAndShrinkButterfly):
     21        - makes a new butterfly with a new shorter length.
     22        * runtime/JSObject.h:
     23        * tests/mozilla/js1_5/Array/regress-101964.js:
     24        - Undo this test change since this patch will prevent us from spending a lot of time
     25          clearing a large butterfly.
     26
    1272015-05-15  Basile Clement  <basile_clement@apple.com>
    228
  • trunk/Source/JavaScriptCore/runtime/JSArray.cpp

    r184217 r184407  
    405405    case ArrayWithInt32:
    406406    case ArrayWithDouble:
    407     case ArrayWithContiguous:
     407    case ArrayWithContiguous: {
    408408        if (newLength == m_butterfly->publicLength())
    409409            return true;
     
    419419            return true;
    420420        }
     421
     422        unsigned lengthToClear = m_butterfly->publicLength() - newLength;
     423        unsigned costToAllocateNewButterfly = 64; // a heuristic.
     424        if (lengthToClear > newLength && lengthToClear > costToAllocateNewButterfly) {
     425            reallocateAndShrinkButterfly(exec->vm(), newLength);
     426            return true;
     427        }
     428
    421429        if (indexingType() == ArrayWithDouble) {
    422430            for (unsigned i = m_butterfly->publicLength(); i-- > newLength;)
     
    428436        m_butterfly->setPublicLength(newLength);
    429437        return true;
     438    }
    430439       
    431440    case ArrayWithArrayStorage:
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r184324 r184407  
    24582458}
    24592459
     2460void JSObject::reallocateAndShrinkButterfly(VM& vm, unsigned length)
     2461{
     2462    ASSERT(length < MAX_ARRAY_INDEX);
     2463    ASSERT(length < MAX_STORAGE_VECTOR_LENGTH);
     2464    ASSERT(hasContiguous(indexingType()) || hasInt32(indexingType()) || hasDouble(indexingType()) || hasUndecided(indexingType()));
     2465    ASSERT(m_butterfly->vectorLength() > length);
     2466    ASSERT(!m_butterfly->indexingHeader()->preCapacity(structure()));
     2467
     2468    DeferGC deferGC(vm.heap);
     2469    Butterfly* newButterfly = m_butterfly->resizeArray(vm, this, structure(), 0, ArrayStorage::sizeFor(length));
     2470    m_butterfly.set(vm, this, newButterfly);
     2471    m_butterfly->setVectorLength(length);
     2472    m_butterfly->setPublicLength(length);
     2473}
     2474
    24602475Butterfly* JSObject::growOutOfLineStorage(VM& vm, size_t oldSize, size_t newSize)
    24612476{
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r184324 r184407  
    828828    }
    829829       
     830    // Call this if you want to shrink the butterfly backing store, and you're
     831    // sure that the array is contiguous.
     832    void reallocateAndShrinkButterfly(VM&, unsigned length);
     833   
    830834    template<IndexingType indexingShape>
    831835    unsigned countElements(Butterfly*);
  • trunk/Source/JavaScriptCore/tests/mozilla/js1_5/Array/regress-101964.js

    r183793 r184407  
    3232var BIG = 10000000;
    3333var LITTLE = 10;
    34 var FAST = 10000; // This used to test that array truncation should be 50 ms or less. We've changed it because we don't care how long it takes. We just try to make sure it doesn't take *ridiculously* long and we want it to run to completion correctly.
     34var FAST = 50; // array truncation should be 50 ms or less to pass the test
    3535var MSG_FAST = 'Truncation took less than ' + FAST + ' ms';
    3636var MSG_SLOW = 'Truncation took ';
Note: See TracChangeset for help on using the changeset viewer.