Changeset 161230 in webkit


Ignore:
Timestamp:
Jan 2, 2014 2:57:14 PM (10 years ago)
Author:
mhahnenberg@apple.com
Message:

Storing new CopiedSpace memory into a JSObject should fire a write barrier
https://bugs.webkit.org/show_bug.cgi?id=126025

Reviewed by Filip Pizlo.

Technically this is creating a pointer between a (potentially) old generation object and a young
generation chunk of memory, thus there needs to be a barrier.

  • JavaScriptCore.xcodeproj/project.pbxproj:
  • dfg/DFGOperations.cpp:
  • heap/CopyWriteBarrier.h: Added. This class functions similarly to the WriteBarrier class. It

acts as a proxy for pointers to CopiedSpace. Assignments to the field cause a write barrier to
fire for the object that is the owner of the CopiedSpace memory. This is to ensure during nursery
collections that objects with new backing stores are visited, even if they are old generation objects.
(JSC::CopyWriteBarrier::CopyWriteBarrier):
(JSC::CopyWriteBarrier::operator!):
(JSC::CopyWriteBarrier::operator UnspecifiedBoolType*):
(JSC::CopyWriteBarrier::get):
(JSC::CopyWriteBarrier::operator*):
(JSC::CopyWriteBarrier::operator->):
(JSC::CopyWriteBarrier::set):
(JSC::CopyWriteBarrier::setWithoutWriteBarrier):
(JSC::CopyWriteBarrier::clear):

  • heap/Heap.h:
  • runtime/JSArray.cpp:

(JSC::JSArray::unshiftCountSlowCase):
(JSC::JSArray::shiftCountWithArrayStorage):
(JSC::JSArray::unshiftCountWithArrayStorage):

  • runtime/JSCell.h:

(JSC::JSCell::unvalidatedStructure):

  • runtime/JSGenericTypedArrayViewInlines.h:

(JSC::JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory):

  • runtime/JSObject.cpp:

