Ignore:
Timestamp:
Jul 25, 2012, 6:22:59 PM (13 years ago)
Author:
[email protected]
Message:

JSC GC object copying APIs should allow for greater flexibility
https://bugs.webkit.org/show_bug.cgi?id=92316

Reviewed by Mark Hahnenberg.

It's now the case that visitChildren() methods can directly pin and allocate in new space during copying.
They can also do the copying and marking themselves. This new API is only used for JSObjects for now.

(JSC::SlotVisitor::allocateNewSpaceSlow):
(JSC::SlotVisitor::allocateNewSpaceOrPin):
(JSC):
(JSC::SlotVisitor::copyAndAppend):

  • heap/MarkStack.h:

(MarkStack):
(JSC::MarkStack::appendUnbarrieredValue):
(JSC):

  • heap/SlotVisitor.h:
  • heap/SlotVisitorInlineMethods.h: Added.

(JSC):
(JSC::SlotVisitor::checkIfShouldCopyAndPinOtherwise):
(JSC::SlotVisitor::allocateNewSpace):

  • runtime/JSObject.cpp:

(JSC::JSObject::visitOutOfLineStorage):
(JSC):
(JSC::JSObject::visitChildren):
(JSC::JSFinalObject::visitChildren):

  • runtime/JSObject.h:

(JSObject):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r123682 r123690  
    3939#include "PropertyDescriptor.h"
    4040#include "PropertyNameArray.h"
     41#include "SlotVisitorInlineMethods.h"
    4142#include <math.h>
    4243#include <wtf/Assertions.h>
     
    8485        }
    8586    }
     87}
     88
     89ALWAYS_INLINE void JSObject::visitOutOfLineStorage(SlotVisitor& visitor, PropertyStorage storage, size_t storageSize)
     90{
     91    ASSERT(storage);
     92    ASSERT(storageSize);
     93   
     94    size_t capacity = structure()->outOfLineCapacity();
     95    ASSERT(capacity);
     96    size_t capacityInBytes = capacity * sizeof(WriteBarrierBase<Unknown>);
     97    PropertyStorage baseOfStorage = storage - capacity - 1;
     98    if (visitor.checkIfShouldCopyAndPinOtherwise(baseOfStorage, capacityInBytes)) {
     99        PropertyStorage newBaseOfStorage = static_cast<PropertyStorage>(visitor.allocateNewSpace(capacityInBytes));
     100        PropertyStorage currentTarget = newBaseOfStorage + capacity;
     101        PropertyStorage newStorage = currentTarget + 1;
     102        PropertyStorage currentSource = storage - 1;
     103        for (size_t count = storageSize; count--;) {
     104            JSValue value = (--currentSource)->get();
     105            ASSERT(value);
     106            visitor.appendUnbarrieredValue(&value);
     107            (--currentTarget)->setWithoutWriteBarrier(value);
     108        }
     109        m_outOfLineStorage.set(newStorage, StorageBarrier::Unchecked);
     110    } else
     111        visitor.appendValues(storage - storageSize - 1, storageSize);
    86112}
    87113
     
    98124
    99125    PropertyStorage storage = thisObject->outOfLineStorage();
    100     if (storage) {
    101         size_t storageSize = thisObject->structure()->outOfLineSizeForKnownNonFinalObject();
    102         size_t capacity = thisObject->structure()->outOfLineCapacity();
    103         // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
    104         void* temp = storage - capacity - 1;
    105         visitor.copyAndAppend(&temp, capacity * sizeof(WriteBarrierBase<Unknown>), (storage - storageSize - 1)->slot(), storageSize);
    106         storage = static_cast<PropertyStorage>(temp) + capacity + 1;
    107         thisObject->m_outOfLineStorage.set(storage, StorageBarrier::Unchecked);
    108     }
     126    if (storage)
     127        thisObject->visitOutOfLineStorage(visitor, storage, thisObject->structure()->outOfLineSizeForKnownNonFinalObject());
    109128
    110129#if !ASSERT_DISABLED
     
    125144
    126145    PropertyStorage storage = thisObject->outOfLineStorage();
    127     if (storage) {
    128         size_t storageSize = thisObject->structure()->outOfLineSizeForKnownFinalObject();
    129         size_t capacity = thisObject->structure()->outOfLineCapacity();
    130         // We have this extra temp here to slake GCC's thirst for the blood of those who dereference type-punned pointers.
    131         void* temp = storage - capacity - 1;
    132         visitor.copyAndAppend(&temp, thisObject->structure()->outOfLineCapacity() * sizeof(WriteBarrierBase<Unknown>), (storage - storageSize - 1)->slot(), storageSize);
    133         storage = static_cast<PropertyStorage>(temp) + capacity + 1;
    134         thisObject->m_outOfLineStorage.set(storage, StorageBarrier::Unchecked);
    135     }
     146    if (storage)
     147        thisObject->visitOutOfLineStorage(visitor, storage, thisObject->structure()->outOfLineSizeForKnownFinalObject());
    136148
    137149    size_t storageSize = thisObject->structure()->inlineSizeForKnownFinalObject();
Note: See TracChangeset for help on using the changeset viewer.