Commit b420579a authored by weinig@apple.com's avatar weinig@apple.com

2008-10-16 Sam Weinig <sam@webkit.org>

        Reviewed by Maciej Stachowiak.

        Fix for https://bugs.webkit.org/show_bug.cgi?id=21683
        Don't create intermediate StructureIDs for builtin objects

        First step in reduce number of StructureIDs created when initializing the
        JSGlobalObject.

        - In order to avoid creating the intermediate StructureIDs use the new putDirectWithoutTransition
          and putDirectFunctionWithoutTransition to add properties to JSObjects without transitioning
          the StructureID.  This patch just implements this strategy for ObjectPrototype but alone
          reduces the number of StructureIDs create for about:blank by 10, from 142 to 132.

        * kjs/JSGlobalObject.cpp:
        (JSC::JSGlobalObject::reset):
        * kjs/JSObject.cpp:
        (JSC::JSObject::putDirectFunctionWithoutTransition):
        * kjs/JSObject.h:
        (JSC::JSObject::putDirectWithoutTransition):
        * kjs/ObjectPrototype.cpp:
        (JSC::ObjectPrototype::ObjectPrototype):
        * kjs/ObjectPrototype.h:
        * kjs/StructureID.cpp:
        (JSC::StructureID::addPropertyWithoutTransition):
        * kjs/StructureID.h:



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@37645 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent d4925584
2008-10-16 Sam Weinig <sam@webkit.org>
Reviewed by Maciej Stachowiak.
Fix for https://bugs.webkit.org/show_bug.cgi?id=21683
Don't create intermediate StructureIDs for builtin objects
First step in reduce number of StructureIDs created when initializing the
JSGlobalObject.
- In order to avoid creating the intermediate StructureIDs use the new putDirectWithoutTransition
and putDirectFunctionWithoutTransition to add properties to JSObjects without transitioning
the StructureID. This patch just implements this strategy for ObjectPrototype but alone
reduces the number of StructureIDs create for about:blank by 10, from 142 to 132.
* kjs/JSGlobalObject.cpp:
(JSC::JSGlobalObject::reset):
* kjs/JSObject.cpp:
(JSC::JSObject::putDirectFunctionWithoutTransition):
* kjs/JSObject.h:
(JSC::JSObject::putDirectWithoutTransition):
* kjs/ObjectPrototype.cpp:
(JSC::ObjectPrototype::ObjectPrototype):
* kjs/ObjectPrototype.h:
* kjs/StructureID.cpp:
(JSC::StructureID::addPropertyWithoutTransition):
* kjs/StructureID.h:
2008-10-16 Maciej Stachowiak <mjs@apple.com>
Reviewed by Cameron Zwarich.
......
......@@ -205,7 +205,8 @@ void JSGlobalObject::reset(JSValue* prototype)
d()->callbackFunctionStructure = JSCallbackFunction::createStructureID(d()->functionPrototype);
d()->prototypeFunctionStructure = PrototypeFunction::createStructureID(d()->functionPrototype);
d()->functionPrototype->addFunctionProperties(exec, d()->prototypeFunctionStructure.get());
d()->objectPrototype = new (exec) ObjectPrototype(exec, d()->prototypeFunctionStructure.get());
d()->objectPrototype = new (exec) ObjectPrototype(exec, ObjectPrototype::createStructureID(jsNull()), d()->prototypeFunctionStructure.get());
d()->emptyObjectStructure = d()->objectPrototype->inheritorID();
d()->functionPrototype->setPrototype(d()->objectPrototype);
d()->argumentsStructure = Arguments::createStructureID(d()->objectPrototype);
......@@ -258,10 +259,11 @@ void JSGlobalObject::reset(JSValue* prototype)
d()->syntaxErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, syntaxErrorPrototype);
d()->typeErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, typeErrorPrototype);
d()->URIErrorConstructor = new (exec) NativeErrorConstructor(exec, nativeErrorStructure, URIErrorPrototype);
d()->functionPrototype->putDirect(exec->propertyNames().constructor, functionConstructor, DontEnum);
d()->objectPrototype->putDirect(exec->propertyNames().constructor, objectConstructor, DontEnum);
d()->objectPrototype->putDirectWithoutTransition(exec->propertyNames().constructor, objectConstructor, DontEnum);
d()->functionPrototype->putDirect(exec->propertyNames().constructor, functionConstructor, DontEnum);
d()->arrayPrototype->putDirect(exec->propertyNames().constructor, arrayConstructor, DontEnum);
d()->booleanPrototype->putDirect(exec->propertyNames().constructor, booleanConstructor, DontEnum);
......
......@@ -490,6 +490,11 @@ void JSObject::putDirectFunction(ExecState* exec, InternalFunction* function, un
putDirect(Identifier(exec, function->name(&exec->globalData())), function, attr);
}
void JSObject::putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr)
{
putDirectWithoutTransition(Identifier(exec, function->name(&exec->globalData())), function, attr);
}
NEVER_INLINE void JSObject::fillGetterPropertySlot(PropertySlot& slot, JSValue** location)
{
if (JSObject* getterFunction = static_cast<GetterSetter*>(*location)->getter())
......
......@@ -157,6 +157,8 @@ namespace JSC {
void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr = 0);
void putDirect(const Identifier& propertyName, JSValue* value, unsigned attr, bool checkReadOnly, PutPropertySlot& slot);
void putDirectFunction(ExecState* exec, InternalFunction* function, unsigned attr = 0);
void putDirectWithoutTransition(const Identifier& propertyName, JSValue* value, unsigned attr);
void putDirectFunctionWithoutTransition(ExecState* exec, InternalFunction* function, unsigned attr);
// Fast access to known property offsets.
JSValue* getDirectOffset(size_t offset) { return m_propertyStorage[offset]; }
......@@ -413,6 +415,15 @@ inline void JSObject::putDirect(const Identifier& propertyName, JSValue* value,
setStructureID(structureID.release());
}
inline void JSObject::putDirectWithoutTransition(const Identifier& propertyName, JSValue* value, unsigned attributes)
{
size_t currentCapacity = m_structureID->propertyStorageCapacity();
size_t offset = m_structureID->addPropertyWithoutTransition(propertyName, attributes);
if (currentCapacity != m_structureID->propertyStorageCapacity())
allocatePropertyStorage(currentCapacity, m_structureID->propertyStorageCapacity());
m_propertyStorage[offset] = value;
}
inline void JSObject::transitionTo(StructureID* newStructureID)
{
if (m_structureID->propertyStorageCapacity() != newStructureID->propertyStorageCapacity())
......
......@@ -39,21 +39,21 @@ static JSValue* objectProtoFuncLookupSetter(ExecState*, JSObject*, JSValue*, con
static JSValue* objectProtoFuncPropertyIsEnumerable(ExecState*, JSObject*, JSValue*, const ArgList&);
static JSValue* objectProtoFuncToLocaleString(ExecState*, JSObject*, JSValue*, const ArgList&);
ObjectPrototype::ObjectPrototype(ExecState* exec, StructureID* prototypeFunctionStructure)
: JSObject(exec->globalData().nullProtoStructureID)
ObjectPrototype::ObjectPrototype(ExecState* exec, PassRefPtr<StructureID> stucture, StructureID* prototypeFunctionStructure)
: JSObject(stucture)
{
putDirectFunction(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, objectProtoFuncToString), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().toLocaleString, objectProtoFuncToLocaleString), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 0, exec->propertyNames().valueOf, objectProtoFuncValueOf), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().hasOwnProperty, objectProtoFuncHasOwnProperty), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().propertyIsEnumerable, objectProtoFuncPropertyIsEnumerable), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().isPrototypeOf, objectProtoFuncIsPrototypeOf), DontEnum);
// Mozilla extensions
putDirectFunction(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
putDirectFunction(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineGetter__, objectProtoFuncDefineGetter), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 2, exec->propertyNames().__defineSetter__, objectProtoFuncDefineSetter), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupGetter__, objectProtoFuncLookupGetter), DontEnum);
putDirectFunctionWithoutTransition(exec, new (exec) PrototypeFunction(exec, prototypeFunctionStructure, 1, exec->propertyNames().__lookupSetter__, objectProtoFuncLookupSetter), DontEnum);
}
// ------------------------------ Functions --------------------------------
......
......@@ -27,7 +27,7 @@ namespace JSC {
class ObjectPrototype : public JSObject {
public:
ObjectPrototype(ExecState*, StructureID* prototypeFunctionStructure);
ObjectPrototype(ExecState*, PassRefPtr<StructureID>, StructureID* prototypeFunctionStructure);
};
JSValue* objectProtoFuncToString(ExecState*, JSObject*, JSValue*, const ArgList&);
......
......@@ -317,6 +317,14 @@ PassRefPtr<StructureID> StructureID::getterSetterTransition(StructureID* structu
return transition.release();
}
size_t StructureID::addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes)
{
size_t offset = m_propertyMap.put(propertyName, attributes);
if (m_propertyMap.storageSize() > propertyStorageCapacity())
growPropertyStorageCapacity();
return offset;
}
StructureIDChain* StructureID::createCachedPrototypeChain()
{
ASSERT(typeInfo().type() == ObjectType);
......
......@@ -105,6 +105,8 @@ namespace JSC {
m_prototype->mark();
}
size_t addPropertyWithoutTransition(const Identifier& propertyName, unsigned attributes);
bool isDictionary() const { return m_isDictionary; }
const TypeInfo& typeInfo() const { return m_typeInfo; }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment