Move allocation in constructors into separate constructorBody() methods

https://bugs.webkit.org/show_bug.cgi?id=66265

Patch by Mark Hahnenberg <mhahnenberg@apple.com> on 2011-08-18
Reviewed by Oliver Hunt.

Source/JavaScriptCore:

Refactoring to put all allocations that need to be done after the object's
initialization list has executed but before the object is ready for use
into a separate constructorBody() method.  This method is still called by the constructor,
so the patch doesn't resolve any potential issues, it's just to set up the code for further refactoring.

* JavaScriptCore.exp:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* jsc.cpp:
(GlobalObject::constructorBody):
(GlobalObject::GlobalObject):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::ErrorInstance):
* runtime/ErrorInstance.h:
(JSC::ErrorInstance::constructorBody):
* runtime/ErrorPrototype.cpp:
(JSC::ErrorPrototype::ErrorPrototype):
(JSC::ErrorPrototype::constructorBody):
* runtime/ErrorPrototype.h:
* runtime/Executable.cpp:
(JSC::FunctionExecutable::FunctionExecutable):
* runtime/Executable.h:
(JSC::FunctionExecutable::constructorBody):
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::InternalFunction):
* runtime/InternalFunction.h:
(JSC::InternalFunction::constructorBody):
* runtime/JSByteArray.cpp:
(JSC::JSByteArray::JSByteArray):
* runtime/JSByteArray.h:
(JSC::JSByteArray::constructorBody):
* runtime/JSFunction.cpp:
(JSC::JSFunction::JSFunction):
(JSC::JSFunction::constructorBody):
* runtime/JSFunction.h:
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::constructorBody):
* runtime/JSPropertyNameIterator.cpp:
(JSC::JSPropertyNameIterator::JSPropertyNameIterator):
* runtime/JSPropertyNameIterator.h:
(JSC::JSPropertyNameIterator::constructorBody):
* runtime/JSString.h:
(JSC::RopeBuilder::JSString):
(JSC::RopeBuilder::constructorBody):
* runtime/NativeErrorConstructor.cpp:
(JSC::NativeErrorConstructor::NativeErrorConstructor):
* runtime/NativeErrorConstructor.h:
(JSC::NativeErrorConstructor::constructorBody):
* runtime/NativeErrorPrototype.cpp:
(JSC::NativeErrorPrototype::NativeErrorPrototype):
(JSC::NativeErrorPrototype::constructorBody):
* runtime/NativeErrorPrototype.h:
* runtime/StringObject.cpp:
* runtime/StringObject.h:
(JSC::StringObject::create):
* runtime/StringObjectThatMasqueradesAsUndefined.h:
(JSC::StringObjectThatMasqueradesAsUndefined::create):
(JSC::StringObjectThatMasqueradesAsUndefined::StringObjectThatMasqueradesAsUndefined):
* runtime/StringPrototype.cpp:
(JSC::StringPrototype::StringPrototype):
* runtime/StringPrototype.h:
(JSC::StringPrototype::create):

Source/WebCore:

No new tests.

Refactoring to put all allocations that need to be done after the object's
initialization list has executed but before the object is ready for use
into a separate constructorBody() method.  This method is still called by the constructor,
so the patch doesn't resolve any potential issues, it's just to set up the code for further refactoring.

