[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

ggaren at apple.com ggaren at apple.com
Thu Apr 8 00:57:49 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit d0d58f4b9c17c27ba9d9e67eb3ae46fd4e899f34
Author: ggaren at apple.com <ggaren at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Jan 7 22:07:36 2010 +0000

    2010-01-07  Geoffrey Garen  <ggaren at 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 at 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.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52948 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 789260a..8ba72fc 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,28 @@
+2010-01-07  Geoffrey Garen  <ggaren at 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  Csaba Osztrogonác  <ossy at webkit.org>
 
         Reviewed by Simon Hausmann.
diff --git a/JavaScriptCore/runtime/Structure.cpp b/JavaScriptCore/runtime/Structure.cpp
index e4c9ac3..5b9a553 100644
--- a/JavaScriptCore/runtime/Structure.cpp
+++ b/JavaScriptCore/runtime/Structure.cpp
@@ -134,6 +134,7 @@ Structure::Structure(JSValue prototype, const TypeInfo& typeInfo)
     , m_isPinnedPropertyTable(false)
     , m_hasGetterSetterProperties(false)
     , m_attributesInPrevious(0)
+    , m_specificFunctionThrashCount(0)
 {
     ASSERT(m_prototype);
     ASSERT(m_prototype.isObject() || m_prototype.isNull());
@@ -358,6 +359,9 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
     ASSERT(!structure->isDictionary());
     ASSERT(structure->typeInfo().type() == ObjectType);
     ASSERT(!Structure::addPropertyTransitionToExistingStructure(structure, propertyName, attributes, specificValue, offset));
+    
+    if (structure->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
+        specificValue = 0;
 
     if (structure->transitionCount() > s_maxTransitionLength) {
         RefPtr<Structure> transition = toCacheableDictionaryTransition(structure);
@@ -378,6 +382,7 @@ PassRefPtr<Structure> Structure::addPropertyTransition(Structure* structure, con
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
 
     if (structure->m_propertyTable) {
         if (structure->m_isPinnedPropertyTable)
@@ -421,6 +426,7 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure,
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
 
     // Don't set m_offset, as one can not transition to this.
 
@@ -433,11 +439,13 @@ PassRefPtr<Structure> Structure::changePrototypeTransition(Structure* structure,
 
 PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structure, const Identifier& replaceFunction)
 {
+    ASSERT(structure->m_specificFunctionThrashCount < maxSpecificFunctionThrashCount);
     RefPtr<Structure> transition = create(structure->storedPrototype(), structure->typeInfo());
 
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount + 1;
 
     // Don't set m_offset, as one can not transition to this.
 
@@ -445,8 +453,12 @@ PassRefPtr<Structure> Structure::despecifyFunctionTransition(Structure* structur
     transition->m_propertyTable = structure->copyPropertyTable();
     transition->m_isPinnedPropertyTable = true;
 
-    bool removed = transition->despecifyFunction(replaceFunction);
-    ASSERT_UNUSED(removed, removed);
+    if (transition->m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
+        transition->despecifyAllFunctions();
+    else {
+        bool removed = transition->despecifyFunction(replaceFunction);
+        ASSERT_UNUSED(removed, removed);
+    }
 
     return transition.release();
 }
@@ -470,6 +482,7 @@ PassRefPtr<Structure> Structure::addAnonymousSlotsTransition(Structure* structur
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
 
     if (structure->m_propertyTable) {
         if (structure->m_isPinnedPropertyTable)
@@ -499,6 +512,7 @@ PassRefPtr<Structure> Structure::getterSetterTransition(Structure* structure)
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = transition->m_hasGetterSetterProperties;
     transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
 
     // Don't set m_offset, as one can not transition to this.
 
@@ -518,6 +532,7 @@ PassRefPtr<Structure> Structure::toDictionaryTransition(Structure* structure, Di
     transition->m_propertyStorageCapacity = structure->m_propertyStorageCapacity;
     transition->m_hasGetterSetterProperties = structure->m_hasGetterSetterProperties;
     transition->m_hasNonEnumerableProperties = structure->m_hasNonEnumerableProperties;
+    transition->m_specificFunctionThrashCount = structure->m_specificFunctionThrashCount;
     
     structure->materializePropertyMapIfNecessary();
     transition->m_propertyTable = structure->copyPropertyTable();
@@ -582,6 +597,10 @@ PassRefPtr<Structure> Structure::flattenDictionaryStructure(JSObject* object)
 size_t Structure::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
 {
     ASSERT(!m_enumerationCache);
+
+    if (m_specificFunctionThrashCount == maxSpecificFunctionThrashCount)
+        specificValue = 0;
+
     materializePropertyMapIfNecessary();
 
     m_isPinnedPropertyTable = true;
@@ -759,6 +778,17 @@ bool Structure::despecifyFunction(const Identifier& propertyName)
     }
 }
 
+void Structure::despecifyAllFunctions()
+{
+    materializePropertyMapIfNecessary();
+    if (!m_propertyTable)
+        return;
+    
+    unsigned entryCount = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount;
+    for (unsigned i = 1; i <= entryCount; ++i)
+        m_propertyTable->entries()[i].specificValue = 0;
+}
+
 size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue)
 {
     ASSERT(!propertyName.isNull());
diff --git a/JavaScriptCore/runtime/Structure.h b/JavaScriptCore/runtime/Structure.h
index c6b7d91..839cbd0 100644
--- a/JavaScriptCore/runtime/Structure.h
+++ b/JavaScriptCore/runtime/Structure.h
@@ -126,13 +126,13 @@ namespace JSC {
         
         bool isEmpty() const { return m_propertyTable ? !m_propertyTable->keyCount : m_offset == noOffset; }
 
-        JSCell* specificValue() { return m_specificValueInPrevious; }
         void despecifyDictionaryFunction(const Identifier& propertyName);
+        void disableSpecificFunctionTracking() { m_specificFunctionThrashCount = maxSpecificFunctionThrashCount; }
 
         void setEnumerationCache(JSPropertyNameIterator* enumerationCache); // Defined in JSPropertyNameIterator.h.
         JSPropertyNameIterator* enumerationCache() { return m_enumerationCache.get(); }
         void getEnumerablePropertyNames(PropertyNameArray&);
-
+        
     private:
         Structure(JSValue prototype, const TypeInfo&);
         
@@ -156,6 +156,7 @@ namespace JSC {
         void checkConsistency();
 
         bool despecifyFunction(const Identifier&);
+        void despecifyAllFunctions();
 
         PropertyMapHashTable* copyPropertyTable();
         void materializePropertyMap();
@@ -180,6 +181,8 @@ namespace JSC {
 
         static const signed char noOffset = -1;
 
+        static const unsigned maxSpecificFunctionThrashCount = 3;
+
         TypeInfo m_typeInfo;
 
         JSValue m_prototype;
@@ -211,6 +214,8 @@ namespace JSC {
         unsigned m_attributesInPrevious : 7;
 #endif
         unsigned m_anonymousSlotsInPrevious : 6;
+        unsigned m_specificFunctionThrashCount : 2;
+        // 4 free bits
     };
 
     inline size_t Structure::get(const Identifier& propertyName)
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 5437621..eb3d6a3 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,15 @@
+2010-01-07  Geoffrey Garen  <ggaren at 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.
+
 2010-01-07  Simon Fraser  <simon.fraser at apple.com>
 
         Reviewed by Kevin Decker, Darin Adler.
diff --git a/WebCore/bindings/js/JSDOMWindowBase.cpp b/WebCore/bindings/js/JSDOMWindowBase.cpp
index b886b52..f0c9279 100644
--- a/WebCore/bindings/js/JSDOMWindowBase.cpp
+++ b/WebCore/bindings/js/JSDOMWindowBase.cpp
@@ -53,6 +53,8 @@ JSDOMWindowBase::JSDOMWindowBaseData::JSDOMWindowBaseData(PassRefPtr<DOMWindow>
 JSDOMWindowBase::JSDOMWindowBase(NonNullPassRefPtr<Structure> structure, PassRefPtr<DOMWindow> window, JSDOMWindowShell* shell)
     : JSDOMGlobalObject(structure, new JSDOMWindowBaseData(window, shell), shell)
 {
+    structure()->disableSpecificFunctionTracking();
+
     GlobalPropertyInfo staticGlobals[] = {
         GlobalPropertyInfo(Identifier(globalExec(), "document"), jsNull(), DontDelete | ReadOnly),
         GlobalPropertyInfo(Identifier(globalExec(), "window"), d()->shell, DontDelete | ReadOnly)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list