Changeset 117343 in webkit


Ignore:
Timestamp:
May 16, 2012 2:21:44 PM (12 years ago)
Author:
mhahnenberg@apple.com
Message:

GC in the middle of JSObject::allocatePropertyStorage can cause badness
https://bugs.webkit.org/show_bug.cgi?id=83839

Reviewed by Geoff Garen.

  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
  • jit/JITStubs.cpp: Making changes to use the new return value of growPropertyStorage.

(JSC::DEFINE_STUB_FUNCTION):

  • runtime/JSObject.cpp:

(JSC::JSObject::growPropertyStorage): Renamed to more accurately reflect that we're
growing our already-existing PropertyStorage.

  • runtime/JSObject.h:

(JSObject):
(JSC::JSObject::setPropertyStorage): "Atomically" sets the new property storage
and the new structure so that we can be sure a GC never occurs when our Structure
info is out of sync with our PropertyStorage.
(JSC):
(JSC::JSObject::putDirectInternal): Moved the check to see if we should
allocate more backing store before the actual property insertion into
the structure.
(JSC::JSObject::putDirectWithoutTransition): Ditto.
(JSC::JSObject::transitionTo): Ditto.

  • runtime/Structure.cpp:

(JSC::Structure::suggestedNewPropertyStorageSize): Added to keep the resize policy
for property backing stores contained within the Structure class.
(JSC):

  • runtime/Structure.h:

(JSC::Structure::shouldGrowPropertyStorage): Lets clients know if another insertion
into the Structure would require resizing the property backing store so that they can
preallocate the required storage.
(Structure):