* bridge/objc/ObjCRuntimeObject.h:
(JSC::Bindings::ObjCRuntimeObject::create):
* bridge/objc/ObjCRuntimeObject.mm:
* bridge/objc/objc_instance.mm:
(ObjCRuntimeMethod::create):
(ObjCRuntimeMethod::ObjCRuntimeMethod):
* bridge/runtime_array.cpp:
* bridge/runtime_array.h:
(JSC::RuntimeArray::create):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@93378 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 3c6a50cd
2011-08-18 Mark Hahnenberg <mhahnenberg@apple.com>
Move allocation in constructors into separate constructorBody() methods
https://bugs.webkit.org/show_bug.cgi?id=66265
Reviewed by Oliver Hunt.
Refactoring to put all allocations that need to be done after the object's
initialization list has executed but before the object is ready for use
into a separate constructorBody() method. This method is still called by the constructor,
so the patch doesn't resolve any potential issues, it's just to set up the code for further refactoring.
* JavaScriptCore.exp:
* JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
* jsc.cpp:
(GlobalObject::constructorBody):
(GlobalObject::GlobalObject):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::ErrorInstance):
* runtime/ErrorInstance.h:
(JSC::ErrorInstance::constructorBody):
* runtime/ErrorPrototype.cpp:
(JSC::ErrorPrototype::ErrorPrototype):
(JSC::ErrorPrototype::constructorBody):
* runtime/ErrorPrototype.h:
* runtime/Executable.cpp:
(JSC::FunctionExecutable::FunctionExecutable):
* runtime/Executable.h:
(JSC::FunctionExecutable::constructorBody):
* runtime/InternalFunction.cpp:
(JSC::InternalFunction::InternalFunction):
* runtime/InternalFunction.h:
(JSC::InternalFunction::constructorBody):
* runtime/JSByteArray.cpp:
(JSC::JSByteArray::JSByteArray):
* runtime/JSByteArray.h:
(JSC::JSByteArray::constructorBody):
* runtime/JSFunction.cpp:
(JSC::JSFunction::JSFunction):
(JSC::JSFunction::constructorBody):
* runtime/JSFunction.h:
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::JSGlobalObject):
(JSC::JSGlobalObject::constructorBody):
* runtime/JSPropertyNameIterator.cpp:
(JSC::JSPropertyNameIterator::JSPropertyNameIterator):
* runtime/JSPropertyNameIterator.h:
(JSC::JSPropertyNameIterator::constructorBody):
* runtime/JSString.h:
(JSC::RopeBuilder::JSString):
(JSC::RopeBuilder::constructorBody):
* runtime/NativeErrorConstructor.cpp:
(JSC::NativeErrorConstructor::NativeErrorConstructor):
* runtime/NativeErrorConstructor.h:
(JSC::NativeErrorConstructor::constructorBody):
* runtime/NativeErrorPrototype.cpp:
(JSC::NativeErrorPrototype::NativeErrorPrototype):
(JSC::NativeErrorPrototype::constructorBody):
* runtime/NativeErrorPrototype.h:
* runtime/StringObject.cpp:
* runtime/StringObject.h:
(JSC::StringObject::create):
* runtime/StringObjectThatMasqueradesAsUndefined.h:
(JSC::StringObjectThatMasqueradesAsUndefined::create):
(JSC::StringObjectThatMasqueradesAsUndefined::StringObjectThatMasqueradesAsUndefined):
* runtime/StringPrototype.cpp:
(JSC::StringPrototype::StringPrototype):
* runtime/StringPrototype.h:
(JSC::StringPrototype::create):
2011-08-10 Filip Pizlo <fpizlo@apple.com>
DFG non-speculative JIT does not inline the double case of ValueAdd
......
......@@ -151,7 +151,7 @@ __ZN3JSC12StringObject19getOwnPropertyNamesEPNS_9ExecStateERNS_17PropertyNameArr
__ZN3JSC12StringObject24getOwnPropertyDescriptorEPNS_9ExecStateERKNS_10IdentifierERNS_18PropertyDescriptorE
__ZN3JSC12StringObject3putEPNS_9ExecStateERKNS_10IdentifierENS_7JSValueERNS_15PutPropertySlotE
__ZN3JSC12StringObject6s_infoE
__ZN3JSC12StringObjectC2EPNS_9ExecStateEPNS_9StructureERKNS_7UStringE
__ZN3JSC12StringObjectC2ERNS_12JSGlobalDataEPNS_9StructureEPNS_8JSStringE
__ZN3JSC13SamplingFlags4stopEv
__ZN3JSC13SamplingFlags5startEv
__ZN3JSC13SamplingFlags7s_flagsE
......
......@@ -19,7 +19,7 @@ EXPORTS
??0RefCountedLeakCounter@WTF@@QAE@PBD@Z
??0RegExpObject@JSC@@IAE@PAVJSGlobalObject@1@PAVStructure@1@PAVRegExp@1@@Z
??0SHA1@WTF@@QAE@XZ
??0StringObject@JSC@@IAE@PAVExecState@1@PAVStructure@1@ABVUString@1@@Z
??0StringObject@JSC@@IAE@AAVJSGlobalData@1@PAVStructure@1@PAVJSString@1@@Z
??0Structure@JSC@@AAE@AAVJSGlobalData@1@VJSValue@1@ABVTypeInfo@1@IPBUClassInfo@1@@Z
??0ThreadCondition@WTF@@QAE@XZ
??0UString@JSC@@QAE@PBD@Z
......
......@@ -155,36 +155,42 @@ public:
return new (allocateCell<GlobalObject>(globalData.heap)) GlobalObject(globalData, structure, arguments);
}
virtual UString className() const { return "global"; }
};
COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false);
ASSERT_CLASS_FITS_IN_CELL(GlobalObject);
GlobalObject::GlobalObject(JSGlobalData& globalData, Structure* structure, const Vector<UString>& arguments)
: JSGlobalObject(globalData, structure)
{
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "debug"), functionDebug));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "print"), functionPrint));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "quit"), functionQuit));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "gc"), functionGC));
protected:
void constructorBody(const Vector<UString>& arguments)
{
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "debug"), functionDebug));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "print"), functionPrint));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "quit"), functionQuit));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "gc"), functionGC));
#ifndef NDEBUG
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "releaseExecutableMemory"), functionReleaseExecutableMemory));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "releaseExecutableMemory"), functionReleaseExecutableMemory));
#endif
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "version"), functionVersion));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "run"), functionRun));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "load"), functionLoad));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "checkSyntax"), functionCheckSyntax));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "readline"), functionReadline));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "preciseTime"), functionPreciseTime));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "version"), functionVersion));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "run"), functionRun));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "load"), functionLoad));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "checkSyntax"), functionCheckSyntax));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "readline"), functionReadline));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 0, Identifier(globalExec(), "preciseTime"), functionPreciseTime));
#if ENABLE(SAMPLING_FLAGS)
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "setSamplingFlags"), functionSetSamplingFlags));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "clearSamplingFlags"), functionClearSamplingFlags));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "setSamplingFlags"), functionSetSamplingFlags));
putDirectFunction(globalExec(), JSFunction::create(globalExec(), this, functionStructure(), 1, Identifier(globalExec(), "clearSamplingFlags"), functionClearSamplingFlags));
#endif
JSObject* array = constructEmptyArray(globalExec());
for (size_t i = 0; i < arguments.size(); ++i)
array->put(globalExec(), i, jsString(globalExec(), arguments[i]));
putDirect(globalExec()->globalData(), Identifier(globalExec(), "arguments"), array);
JSObject* array = constructEmptyArray(globalExec());
for (size_t i = 0; i < arguments.size(); ++i)
array->put(globalExec(), i, jsString(globalExec(), arguments[i]));
putDirect(globalExec()->globalData(), Identifier(globalExec(), "arguments"), array);
}
};
COMPILE_ASSERT(!IsInteger<GlobalObject>::value, WTF_IsInteger_GlobalObject_false);
ASSERT_CLASS_FITS_IN_CELL(GlobalObject);
GlobalObject::GlobalObject(JSGlobalData& globalData, Structure* structure, const Vector<UString>& arguments)
: JSGlobalObject(globalData, structure)
{
constructorBody(arguments);
}
EncodedJSValue JSC_HOST_CALL functionPrint(ExecState* exec)
......
......@@ -29,8 +29,7 @@ ErrorInstance::ErrorInstance(JSGlobalData& globalData, Structure* structure)
: JSNonFinalObject(globalData, structure)
, m_appendSourceToMessage(false)
{
ASSERT(inherits(&s_info));
putDirect(globalData, globalData.propertyNames->message, jsString(&globalData, ""), DontEnum);
constructorBody(globalData);
}
ErrorInstance::ErrorInstance(JSGlobalData& globalData, Structure* structure, const UString& message)
......
......@@ -50,6 +50,12 @@ namespace JSC {
explicit ErrorInstance(JSGlobalData&, Structure*);
explicit ErrorInstance(JSGlobalData&, Structure*, const UString&);
void constructorBody(JSGlobalData& globalData)
{
ASSERT(inherits(&s_info));
putDirect(globalData, globalData.propertyNames->message, jsString(&globalData, ""), DontEnum);
}
bool m_appendSourceToMessage;
};
......
......@@ -53,9 +53,13 @@ ASSERT_CLASS_FITS_IN_CELL(ErrorPrototype);
ErrorPrototype::ErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
: ErrorInstance(exec->globalData(), structure)
{
putDirect(exec->globalData(), exec->propertyNames().name, jsNontrivialString(exec, "Error"), DontEnum);
constructorBody(exec, globalObject);
}
void ErrorPrototype::constructorBody(ExecState* exec, JSGlobalObject* globalObject)
{
ASSERT(inherits(&s_info));
putDirect(exec->globalData(), exec->propertyNames().name, jsNontrivialString(exec, "Error"), DontEnum);
putAnonymousValue(globalObject->globalData(), 0, globalObject);
}
......
......@@ -45,6 +45,8 @@ namespace JSC {
protected:
ErrorPrototype(ExecState*, JSGlobalObject*, Structure*);
void constructorBody(ExecState*, JSGlobalObject*);
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | ErrorInstance::StructureFlags;
static const unsigned AnonymousSlotCount = ErrorInstance::AnonymousSlotCount + 1;
......
......@@ -142,9 +142,7 @@ FunctionExecutable::FunctionExecutable(JSGlobalData& globalData, const Identifie
, m_name(name)
, m_symbolTable(0)
{
m_firstLine = firstLine;
m_lastLine = lastLine;
m_nameValue.set(globalData, this, jsString(&globalData, name.ustring()));
constructorBody(globalData, name, firstLine, lastLine);
}
FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
......@@ -157,7 +155,7 @@ FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name,
{
m_firstLine = firstLine;
m_lastLine = lastLine;
m_nameValue.set(exec->globalData(), this, jsString(&exec->globalData(), name.ustring()));
constructorBody(exec->globalData(), name, firstLine, lastLine);
}
......
......@@ -504,6 +504,14 @@ namespace JSC {
static const ClassInfo s_info;
protected:
void constructorBody(JSGlobalData& globalData, const Identifier& name, int firstLine, int lastLine)
{
m_firstLine = firstLine;
m_lastLine = lastLine;
m_nameValue.set(globalData, this, jsString(&globalData, name.ustring()));
}
private:
FunctionExecutable(JSGlobalData&, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine);
FunctionExecutable(ExecState*, const Identifier& name, const SourceCode&, bool forceUsesArguments, FunctionParameters*, bool, int firstLine, int lastLine);
......
......@@ -44,8 +44,7 @@ InternalFunction::InternalFunction(VPtrStealingHackType)
InternalFunction::InternalFunction(JSGlobalData* globalData, JSGlobalObject* globalObject, Structure* structure, const Identifier& name)
: JSObjectWithGlobalObject(globalObject, structure)
{
ASSERT(inherits(&s_info));
putDirect(*globalData, globalData->propertyNames->name, jsString(globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
constructorBody(*globalData, name);
}
const UString& InternalFunction::name(ExecState* exec)
......
......@@ -54,6 +54,12 @@ namespace JSC {
InternalFunction(JSGlobalData*, JSGlobalObject*, Structure*, const Identifier&);
void constructorBody(JSGlobalData& globalData, const Identifier& name)
{
ASSERT(inherits(&s_info));
putDirect(globalData, globalData.propertyNames->name, jsString(&globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
}
private:
virtual CallType getCallData(CallData&) = 0;
......
......@@ -39,7 +39,7 @@ JSByteArray::JSByteArray(ExecState* exec, Structure* structure, ByteArray* stora
: JSNonFinalObject(exec->globalData(), structure)
, m_storage(storage)
{
putDirect(exec->globalData(), exec->globalData().propertyNames->length, jsNumber(m_storage->length()), ReadOnly | DontDelete);
constructorBody(exec);
}
JSByteArray* JSByteArray::create(ExecState* exec, Structure* structure, ByteArray* storage)
......
......@@ -104,6 +104,11 @@ namespace JSC {
protected:
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSObject::StructureFlags;
void constructorBody(ExecState* exec)
{
putDirect(exec->globalData(), exec->globalData().propertyNames->length, jsNumber(m_storage->length()), ReadOnly | DontDelete);
}
private:
JSByteArray(VPtrStealingHackType)
: JSNonFinalObject(VPtrStealingHack)
......
......@@ -63,25 +63,19 @@ JSFunction::JSFunction(VPtrStealingHackType)
JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, int length, const Identifier& name, NativeExecutable* thunk)
: Base(globalObject, structure)
, m_executable(exec->globalData(), this, thunk)
, m_executable()
, m_scopeChain(exec->globalData(), this, globalObject->globalScopeChain())
{
ASSERT(inherits(&s_info));
putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
constructorBody(exec, length, name, thunk);
}
JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, int length, const Identifier& name, NativeFunction func)
: Base(globalObject, structure)
, m_executable()
, m_scopeChain(exec->globalData(), this, globalObject->globalScopeChain())
{
ASSERT(inherits(&s_info));
// Can't do this during initialization because getHostFunction might do a GC allocation.
m_executable.set(exec->globalData(), this, exec->globalData().getHostFunction(func));
putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
constructorBody(exec, length, name, exec->globalData().getHostFunction(func));
}
JSFunction::JSFunction(ExecState* exec, FunctionExecutable* executable, ScopeChainNode* scopeChainNode)
......@@ -94,6 +88,14 @@ JSFunction::JSFunction(ExecState* exec, FunctionExecutable* executable, ScopeCha
putDirectOffset(exec->globalData(), scopeChainNode->globalObject->functionNameOffset(), executable->nameValue());
}
inline void JSFunction::constructorBody(ExecState* exec, int length, const Identifier& name, ExecutableBase* executable)
{
ASSERT(inherits(&s_info));
m_executable.set(exec->globalData(), this, executable);
putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum);
}
JSFunction::~JSFunction()
{
ASSERT(vptr() == JSGlobalData::jsFunctionVPtr);
......
......@@ -123,6 +123,8 @@ namespace JSC {
protected:
const static unsigned StructureFlags = OverridesGetOwnPropertySlot | ImplementsHasInstance | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
void constructorBody(ExecState*, int length, const Identifier& name, ExecutableBase*);
private:
explicit JSFunction(VPtrStealingHackType);
......
......@@ -159,9 +159,7 @@ namespace JSC {
, m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
, m_evalEnabled(true)
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
putThisToAnonymousValue(0);
init(this);
constructorBody(this);
}
JSGlobalObject(JSGlobalData& globalData, Structure* structure, JSObject* thisValue)
......@@ -170,6 +168,11 @@ namespace JSC {
, m_globalScopeChain()
, m_weakRandom(static_cast<unsigned>(randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)))
, m_evalEnabled(true)
{
constructorBody(thisValue);
}
void constructorBody(JSObject* thisValue)
{
COMPILE_ASSERT(JSGlobalObject::AnonymousSlotCount == 1, JSGlobalObject_has_only_a_single_slot);
putThisToAnonymousValue(0);
......
......@@ -43,9 +43,7 @@ inline JSPropertyNameIterator::JSPropertyNameIterator(ExecState* exec, PropertyN
, m_jsStringsSize(propertyNameArrayData->propertyNameVector().size())
, m_jsStrings(adoptArrayPtr(new WriteBarrier<Unknown>[m_jsStringsSize]))
{
PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
for (size_t i = 0; i < m_jsStringsSize; ++i)
m_jsStrings[i].set(exec->globalData(), this, jsOwnedString(exec, propertyNameVector[i].ustring()));
constructorBody(exec, propertyNameArrayData);
}
JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSObject* o)
......
......@@ -84,6 +84,14 @@ namespace JSC {
static const ClassInfo s_info;
protected:
void constructorBody(ExecState* exec, PropertyNameArrayData* propertyNameArrayData)
{
PropertyNameArrayData::PropertyNameVector& propertyNameVector = propertyNameArrayData->propertyNameVector();
for (size_t i = 0; i < m_jsStringsSize; ++i)
m_jsStrings[i].set(exec->globalData(), this, jsOwnedString(exec, propertyNameVector[i].ustring()));
}
private:
JSPropertyNameIterator(ExecState*, PropertyNameArrayData* propertyNameArrayData, size_t numCacheableSlot);
......
......@@ -267,11 +267,7 @@ namespace JSC {
, m_length(0)
, m_fiberCount(s_maxInternalRopeLength)
{
unsigned index = 0;
appendValueInConstructAndIncrementLength(exec, index, v1);
appendValueInConstructAndIncrementLength(exec, index, v2);
appendValueInConstructAndIncrementLength(exec, index, v3);
ASSERT(index == s_maxInternalRopeLength);
constructorBody(exec, v1, v2, v3);
}
// This constructor constructs a new string by concatenating u1 & u2.
......@@ -299,6 +295,16 @@ namespace JSC {
ASSERT(index <= s_maxInternalRopeLength);
}
protected:
void constructorBody(ExecState* exec, JSValue v1, JSValue v2, JSValue v3)
{
unsigned index = 0;
appendValueInConstructAndIncrementLength(exec, index, v1);
appendValueInConstructAndIncrementLength(exec, index, v2);
appendValueInConstructAndIncrementLength(exec, index, v3);
ASSERT(index == s_maxInternalRopeLength);
}
public:
static JSString* create(JSGlobalData& globalData, const UString& value)
{
......
......@@ -35,15 +35,7 @@ const ClassInfo NativeErrorConstructor::s_info = { "Function", &InternalFunction
NativeErrorConstructor::NativeErrorConstructor(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, Structure* prototypeStructure, const UString& nameAndMessage)
: InternalFunction(&exec->globalData(), globalObject, structure, Identifier(exec, nameAndMessage))
{
ASSERT(inherits(&s_info));
NativeErrorPrototype* prototype = NativeErrorPrototype::create(exec, globalObject, prototypeStructure, nameAndMessage, this);
putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | ReadOnly | DontEnum);
m_errorStructure.set(exec->globalData(), this, ErrorInstance::createStructure(exec->globalData(), prototype));
ASSERT(m_errorStructure);
ASSERT(m_errorStructure->typeInfo().type() == ObjectType);
constructorBody(exec, globalObject, prototypeStructure, nameAndMessage);
}
void NativeErrorConstructor::visitChildren(SlotVisitor& visitor)
......
......@@ -22,6 +22,7 @@
#define NativeErrorConstructor_h
#include "InternalFunction.h"
#include "NativeErrorPrototype.h"
namespace JSC {
......@@ -47,6 +48,20 @@ namespace JSC {
Structure* errorStructure() { return m_errorStructure.get(); }
protected:
void constructorBody(ExecState* exec, JSGlobalObject* globalObject, Structure* prototypeStructure, const UString& nameAndMessage)
{
ASSERT(inherits(&s_info));
NativeErrorPrototype* prototype = NativeErrorPrototype::create(exec, globalObject, prototypeStructure, nameAndMessage, this);
putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(1), DontDelete | ReadOnly | DontEnum); // ECMA 15.11.7.5
putDirect(exec->globalData(), exec->propertyNames().prototype, prototype, DontDelete | ReadOnly | DontEnum);
m_errorStructure.set(exec->globalData(), this, ErrorInstance::createStructure(exec->globalData(), prototype));
ASSERT(m_errorStructure);
ASSERT(m_errorStructure->typeInfo().type() == ObjectType);
}
private:
NativeErrorConstructor(ExecState*, JSGlobalObject*, Structure*, Structure* prototypeStructure, const UString&);
static const unsigned StructureFlags = OverridesVisitChildren | InternalFunction::StructureFlags;
......
......@@ -32,6 +32,11 @@ ASSERT_CLASS_FITS_IN_CELL(NativeErrorPrototype);
NativeErrorPrototype::NativeErrorPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, const UString& nameAndMessage, NativeErrorConstructor* constructor)
: ErrorPrototype(exec, globalObject, structure)
{
constructorBody(exec, nameAndMessage, constructor);
}
inline void NativeErrorPrototype::constructorBody(ExecState* exec, const UString& nameAndMessage, NativeErrorConstructor* constructor)
{
putDirect(exec->globalData(), exec->propertyNames().name, jsString(exec, nameAndMessage), DontEnum);
putDirect(exec->globalData(), exec->propertyNames().message, jsString(exec, nameAndMessage), DontEnum);
......
......@@ -37,6 +37,9 @@ namespace JSC {
{
return new (allocateCell<NativeErrorPrototype>(*exec->heap())) NativeErrorPrototype(exec, globalObject, structure, nameAndMessage, constructor);
}
protected:
void constructorBody(ExecState*, const UString& nameAndMessage, NativeErrorConstructor*);
};
} // namespace JSC
......
......@@ -29,13 +29,6 @@ ASSERT_CLASS_FITS_IN_CELL(StringObject);
const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0 };
StringObject::StringObject(ExecState* exec, Structure* structure)
: JSWrapperObject(exec->globalData(), structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsEmptyString(exec));
}
StringObject::StringObject(JSGlobalData& globalData, Structure* structure, JSString* string)
: JSWrapperObject(globalData, structure)
{
......@@ -43,13 +36,6 @@ StringObject::StringObject(JSGlobalData& globalData, Structure* structure, JSStr
setInternalValue(globalData, string);
}
StringObject::StringObject(ExecState* exec, Structure* structure, const UString& string)
: JSWrapperObject(exec->globalData(), structure)
{
ASSERT(inherits(&s_info));
setInternalValue(exec->globalData(), jsString(exec, string));
}
bool StringObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
{
if (internalValue()->getStringPropertySlot(exec, propertyName, slot))
......
......@@ -32,14 +32,15 @@ namespace JSC {
static StringObject* create(ExecState* exec, Structure* structure)
{
return new (allocateCell<StringObject>(*exec->heap())) StringObject(exec, structure);
JSString* string = jsEmptyString(exec);
return new (allocateCell<StringObject>(*exec->heap())) StringObject(exec->globalData(), structure, string);
}
static StringObject* create(ExecState* exec, Structure* structure, const UString& str)
{
return new (allocateCell<StringObject>(*exec->heap())) StringObject(exec, structure, str);
JSString* string = jsString(exec, str);
return new (allocateCell<StringObject>(*exec->heap())) StringObject(exec->globalData(), structure, string);
}
static StringObject* create(ExecState*, JSGlobalObject*, JSString*);
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
......@@ -59,8 +60,6 @@ namespace JSC {
}
protected:
StringObject(ExecState*, Structure*);
StringObject(ExecState*, Structure*, const UString&);
static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesGetPropertyNames | JSWrapperObject::StructureFlags;
StringObject(JSGlobalData&, Structure*, JSString*);
};
......
......@@ -34,13 +34,14 @@ namespace JSC {
static StringObjectThatMasqueradesAsUndefined* create(ExecState* exec, const UString& string)
{
JSString* newString = jsString(exec, string);
return new (allocateCell<StringObjectThatMasqueradesAsUndefined>(*exec->heap())) StringObjectThatMasqueradesAsUndefined(exec,
createStructure(exec->globalData(), exec->lexicalGlobalObject()->stringPrototype()), string);
createStructure(exec->globalData(), exec->lexicalGlobalObject()->stringPrototype()), newString);
}
private:
StringObjectThatMasqueradesAsUndefined(ExecState* exec, Structure* structure, const UString& string)
: StringObject(exec, structure, string)
StringObjectThatMasqueradesAsUndefined(ExecState* exec, Structure* structure, JSString* string)
: StringObject(exec->globalData(), structure, string)
{
}
......
......@@ -131,8 +131,8 @@ const ClassInfo StringPrototype::s_info = { "String", &StringObject::s_info, 0,
*/
// ECMA 15.5.4
StringPrototype::StringPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
: StringObject(exec, structure)
StringPrototype::StringPrototype(ExecState* exec, JSGlobalObject* globalObject, Structure* structure, JSString* nameAndMessage)
: StringObject(exec->globalData(), structure, nameAndMessage)
{
ASSERT(inherits(&s_info));
......
......@@ -29,14 +29,15 @@ namespace JSC {
class StringPrototype : public StringObject {
private:
StringPrototype(ExecState*, JSGlobalObject*, Structure*);
StringPrototype(ExecState*, JSGlobalObject*, Structure*, JSString*);
public:
typedef StringObject Base;
static StringPrototype* create(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
{
return new (allocateCell<StringPrototype>(*exec->heap())) StringPrototype(exec, globalObject, structure);
JSString* nameAndMessage = jsEmptyString(exec);
return new (allocateCell<StringPrototype>(*exec->heap())) StringPrototype(exec, globalObject, structure, nameAndMessage);
}
virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
......
2011-08-18 Mark Hahnenberg <mhahnenberg@apple.com>
Move allocation in constructors into separate constructorBody() methods
https://bugs.webkit.org/show_bug.cgi?id=66265
Reviewed by Oliver Hunt.
No new tests.
Refactoring to put all allocations that need to be done after the object's
initialization list has executed but before the object is ready for use
into a separate constructorBody() method. This method is still called by the constructor,
so the patch doesn't resolve any potential issues, it's just to set up the code for further refactoring.
* bridge/objc/ObjCRuntimeObject.h:
(JSC::Bindings::ObjCRuntimeObject::create):