[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.18-1-697-g2f78b87
ggaren at apple.com
ggaren at apple.com
Wed Jan 20 22:16:25 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit aa36911439df4c7dbf9b7bb52553750c6ddcece1
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