Changeset 251399 in webkit


Ignore:
Timestamp:
Oct 21, 2019 5:04:27 PM (4 years ago)
Author:
mark.lam@apple.com
Message:

Fix issues when setting public length on ArrayWithContiguous type butterflies.
https://bugs.webkit.org/show_bug.cgi?id=203211
<rdar://problem/56476097>

Reviewed by Keith Miller and Saam Barati.

For ArrayWithContiguous type butterflies, SlotVisitor scans up to the public
length of the butterfly. When setting a new public length, if the new public
length is greater than the current, we should always writeBarrier after the
setting of the new public length. Otherwise, there can be a race where the GC
scans the butterfly after new values have been written to it but before the
public length as been updated. As a result, the new values never get scanned.

For the DFG and FTL, the StoreBarrierInsertionPhase is responsible for inserting
the writeBarriers after the node. Hence, the writeBarrier is guaranteed to be
after the publicLength has been updated.

  • runtime/JSArray.cpp:

(JSC::JSArray::shiftCountWithArrayStorage):
(JSC::JSArray::shiftCountWithAnyIndexingType):

  • runtime/JSArrayInlines.h:

(JSC::JSArray::pushInline):

  • runtime/JSObject.cpp:

(JSC::JSObject::putByIndex):
(JSC::JSObject::reallocateAndShrinkButterfly):

  • runtime/JSObject.h:

(JSC::JSObject::setIndexQuickly):

Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r251395 r251399  
     12019-10-21  Mark Lam  <mark.lam@apple.com>
     2
     3        Fix issues when setting public length on ArrayWithContiguous type butterflies.
     4        https://bugs.webkit.org/show_bug.cgi?id=203211
     5        <rdar://problem/56476097>
     6
     7        Reviewed by Keith Miller and Saam Barati.
     8
     9        For ArrayWithContiguous type butterflies, SlotVisitor scans up to the public
     10        length of the butterfly.  When setting a new public length, if the new public
     11        length is greater than the current, we should always writeBarrier after the
     12        setting of the new public length.  Otherwise, there can be a race where the GC
     13        scans the butterfly after new values have been written to it but before the
     14        public length as been updated.  As a result, the new values never get scanned.
     15
     16        For the DFG and FTL, the StoreBarrierInsertionPhase is responsible for inserting
     17        the writeBarriers after the node.  Hence, the writeBarrier is guaranteed to be
     18        after the publicLength has been updated.
     19
     20        * runtime/JSArray.cpp:
     21        (JSC::JSArray::shiftCountWithArrayStorage):
     22        (JSC::JSArray::shiftCountWithAnyIndexingType):
     23        * runtime/JSArrayInlines.h:
     24        (JSC::JSArray::pushInline):
     25        * runtime/JSObject.cpp:
     26        (JSC::JSObject::putByIndex):
     27        (JSC::JSObject::reallocateAndShrinkButterfly):
     28        * runtime/JSObject.h:
     29        (JSC::JSObject::setIndexQuickly):
     30
    1312019-10-21  Devin Rousso  <drousso@apple.com>
    232
  • trunk/Source/JavaScriptCore/runtime/JSArray.cpp

    r250005 r251399  
    895895    Butterfly* butterfly = this->butterfly();
    896896   
    897     switch (indexingType()) {
     897    auto indexingType = this->indexingType();
     898    switch (indexingType) {
    898899    case ArrayClass:
    899900        return true;
     
    935936        for (unsigned i = end; i < oldLength; ++i)
    936937            butterfly->contiguous().at(this, i).clear();
    937        
     938
    938939        butterfly->setPublicLength(oldLength - count);
    939940
    940941        // Our memmoving of values around in the array could have concealed some of them from
    941942        // the collector. Let's make sure that the collector scans this object again.
    942         vm.heap.writeBarrier(this);
    943        
     943        if (indexingType == ArrayWithContiguous)
     944            vm.heap.writeBarrier(this);
     945
    944946        return true;
    945947    }
  • trunk/Source/JavaScriptCore/runtime/JSArrayInlines.h

    r246040 r251399  
    158158        ASSERT(length <= butterfly->vectorLength());
    159159        if (length < butterfly->vectorLength()) {
    160             butterfly->contiguous().at(this, length).set(vm, this, value);
     160            butterfly->contiguous().at(this, length).setWithoutWriteBarrier(value);
    161161            butterfly->setPublicLength(length + 1);
     162            vm.heap.writeBarrier(this, value);
    162163            return;
    163164        }
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r251274 r251399  
    892892        if (propertyName >= butterfly->vectorLength())
    893893            break;
    894         butterfly->contiguous().at(thisObject, propertyName).set(vm, thisObject, value);
     894        butterfly->contiguous().at(thisObject, propertyName).setWithoutWriteBarrier(value);
    895895        if (propertyName >= butterfly->publicLength())
    896896            butterfly->setPublicLength(propertyName + 1);
     897        vm.heap.writeBarrier(thisObject, value);
    897898        return true;
    898899    }
     
    34303431    ASSERT(hasContiguous(indexingType()) || hasInt32(indexingType()) || hasDouble(indexingType()) || hasUndecided(indexingType()));
    34313432    ASSERT(m_butterfly->vectorLength() > length);
     3433    ASSERT(m_butterfly->publicLength() >= length);
    34323434    ASSERT(!m_butterfly->indexingHeader()->preCapacity(structure(vm)));
    34333435
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r250803 r251399  
    410410        case ALL_CONTIGUOUS_INDEXING_TYPES: {
    411411            ASSERT(i < butterfly->vectorLength());
    412             butterfly->contiguous().at(this, i).set(vm, this, v);
     412            butterfly->contiguous().at(this, i).setWithoutWriteBarrier(v);
    413413            if (i >= butterfly->publicLength())
    414414                butterfly->setPublicLength(i + 1);
     415            vm.heap.writeBarrier(this, v);
    415416            break;
    416417        }
Note: See TracChangeset for help on using the changeset viewer.