Reviewed by Maciej Stachowiak.
Patch for https://bugs.webkit.org/show_bug.cgi?id=20849
Cache property names for getEnumerablePropertyNames in the StructureID.
~0.5% speedup on Sunspider overall (9.7% speedup on string-fasta). ~1% speedup
on the v8 test suite.
* kjs/JSObject.cpp:
(JSC::JSObject::getPropertyNames):
* kjs/PropertyMap.cpp:
(JSC::PropertyMap::getEnumerablePropertyNames):
* kjs/PropertyMap.h:
* kjs/StructureID.cpp:
(JSC::StructureID::StructureID):
(JSC::StructureID::getEnumerablePropertyNames):
* kjs/StructureID.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@36429
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2008-09-15 Sam Weinig <sam@webkit.org>
+
+ Reviewed by Maciej Stachowiak.
+
+ Patch for https://bugs.webkit.org/show_bug.cgi?id=20849
+ Cache property names for getEnumerablePropertyNames in the StructureID.
+
+ ~0.5% speedup on Sunspider overall (9.7% speedup on string-fasta). ~1% speedup
+ on the v8 test suite.
+
+ * kjs/JSObject.cpp:
+ (JSC::JSObject::getPropertyNames):
+ * kjs/PropertyMap.cpp:
+ (JSC::PropertyMap::getEnumerablePropertyNames):
+ * kjs/PropertyMap.h:
+ * kjs/StructureID.cpp:
+ (JSC::StructureID::StructureID):
+ (JSC::StructureID::getEnumerablePropertyNames):
+ * kjs/StructureID.h:
+
2008-09-14 Maciej Stachowiak <mjs@apple.com>
Reviewed by Cameron Zwarich.
void JSObject::getPropertyNames(ExecState* exec, PropertyNameArray& propertyNames)
{
- m_structureID->propertyMap().getEnumerablePropertyNames(propertyNames);
+ m_structureID->getEnumerablePropertyNames(propertyNames);
// Add properties from the static hashtables of properties
for (const ClassInfo* info = classInfo(); info; info = info->parentClass) {
#include "JSObject.h"
#include "protect.h"
-#include "PropertyNameArray.h"
#include <algorithm>
#include <wtf/Assertions.h>
#include <wtf/FastMalloc.h>
return 0;
}
-void PropertyMap::getEnumerablePropertyNames(PropertyNameArray& propertyNames) const
+void PropertyMap::getEnumerablePropertyNames(Vector<UString::Rep*>& propertyNames) const
{
if (!m_table)
return;
++i;
}
}
- if (!propertyNames.size()) {
- for (int k = 0; k < i; ++k)
- propertyNames.addKnownUnique(a[k]->key);
- } else {
- for (int k = 0; k < i; ++k)
- propertyNames.add(a[k]->key);
- }
+ propertyNames.reserveCapacity(i);
+ for (int k = 0; k < i; ++k)
+ propertyNames.append(a[k]->key);
return;
}
qsort(sortedEnumerables.data(), p - sortedEnumerables.data(), sizeof(Entry*), comparePropertyMapEntryIndices);
// Put the keys of the sorted entries into the list.
- for (Entry** q = sortedEnumerables.data(); q != p; ++q)
- propertyNames.add(q[0]->key);
+ propertyNames.reserveCapacity(sortedEnumerables.size());
+ for (size_t i = 0; i < sortedEnumerables.size(); ++i)
+ propertyNames.append(sortedEnumerables[i]->key);
}
#if DO_PROPERTYMAP_CONSTENCY_CHECK
class JSObject;
class JSValue;
- class PropertyNameArray;
typedef JSValue** PropertyStorage;
size_t getOffset(const Identifier& propertyName);
size_t getOffset(const Identifier& propertyName, unsigned& attributes);
- void getEnumerablePropertyNames(PropertyNameArray&) const;
+ void getEnumerablePropertyNames(Vector<UString::Rep*>&) const;
bool hasGetterSetterProperties() const { return m_getterSetterFlag; }
void setHasGetterSetterProperties(bool f) { m_getterSetterFlag = f; }
#include "identifier.h"
#include "JSObject.h"
+#include "PropertyNameArray.h";
#include <wtf/RefPtr.h>
using namespace std;
namespace JSC {
- StructureID::StructureID(JSValue* prototype, JSType type)
+StructureID::StructureID(JSValue* prototype, JSType type)
: m_isDictionary(false)
, m_type(type)
, m_prototype(prototype)
ASSERT(m_prototype->isObject() || m_prototype->isNull());
}
+void StructureID::getEnumerablePropertyNames(PropertyNameArray& propertyNames) const
+{
+ if (m_cachedPropertyNameArray.isEmpty())
+ m_propertyMap.getEnumerablePropertyNames(m_cachedPropertyNameArray);
+
+ if (!propertyNames.size()) {
+ for (size_t i = 0; i < m_cachedPropertyNameArray.size(); ++i)
+ propertyNames.addKnownUnique(m_cachedPropertyNameArray[i]);
+ } else {
+ for (size_t i = 0; i < m_cachedPropertyNameArray.size(); ++i)
+ propertyNames.add(m_cachedPropertyNameArray[i]);
+ }
+}
+
void StructureID::transitionTo(StructureID* oldStructureID, StructureID* newStructureID, JSObject* slotBase)
{
if (!slotBase->usingInlineStorage() && oldStructureID->m_propertyMap.size() != newStructureID->m_propertyMap.size())
namespace JSC {
class JSValue;
+ class PropertyNameArray;
class StructureIDChain;
struct TransitionTableHash {
const PropertyMap& propertyMap() const { return m_propertyMap; }
PropertyMap& propertyMap() { return m_propertyMap; }
+ void getEnumerablePropertyNames(PropertyNameArray&) const;
+
static void transitionTo(StructureID* oldStructureID, StructureID* newStructureID, JSObject* slotBase);
private:
size_t m_transitionCount;
TransitionTable m_transitionTable;
+ mutable Vector<UString::Rep*> m_cachedPropertyNameArray;
+
PropertyMap m_propertyMap;
};