Changeset 52948 in webkit for trunk/JavaScriptCore/runtime


Ignore:
Timestamp:
Jan 7, 2010, 2:07:36 PM (15 years ago)
Author:
[email protected]
Message:

2010-01-07 Geoffrey Garen <[email protected]>

Reviewed by Sam Weinig.

Safari memory usage skyrockets using new Google AdWords interface
https://bugs.webkit.org/show_bug.cgi?id=33343

The memory use was caused by the global object creating too many structures
as it thrashed between different specific functions.

  • runtime/Structure.cpp: (JSC::Structure::Structure): (JSC::Structure::addPropertyTransition): (JSC::Structure::changePrototypeTransition): (JSC::Structure::despecifyFunctionTransition): (JSC::Structure::addAnonymousSlotsTransition): (JSC::Structure::getterSetterTransition): (JSC::Structure::toDictionaryTransition): (JSC::Structure::addPropertyWithoutTransition): (JSC::Structure::despecifyAllFunctions):
  • runtime/Structure.h: (JSC::Structure::disableSpecificFunctionTracking): Track a thrash count for specific functions. Disable specific function tracking once the thrash count has been hit.

2010-01-07 Geoffrey Garen <[email protected]>

Reviewed by Sam Weinig.

Safari memory usage skyrockets using new Google AdWords interface
https://bugs.webkit.org/show_bug.cgi?id=33343

  • bindings/js/JSDOMWindowBase.cpp: (WebCore::JSDOMWindowBase::JSDOMWindowBase): Disabled specific function tracking for the window object, since there's no way to do direct method calls on the window object; they all go through the window shell.
Location:
trunk/JavaScriptCore/runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/Structure.cpp

    r51875 r52948  
    135135    , m_hasGetterSetterProperties(false)
    136136    , m_attributesInPrevious(0)
     137    , m_specificFunctionThrashCount(0)
    137138{
    138139    ASSERT(m_prototype);
     
    359360    ASSERT(structure->typeInfo().type() == ObjectType);
    360361    ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset));
     362   
     363    if (structure->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
     364        specificValue = 0;
    361365
    362366    if (structure->transitionCount() > s_maxTransitionLength) {
     
    379383    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
    380384    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
     385    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
    381386
    382387    if (structure->m_propertyTable) {
     
    422427    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
    423428    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
     429    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
    424430
    425431    // Don't set m_offset, as one can not transition to this.
     
    434440PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structure, const Identifier& replaceFunction)
    435441{
     442    ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount);
    436443    RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
    437444
     
    439446    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
    440447    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
     448    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount + 1;
    441449
    442450    // Don't set m_offset, as one can not transition to this.
     
    446454    transition->m_isPinnedPropertyTable = true;
    447455
    448     bool removed = transition->despecifyFunction(replaceFunction);
    449     ASSERT_UNUSED(removed, removed);
     456    if (transition->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
     457        transition->despecifyAllFunctions();
     458    else {
     459        bool removed = transition->despecifyFunction(replaceFunction);
     460        ASSERT_UNUSED(removed, removed);
     461    }
    450462
    451463    return transition.release();
     
    471483    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
    472484    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
     485    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
    473486
    474487    if (structure->m_propertyTable) {
     
    500513    transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties;
    501514    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
     515    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
    502516
    503517    // Don't set m_offset, as one can not transition to this.
     
    519533    transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
    520534    transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
     535    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
    521536   
    522537    structure->materializePropertyMapIfNecessary();
     
    583598{
    584599    ASSERT(!m_enumerationCache);
     600
     601    if (m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
     602        specificValue = 0;
     603
    585604    materializePropertyMapIfNecessary();
    586605
     
    758777        }
    759778    }
     779}
     780
     781void Structure::despecifyAllFunctions()
     782{
     783    materializePropertyMapIfNecessary();
     784    if (!m_propertyTable)
     785        return;
     786   
     787    unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
     788    for (unsigned i = 1; i <= entryCount; ++i)
     789        m_propertyTable->entries()[i].specificValue = 0;
    760790}
    761791
  • trunk/JavaScriptCore/runtime/Structure.h

    r51955 r52948  
    127127        bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; }
    128128
    129         JSCell* specificValue() { return m_specificValueInPrevious; }
    130129        void despecifyDictionaryFunction(const Identifier& propertyName);
     130        void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
    131131
    132132        void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
    133133        JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); }
    134134        void getEnumerablePropertyNames(PropertyNameArray&);
    135 
     135       
    136136    private:
    137137        Structure(JSValue prototype, const TypeInfo&);
     
    157157
    158158        bool despecifyFunction(const Identifier&);
     159        void despecifyAllFunctions();
    159160
    160161        PropertyMapHashTable* copyPropertyTable();
     
    180181
    181182        static const signed char noOffset = -1;
     183
     184        static const unsigned maxSpecificFunctionThrashCount = 3;
    182185
    183186        TypeInfo m_typeInfo;
     
    212215#endif
    213216        unsigned m_anonymousSlotsInPrevious : 6;
     217        unsigned m_specificFunctionThrashCount : 2;
     218        // 4 free bits
    214219    };
    215220
Note: See TracChangeset for help on using the changeset viewer.