(JSC::JSObject::copyButterfly):
(JSC::JSObject::getOwnPropertySlotByIndex):
(JSC::JSObject::putByIndex):
(JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
(JSC::JSObject::createInitialIndexedStorage):
(JSC::JSObject::createArrayStorage):
(JSC::JSObject::deletePropertyByIndex):
(JSC::JSObject::getOwnPropertyNames):
(JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
(JSC::JSObject::countElements):
(JSC::JSObject::increaseVectorLength):
(JSC::JSObject::ensureLengthSlow):

  • runtime/JSObject.h:

(JSC::JSObject::butterfly):
(JSC::JSObject::setStructureAndButterfly):
(JSC::JSObject::setButterflyWithoutChangingStructure):
(JSC::JSObject::JSObject):
(JSC::JSObject::putDirectInternal):
(JSC::JSObject::putDirectWithoutTransition):

  • runtime/MapData.cpp:

(JSC::MapData::ensureSpaceForAppend):

  • runtime/Structure.cpp:

(JSC::Structure::materializePropertyMap):

Location:
trunk/Source/JavaScriptCore
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r161220 r161230  
     12014-01-02  Mark Hahnenberg  <mhahnenberg@apple.com>
     2
     3        Storing new CopiedSpace memory into a JSObject should fire a write barrier
     4        https://bugs.webkit.org/show_bug.cgi?id=126025
     5
     6        Reviewed by Filip Pizlo.
     7
     8        Technically this is creating a pointer between a (potentially) old generation object and a young
     9        generation chunk of memory, thus there needs to be a barrier.
     10
     11        * JavaScriptCore.xcodeproj/project.pbxproj:
     12        * dfg/DFGOperations.cpp:
     13        * heap/CopyWriteBarrier.h: Added. This class functions similarly to the WriteBarrier class. It
     14        acts as a proxy for pointers to CopiedSpace. Assignments to the field cause a write barrier to
     15        fire for the object that is the owner of the CopiedSpace memory. This is to ensure during nursery
     16        collections that objects with new backing stores are visited, even if they are old generation objects.
     17        (JSC::CopyWriteBarrier::CopyWriteBarrier):
     18        (JSC::CopyWriteBarrier::operator!):
     19        (JSC::CopyWriteBarrier::operator UnspecifiedBoolType*):
     20        (JSC::CopyWriteBarrier::get):
     21        (JSC::CopyWriteBarrier::operator*):
     22        (JSC::CopyWriteBarrier::operator->):
     23        (JSC::CopyWriteBarrier::set):
     24        (JSC::CopyWriteBarrier::setWithoutWriteBarrier):
     25        (JSC::CopyWriteBarrier::clear):
     26        * heap/Heap.h:
     27        * runtime/JSArray.cpp:
     28        (JSC::JSArray::unshiftCountSlowCase):
     29        (JSC::JSArray::shiftCountWithArrayStorage):
     30        (JSC::JSArray::unshiftCountWithArrayStorage):
     31        * runtime/JSCell.h:
     32        (JSC::JSCell::unvalidatedStructure):
     33        * runtime/JSGenericTypedArrayViewInlines.h:
     34        (JSC::JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory):
     35        * runtime/JSObject.cpp:
     36        (JSC::JSObject::copyButterfly):
     37        (JSC::JSObject::getOwnPropertySlotByIndex):
     38        (JSC::JSObject::putByIndex):
     39        (JSC::JSObject::enterDictionaryIndexingModeWhenArrayStorageAlreadyExists):
     40        (JSC::JSObject::createInitialIndexedStorage):
     41        (JSC::JSObject::createArrayStorage):
     42        (JSC::JSObject::deletePropertyByIndex):
     43        (JSC::JSObject::getOwnPropertyNames):
     44        (JSC::JSObject::putByIndexBeyondVectorLengthWithoutAttributes):
     45        (JSC::JSObject::countElements):
     46        (JSC::JSObject::increaseVectorLength):
     47        (JSC::JSObject::ensureLengthSlow):
     48        * runtime/JSObject.h:
     49        (JSC::JSObject::butterfly):
     50        (JSC::JSObject::setStructureAndButterfly):
     51        (JSC::JSObject::setButterflyWithoutChangingStructure):
     52        (JSC::JSObject::JSObject):
     53        (JSC::JSObject::putDirectInternal):
     54        (JSC::JSObject::putDirectWithoutTransition):
     55        * runtime/MapData.cpp:
     56        (JSC::MapData::ensureSpaceForAppend):
     57        * runtime/Structure.cpp:
     58        (JSC::Structure::materializePropertyMap):
     59
    1602013-12-23  Oliver Hunt  <oliver@apple.com>
    261
  • trunk/Source/JavaScriptCore/GNUmakefile.list.am

    r160796 r161230  
    503503        Source/JavaScriptCore/heap/CopyVisitor.cpp \
    504504        Source/JavaScriptCore/heap/CopyWorkList.h \
     505        Source/JavaScriptCore/heap/CopyWriteBarrier.h \
    505506        Source/JavaScriptCore/heap/ConservativeRoots.cpp \
    506507        Source/JavaScriptCore/heap/ConservativeRoots.h \
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj

    r160796 r161230  
    985985    <ClInclude Include="..\heap\CopyVisitorInlines.h" />
    986986    <ClInclude Include="..\heap\CopyWorkList.h" />
     987    <ClInclude Include="..\heap\CopyWriteBarrier.h" />
    987988    <ClInclude Include="..\heap\DeferGC.h" />
    988989    <ClInclude Include="..\heap\DelayedReleaseScope.h" />
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters

    r160796 r161230  
    16291629      <Filter>heap</Filter>
    16301630    </ClInclude>
     1631    <ClInclude Include="..\heap\CopyWriteBarrier.h">
     1632      <Filter>heap</Filter>
     1633    </ClInclude>
    16311634    <ClInclude Include="..\heap\DeferGC.h">
    16321635      <Filter>heap</Filter>
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r160796 r161230  
    721721                2A4EC90B1860D6C20094F782 /* WriteBarrierBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */; };
    722722                2A4EC90C1860D6C20094F782 /* WriteBarrierBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A4EC90A1860D6C20094F782 /* WriteBarrierBuffer.h */; settings = {ATTRIBUTES = (Private, ); }; };
     723                2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */; settings = {ATTRIBUTES = (Private, ); }; };
    723724                2A6F462617E959CE00C45C98 /* HeapOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 2A6F462517E959CE00C45C98 /* HeapOperation.h */; settings = {ATTRIBUTES = (Private, ); }; };
    724725                2A7A58EF1808A4C40020BDF7 /* DeferGC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */; };
     
    20282029                2A4EC9091860D6C20094F782 /* WriteBarrierBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WriteBarrierBuffer.cpp; sourceTree = "<group>"; };
    20292030                2A4EC90A1860D6C20094F782 /* WriteBarrierBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WriteBarrierBuffer.h; sourceTree = "<group>"; };
     2031                2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CopyWriteBarrier.h; sourceTree = "<group>"; };
    20302032                2A6F462517E959CE00C45C98 /* HeapOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapOperation.h; sourceTree = "<group>"; };
    20312033                2A7A58EE1808A4C40020BDF7 /* DeferGC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DeferGC.cpp; sourceTree = "<group>"; };
     
    32133215                                2A2825CF18341F2D0087FBA9 /* DelayedReleaseScope.h */,
    32143216                                2AAD964918569417001F93BE /* RecursiveAllocationScope.h */,
     3217                                2A68295A1875F80500B6C3E2 /* CopyWriteBarrier.h */,
    32153218                        );
    32163219                        path = heap;
     
    43744377                                86ADD1450FDDEA980006EEC2 /* ARMv7Assembler.h in Headers */,
    43754378                                65C0285D1717966800351E35 /* ARMv7DOpcode.h in Headers */,
     4379                                2A68295B1875F80500B6C3E2 /* CopyWriteBarrier.h in Headers */,
    43764380                                2A4EC90C1860D6C20094F782 /* WriteBarrierBuffer.h in Headers */,
    43774381                                A532439218569709002ED692 /* CodeGeneratorInspector.py in Headers */,
  • trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp

    r161220 r161230  
    852852    ASSERT(!object->structure()->outOfLineCapacity());
    853853    Butterfly* result = object->growOutOfLineStorage(vm, 0, initialOutOfLineCapacity);
    854     object->setButterflyWithoutChangingStructure(result);
     854    object->setButterflyWithoutChangingStructure(vm, result);
    855855    return reinterpret_cast<char*>(result);
    856856}
     
    862862
    863863    Butterfly* result = object->growOutOfLineStorage(vm, object->structure()->outOfLineCapacity(), newSize);
    864     object->setButterflyWithoutChangingStructure(result);
     864    object->setButterflyWithoutChangingStructure(vm, result);
    865865    return reinterpret_cast<char*>(result);
    866866}
  • trunk/Source/JavaScriptCore/runtime/JSArray.cpp

    r160186 r161230  
    322322    newButterfly->arrayStorage()->setVectorLength(newVectorLength);
    323323    newButterfly->arrayStorage()->m_indexBias = newIndexBias;
    324 
    325     m_butterfly = newButterfly;
     324    setButterflyWithoutChangingStructure(vm, newButterfly);
    326325
    327326    return true;
     
    721720        // the start of the Butterfly, which needs to point at the first indexed property in the used
    722721        // portion of the vector.
    723         m_butterfly = m_butterfly->shift(structure(), count);
     722        m_butterfly.setWithoutWriteBarrier(m_butterfly->shift(structure(), count));
    724723        storage = m_butterfly->arrayStorage();
    725724        storage->m_indexBias += count;
     
    858857
    859858    if (moveFront && storage->m_indexBias >= count) {
    860         m_butterfly = storage->butterfly()->unshift(structure(), count);
    861         storage = m_butterfly->arrayStorage();
     859        Butterfly* newButterfly = storage->butterfly()->unshift(structure(), count);
     860        storage = newButterfly->arrayStorage();
    862861        storage->m_indexBias -= count;
    863862        storage->setVectorLength(vectorLength + count);
     863        setButterflyWithoutChangingStructure(exec->vm(), newButterfly);
    864864    } else if (!moveFront && vectorLength - length >= count)
    865865        storage = storage->butterfly()->arrayStorage();
  • trunk/Source/JavaScriptCore/runtime/JSCell.h

    r155357 r161230  
    147147       
    148148#if ENABLE(GC_VALIDATION)
    149     Structure* unvalidatedStructure() { return m_structure.unvalidatedGet(); }
     149    Structure* unvalidatedStructure() const { return m_structure.unvalidatedGet(); }
    150150#endif
    151151       
  • trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h

    r161220 r161230  
    507507   
    508508    if (thisObject->m_mode == FastTypedArray
    509         && !thisObject->m_butterfly && size >= sizeof(IndexingHeader)) {
     509        && !thisObject->butterfly() && size >= sizeof(IndexingHeader)) {
    510510        ASSERT(thisObject->m_vector);
    511511        // Reuse already allocated memory if at all possible.
    512         thisObject->m_butterfly =
    513             static_cast<IndexingHeader*>(thisObject->m_vector)->butterfly();
     512        thisObject->m_butterfly.setWithoutWriteBarrier(
     513            static_cast<IndexingHeader*>(thisObject->m_vector)->butterfly());
    514514    } else {
    515         thisObject->m_butterfly = Butterfly::createOrGrowArrayRight(
    516             thisObject->m_butterfly, *heap->vm(), thisObject, thisObject->structure(),
    517             thisObject->structure()->outOfLineCapacity(), false, 0, 0);
     515        VM& vm = *heap->vm();
     516        thisObject->m_butterfly.set(vm, thisObject, Butterfly::createOrGrowArrayRight(
     517            thisObject->butterfly(), vm, thisObject, thisObject->structure(),
     518            thisObject->structure()->outOfLineCapacity(), false, 0, 0));
    518519    }
    519520
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r161220 r161230  
    160160        }
    161161       
    162         m_butterfly = newButterfly;
     162        m_butterfly.setWithoutWriteBarrier(newButterfly);
    163163        visitor.didCopy(butterfly->base(preCapacity, propertyCapacity), capacityInBytes);
    164164    }
     
    284284    case ALL_INT32_INDEXING_TYPES:
    285285    case ALL_CONTIGUOUS_INDEXING_TYPES: {
    286         Butterfly* butterfly = thisObject->m_butterfly;
     286        Butterfly* butterfly = thisObject->butterfly();
    287287        if (i >= butterfly->vectorLength())
    288288            return false;
     
    298298       
    299299    case ALL_DOUBLE_INDEXING_TYPES: {
    300         Butterfly* butterfly = thisObject->m_butterfly;
     300        Butterfly* butterfly = thisObject->butterfly();
    301301        if (i >= butterfly->vectorLength())
    302302            return false;
     
    438438       
    439439    case ALL_CONTIGUOUS_INDEXING_TYPES: {
    440         Butterfly* butterfly = thisObject->m_butterfly;
     440        Butterfly* butterfly = thisObject->butterfly();
    441441        if (propertyName >= butterfly->vectorLength())
    442442            break;
     
    461461            return;
    462462        }
    463         Butterfly* butterfly = thisObject->m_butterfly;
     463        Butterfly* butterfly = thisObject->butterfly();
    464464        if (propertyName >= butterfly->vectorLength())
    465465            break;
     
    550550    Butterfly* newButterfly = storage->butterfly()->resizeArray(vm, this, structure(), 0, ArrayStorage::sizeFor(0));
    551551    RELEASE_ASSERT(newButterfly);
    552    
    553     m_butterfly = newButterfly;
    554552    newButterfly->arrayStorage()->m_indexBias = 0;
    555553    newButterfly->arrayStorage()->setVectorLength(0);
    556554    newButterfly->arrayStorage()->m_sparseMap.set(vm, this, map);
     555    setButterflyWithoutChangingStructure(vm, newButterfly);
    557556   
    558557    return newButterfly->arrayStorage();
     
    602601    unsigned vectorLength = std::max(length, BASE_VECTOR_LEN);
    603602    Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(
    604         m_butterfly, vm, this, structure(), structure()->outOfLineCapacity(), false, 0,
     603        m_butterfly.get(), vm, this, structure(), structure()->outOfLineCapacity(), false, 0,
    605604        elementSize * vectorLength);
    606605    newButterfly->setPublicLength(length);
     
    653652    ASSERT_UNUSED(oldType, !hasIndexedProperties(oldType));
    654653    Butterfly* newButterfly = Butterfly::createOrGrowArrayRight(
    655         m_butterfly, vm, this, structure(), structure()->outOfLineCapacity(), false, 0,
     654        m_butterfly.get(), vm, this, structure(), structure()->outOfLineCapacity(), false, 0,
    656655        ArrayStorage::sizeFor(vectorLength));
    657656    RELEASE_ASSERT(newButterfly);
     
    12971296    case ALL_INT32_INDEXING_TYPES:
    12981297    case ALL_CONTIGUOUS_INDEXING_TYPES: {
    1299         Butterfly* butterfly = thisObject->m_butterfly;
     1298        Butterfly* butterfly = thisObject->butterfly();
    13001299        if (i >= butterfly->vectorLength())
    13011300            return true;
     
    13051304       
    13061305    case ALL_DOUBLE_INDEXING_TYPES: {
    1307         Butterfly* butterfly = thisObject->m_butterfly;
     1306        Butterfly* butterfly = thisObject->butterfly();
    13081307        if (i >= butterfly->vectorLength())
    13091308            return true;
     
    14811480    case ALL_INT32_INDEXING_TYPES:
    14821481    case ALL_CONTIGUOUS_INDEXING_TYPES: {
    1483         Butterfly* butterfly = object->m_butterfly;
     1482        Butterfly* butterfly = object->butterfly();
    14841483        unsigned usedLength = butterfly->publicLength();
    14851484        for (unsigned i = 0; i < usedLength; ++i) {
     
    14921491       
    14931492    case ALL_DOUBLE_INDEXING_TYPES: {
    1494         Butterfly* butterfly = object->m_butterfly;
     1493        Butterfly* butterfly = object->butterfly();
    14951494        unsigned usedLength = butterfly->publicLength();
    14961495        for (unsigned i = 0; i < usedLength; ++i) {
     
    18761875    if (i >= MAX_ARRAY_INDEX - 1
    18771876        || (i >= MIN_SPARSE_ARRAY_INDEX
    1878             && !isDenseEnoughForVector(i, countElements<indexingShape>(m_butterfly)))
     1877            && !isDenseEnoughForVector(i, countElements<indexingShape>(butterfly())))
    18791878        || indexIsSufficientlyBeyondLengthForSparseMap(i, m_butterfly->vectorLength())) {
    18801879        ASSERT(i <= MAX_ARRAY_INDEX);
     
    23132312       
    23142313    case ALL_INT32_INDEXING_TYPES:
    2315         return countElements<Int32Shape>(m_butterfly);
     2314        return countElements<Int32Shape>(butterfly());
    23162315       
    23172316    case ALL_DOUBLE_INDEXING_TYPES:
    2318         return countElements<DoubleShape>(m_butterfly);
     2317        return countElements<DoubleShape>(butterfly());
    23192318       
    23202319    case ALL_CONTIGUOUS_INDEXING_TYPES:
    2321         return countElements<ContiguousShape>(m_butterfly);
     2320        return countElements<ContiguousShape>(butterfly());
    23222321       
    23232322    default:
     
    23532352        if (!newButterfly)
    23542353            return false;
    2355         m_butterfly = newButterfly;
    23562354        newButterfly->arrayStorage()->setVectorLength(newVectorLength);
     2355        setButterflyWithoutChangingStructure(vm, newButterfly);
    23572356        return true;
    23582357    }
     
    23672366    if (!newButterfly)
    23682367        return false;
    2369    
    2370     m_butterfly = newButterfly;
    23712368    newButterfly->arrayStorage()->setVectorLength(newVectorLength);
    23722369    newButterfly->arrayStorage()->m_indexBias = newIndexBias;
     2370    setButterflyWithoutChangingStructure(vm, newButterfly);
    23732371    return true;
    23742372}
     
    23852383    unsigned oldVectorLength = m_butterfly->vectorLength();
    23862384    DeferGC deferGC(vm.heap);
    2387     m_butterfly = m_butterfly->growArrayRight(
     2385    m_butterfly.set(vm, this, m_butterfly->growArrayRight(
    23882386        vm, this, structure(), structure()->outOfLineCapacity(), true,
    23892387        oldVectorLength * sizeof(EncodedJSValue),
    2390         newVectorLength * sizeof(EncodedJSValue));
     2388        newVectorLength * sizeof(EncodedJSValue)));
     2389
     2390    m_butterfly->setVectorLength(newVectorLength);
     2391
    23912392    if (hasDouble(structure()->indexingType())) {
    23922393        for (unsigned i = oldVectorLength; i < newVectorLength; ++i)
    23932394            m_butterfly->contiguousDouble().data()[i] = QNaN;
    23942395    }
    2395     m_butterfly->setVectorLength(newVectorLength);
    23962396}
    23972397
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r161220 r161230  
    2828#include "ArrayStorage.h"
    2929#include "Butterfly.h"
     30#include "CallFrame.h"
    3031#include "ClassInfo.h"
    3132#include "CommonIdentifiers.h"
    32 #include "CallFrame.h"
     33#include "CopyWriteBarrier.h"
    3334#include "DeferGC.h"
     35#include "Heap.h"
     36#include "IndexingHeaderInlines.h"
    3437#include "JSCell.h"
    3538#include "PropertySlot.h"
     
    540543    }
    541544       
    542     const Butterfly* butterfly() const { return m_butterfly; }
    543     Butterfly* butterfly() { return m_butterfly; }
     545    const Butterfly* butterfly() const { return m_butterfly.get(); }
     546    Butterfly* butterfly() { return m_butterfly.get(); }
    544547       
    545548    ConstPropertyStorage outOfLineStorage() const { return m_butterfly->propertyStorage(); }
     
    606609
    607610    JS_EXPORT_PRIVATE Butterfly* growOutOfLineStorage(VM&, size_t oldSize, size_t newSize);
    608     void setButterflyWithoutChangingStructure(Butterfly*); // You probably don't want to call this.
     611    void setButterflyWithoutChangingStructure(VM&, Butterfly*);
    609612       
    610613    void setStructure(VM&, Structure*);
     
    976979   
    977980protected:
    978     Butterfly* m_butterfly;
     981    CopyWriteBarrier<Butterfly> m_butterfly;
    979982};
    980983
     
    11361139inline void JSObject::setStructureAndButterfly(VM& vm, Structure* structure, Butterfly* butterfly)
    11371140{
    1138     m_butterfly = butterfly;
     1141    ASSERT(structure);
     1142    ASSERT(!butterfly == (!structure->outOfLineCapacity() && !structure->hasIndexingHeader(this)));
     1143    m_butterfly.set(vm, this, butterfly);
    11391144    setStructure(vm, structure);
    11401145}
     
    11471152}
    11481153
    1149 inline void JSObject::setButterflyWithoutChangingStructure(Butterfly* butterfly)
    1150 {
    1151     m_butterfly = butterfly;
     1154inline void JSObject::setButterflyWithoutChangingStructure(VM& vm, Butterfly* butterfly)
     1155{
     1156    m_butterfly.set(vm, this, butterfly);
    11521157}
    11531158
     
    11791184inline JSObject::JSObject(VM& vm, Structure* structure, Butterfly* butterfly)
    11801185    : JSCell(vm, structure)
    1181     , m_butterfly(butterfly)
     1186    , m_butterfly(vm, this, butterfly)
    11821187{
    11831188    vm.heap.ascribeOwner(this, butterfly);
     
    13031308
    13041309        DeferGC deferGC(vm.heap);
    1305         Butterfly* newButterfly = m_butterfly;
     1310        Butterfly* newButterfly = butterfly();
    13061311        if (structure()->putWillGrowOutOfLineStorage())
    13071312            newButterfly = growOutOfLineStorage(vm, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
     
    13241329    if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, specificFunction, offset)) {
    13251330        DeferGC deferGC(vm.heap);
    1326         Butterfly* newButterfly = m_butterfly;
    1327         if (currentCapacity != structure->outOfLineCapacity())
     1331        Butterfly* newButterfly = butterfly();
     1332        if (currentCapacity != structure->outOfLineCapacity()) {
     1333            ASSERT(structure != this->structure());
    13281334            newButterfly = growOutOfLineStorage(vm, currentCapacity, structure->outOfLineCapacity());
     1335        }
    13291336
    13301337        validateOffset(offset);
     
    14371444    DeferGC deferGC(vm.heap);
    14381445    ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
    1439     Butterfly* newButterfly = m_butterfly;
     1446    Butterfly* newButterfly = m_butterfly.get();
    14401447    if (structure()->putWillGrowOutOfLineStorage())
    14411448        newButterfly = growOutOfLineStorage(vm, structure()->outOfLineCapacity(), structure()->suggestedNewOutOfLineStorageCapacity());
  • trunk/Source/JavaScriptCore/runtime/MapData.cpp

    r158875 r161230  
    199199    size_t requiredSize = std::max(m_capacity + (m_capacity / 2) + 1, minimumMapSize);
    200200    void* newStorage = 0;
     201    DeferGC defer(*callFrame->heap());
    201202    if (!callFrame->heap()->tryAllocateStorage(this, requiredSize * sizeof(Entry), &newStorage)) {
    202203        throwOutOfMemoryError(callFrame);
    203204        return false;
    204205    }
    205     DeferGC defer(*callFrame->heap());
    206206    Entry* newEntries = static_cast<Entry*>(newStorage);
    207207    if (shouldPack())
     
    209209    else
    210210        replaceBackingStore(newEntries, requiredSize);
     211    Heap::writeBarrier(this);
    211212    return true;
    212213}
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r159395 r161230  
    274274   
    275275    if (table) {
    276         table = table->copy(vm, 0, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
     276        table = table->copy(vm, structure, numberOfSlotsForLastOffset(m_offset, m_inlineCapacity));
    277277        structure->m_lock.unlock();
    278278    }
Note: See TracChangeset for help on using the changeset viewer.