Changeset 52948 in webkit


Ignore:
Timestamp:
Jan 7, 2010 2:07:36 PM (14 years ago)
Author:
ggaren@apple.com
Message:

2010-01-07 Geoffrey Garen <ggaren@apple.com>

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 <ggaren@apple.com>

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
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/ChangeLog

    r52924 r52948  
     12010-01-07  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Reviewed by Sam Weinig.
     4
     5        Safari memory usage skyrockets using new Google AdWords interface
     6        https://bugs.webkit.org/show_bug.cgi?id=33343
     7
     8        The memory use was caused by the global object creating too many structures
     9        as it thrashed between different specific functions.
     10
     11        * runtime/Structure.cpp:
     12        (JSC::Structure::Structure):
     13        (JSC::Structure::addPropertyTransition):
     14        (JSC::Structure::changePrototypeTransition):
     15        (JSC::Structure::despecifyFunctionTransition):
     16        (JSC::Structure::addAnonymousSlotsTransition):
     17        (JSC::Structure::getterSetterTransition):
     18        (JSC::Structure::toDictionaryTransition):
     19        (JSC::Structure::addPropertyWithoutTransition):
     20        (JSC::Structure::despecifyAllFunctions):
     21        * runtime/Structure.h:
     22        (JSC::Structure::disableSpecificFunctionTracking): Track a thrash count
     23        for specific functions. Disable specific function tracking once the
     24        thrash count has been hit.
     25
    1262010-01-07  Csaba Osztrogonác  <ossy@webkit.org>
    227
  • 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
  • trunk/WebCore/ChangeLog

    r52947 r52948  
     12010-01-07  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Reviewed by Sam Weinig.
     4
     5        Safari memory usage skyrockets using new Google AdWords interface
     6        https://bugs.webkit.org/show_bug.cgi?id=33343
     7
     8        * bindings/js/JSDOMWindowBase.cpp:
     9        (WebCore::JSDOMWindowBase::JSDOMWindowBase): Disabled specific function
     10        tracking for the window object, since there's no way to do direct
     11        method calls on the window object; they all go through the window shell.
     12
    1132010-01-07  Simon Fraser  <simon.fraser@apple.com>
    214
  • trunk/WebCore/bindings/js/JSDOMWindowBase.cpp

    r52314 r52948  
    5454    : JSDOMGlobalObject(structure, new JSDOMWindowBaseData(window, shell), shell)
    5555{
     56    structure()->disableSpecificFunctionTracking();
     57
    5658    GlobalPropertyInfo staticGlobals[] = {
    5759        GlobalPropertyInfo(Identifier(globalExec(), "document"), jsNull(), DontDelete | ReadOnly),
Note: See TracChangeset for help on using the changeset viewer.