Location:
trunk/Source/JavaScriptCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r117340 r117343  
     12012-05-16  Mark Hahnenberg  <mhahnenberg@apple.com>
     2
     3        GC in the middle of JSObject::allocatePropertyStorage can cause badness
     4        https://bugs.webkit.org/show_bug.cgi?id=83839
     5
     6        Reviewed by Geoff Garen.
     7
     8        * JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
     9        * jit/JITStubs.cpp: Making changes to use the new return value of growPropertyStorage.
     10        (JSC::DEFINE_STUB_FUNCTION):
     11        * runtime/JSObject.cpp:
     12        (JSC::JSObject::growPropertyStorage): Renamed to more accurately reflect that we're
     13        growing our already-existing PropertyStorage.
     14        * runtime/JSObject.h:
     15        (JSObject):
     16        (JSC::JSObject::setPropertyStorage): "Atomically" sets the new property storage
     17        and the new structure so that we can be sure a GC never occurs when our Structure
     18        info is out of sync with our PropertyStorage.
     19        (JSC):
     20        (JSC::JSObject::putDirectInternal): Moved the check to see if we should
     21        allocate more backing store before the actual property insertion into
     22        the structure.
     23        (JSC::JSObject::putDirectWithoutTransition): Ditto.
     24        (JSC::JSObject::transitionTo): Ditto.
     25        * runtime/Structure.cpp:
     26        (JSC::Structure::suggestedNewPropertyStorageSize): Added to keep the resize policy
     27        for property backing stores contained within the Structure class.
     28        (JSC):
     29        * runtime/Structure.h:
     30        (JSC::Structure::shouldGrowPropertyStorage): Lets clients know if another insertion
     31        into the Structure would require resizing the property backing store so that they can
     32        preallocate the required storage.
     33        (Structure):
     34
    1352012-05-16  Geoffrey Garen  <ggaren@apple.com>
    236
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def

    r117015 r117343  
    6363    ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVJSGlobalData@2@PAVStringImpl@4@@Z
    6464    ?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
    65     ?allocatePropertyStorage@JSObject@JSC@@QAEXAAVJSGlobalData@2@II@Z
    6665    ?allocateSlowCase@MarkedAllocator@JSC@@AAEPAXXZ
    6766    ?append@StringBuilder@WTF@@QAEXPBEI@Z
     
    209208    ?globalObjectCount@Heap@JSC@@QAEIXZ
    210209    ?grow@HandleSet@JSC@@AAEXXZ
     210    ?growPropertyStorage@JSObject@JSC@@QAEPAV?$WriteBarrierBase@W4Unknown@JSC@@@2@AAVJSGlobalData@2@II@Z
    211211    ?hasInstance@JSObject@JSC@@SA_NPAV12@PAVExecState@2@VJSValue@2@2@Z
    212212    ?hasProperty@JSObject@JSC@@QBE_NPAVExecState@2@I@Z
     
    320320    ?stopSampling@JSGlobalData@JSC@@QAEXXZ
    321321    ?substringSharingImpl@UString@JSC@@QBE?AV12@II@Z
     322    ?suggestedNewPropertyStorageSize@Structure@JSC@@QAEIXZ
    322323    ?synthesizePrototype@JSValue@JSC@@QBEPAVJSObject@2@PAVExecState@2@@Z
    323324    ?thisObject@DebuggerCallFrame@JSC@@QBEPAVJSObject@2@XZ
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r116670 r117343  
    14931493    ASSERT(baseValue.isObject());
    14941494    JSObject* base = asObject(baseValue);
    1495     base->allocatePropertyStorage(*stackFrame.globalData, oldSize, newSize);
     1495    JSGlobalData& globalData = *stackFrame.globalData;
     1496    PropertyStorage newStorage = base->growPropertyStorage(globalData, oldSize, newSize);
     1497    base->setPropertyStorage(globalData, newStorage, newStructure);
    14961498
    14971499    return base;
  • trunk/Source/JavaScriptCore/runtime/JSObject.cpp

    r116828 r117343  
    553553}
    554554
    555 void JSObject::allocatePropertyStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize)
     555PropertyStorage JSObject::growPropertyStorage(JSGlobalData& globalData, size_t oldSize, size_t newSize)
    556556{
    557557    ASSERT(newSize > oldSize);
     
    581581
    582582    ASSERT(newPropertyStorage);
    583     m_propertyStorage.set(globalData, this, newPropertyStorage);
     583    return newPropertyStorage;
    584584}
    585585
  • trunk/Source/JavaScriptCore/runtime/JSObject.h

    r116828 r117343  
    213213        void reifyStaticFunctionsForDelete(ExecState* exec);
    214214
    215         JS_EXPORT_PRIVATE void allocatePropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize);
     215        JS_EXPORT_PRIVATE PropertyStorage growPropertyStorage(JSGlobalData&, size_t oldSize, size_t newSize);
    216216        bool isUsingInlineStorage() const { return static_cast<const void*>(m_propertyStorage.get()) == static_cast<const void*>(this + 1); }
     217        void setPropertyStorage(JSGlobalData&, PropertyStorage, Structure*);
    217218
    218219        void* addressOfPropertyStorage()
     
    453454}
    454455
     456inline void JSObject::setPropertyStorage(JSGlobalData& globalData, PropertyStorage storage, Structure* structure)
     457{
     458    ASSERT(storage);
     459    ASSERT(structure);
     460    setStructure(globalData, structure);
     461    m_propertyStorage.set(globalData, this, storage);
     462}
     463
    455464inline JSObject* constructEmptyObject(ExecState* exec, Structure* structure)
    456465{
     
    664673            return false;
    665674
    666         size_t currentCapacity = structure()->propertyStorageCapacity();
     675        PropertyStorage newStorage = propertyStorage();
     676        if (structure()->shouldGrowPropertyStorage())
     677            newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize());
    667678        offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, specificFunction);
    668         if (currentCapacity != structure()->propertyStorageCapacity())
    669             allocatePropertyStorage(globalData, currentCapacity, structure()->propertyStorageCapacity());
     679        setPropertyStorage(globalData, newStorage, structure());
    670680
    671681        ASSERT(offset < structure()->propertyStorageCapacity());
     
    679689    size_t offset;
    680690    size_t currentCapacity = structure()->propertyStorageCapacity();
    681     if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, specificFunction, offset)) {   
     691    if (Structure* structure = Structure::addPropertyTransitionToExistingStructure(this->structure(), propertyName, attributes, specificFunction, offset)) {
     692        PropertyStorage newStorage = propertyStorage();
    682693        if (currentCapacity != structure->propertyStorageCapacity())
    683             allocatePropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity());
     694            newStorage = growPropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity());
    684695
    685696        ASSERT(offset < structure->propertyStorageCapacity());
    686         setStructure(globalData, structure);
     697        setPropertyStorage(globalData, newStorage, structure);
    687698        putDirectOffset(globalData, offset, value);
    688699        // This is a new property; transitions with specific values are not currently cachable,
     
    728739        return false;
    729740
     741    PropertyStorage newStorage = propertyStorage();
     742    if (structure()->shouldGrowPropertyStorage())
     743        newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize());
     744
    730745    Structure* structure = Structure::addPropertyTransition(globalData, this->structure(), propertyName, attributes, specificFunction, offset);
    731746
    732     if (currentCapacity != structure->propertyStorageCapacity())
    733         allocatePropertyStorage(globalData, currentCapacity, structure->propertyStorageCapacity());
    734 
    735747    ASSERT(offset < structure->propertyStorageCapacity());
    736     setStructure(globalData, structure);
     748    setPropertyStorage(globalData, newStorage, structure);
    737749    putDirectOffset(globalData, offset, value);
    738750    // This is a new property; transitions with specific values are not currently cachable,
     
    768780{
    769781    ASSERT(!value.isGetterSetter() && !(attributes & Accessor));
    770     size_t currentCapacity = structure()->propertyStorageCapacity();
     782    PropertyStorage newStorage = propertyStorage();
     783    if (structure()->shouldGrowPropertyStorage())
     784        newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), structure()->suggestedNewPropertyStorageSize());
    771785    size_t offset = structure()->addPropertyWithoutTransition(globalData, propertyName, attributes, getJSFunction(value));
    772     if (currentCapacity != structure()->propertyStorageCapacity())
    773         allocatePropertyStorage(globalData, currentCapacity, structure()->propertyStorageCapacity());
     786    setPropertyStorage(globalData, newStorage, structure());
    774787    putDirectOffset(globalData, offset, value);
    775788}
     
    777790inline void JSObject::transitionTo(JSGlobalData& globalData, Structure* newStructure)
    778791{
     792    PropertyStorage newStorage = propertyStorage();
    779793    if (structure()->propertyStorageCapacity() != newStructure->propertyStorageCapacity())
    780         allocatePropertyStorage(globalData, structure()->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
    781     setStructure(globalData, newStructure);
     794        newStorage = growPropertyStorage(globalData, structure()->propertyStorageCapacity(), newStructure->propertyStorageCapacity());
     795    setPropertyStorage(globalData, newStorage, newStructure);
    782796}
    783797
  • trunk/Source/JavaScriptCore/runtime/Structure.cpp

    r116828 r117343  
    267267}
    268268
     269size_t Structure::suggestedNewPropertyStorageSize()
     270{
     271    if (isUsingInlineStorage())
     272        return JSObject::baseExternalStorageCapacity;
     273    return m_propertyStorageCapacity * 2;
     274}
     275 
    269276void Structure::despecifyDictionaryFunction(JSGlobalData& globalData, PropertyName propertyName)
    270277{
  • trunk/Source/JavaScriptCore/runtime/Structure.h

    r116828 r117343  
    103103        bool isExtensible() const { return !m_preventExtensions; }
    104104        bool didTransition() const { return m_didTransition; }
     105        bool shouldGrowPropertyStorage() { return propertyStorageCapacity() == propertyStorageSize(); }
     106        JS_EXPORT_PRIVATE size_t suggestedNewPropertyStorageSize();
    105107
    106108        Structure* flattenDictionaryStructure(JSGlobalData&, JSObject*);
Note: See TracChangeset for help on using the changeset viewer.