Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (92249 => 92250)
--- trunk/Source/_javascript_Core/ChangeLog 2011-08-03 00:04:06 UTC (rev 92249)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-08-03 00:41:11 UTC (rev 92250)
@@ -1,3 +1,28 @@
+2011-07-30 Oliver Hunt <[email protected]>
+
+ Simplify JSFunction creation for functions written in JS
+ https://bugs.webkit.org/show_bug.cgi?id=65422
+
+ Reviewed by Gavin Barraclough.
+
+ Remove hash lookups used to write name property and transition
+ function structure by caching the resultant structure and property
+ offset in JSGlobalObject. This doesn't impact performance, but
+ we can use this change to make other improvements later.
+
+ * runtime/Executable.cpp:
+ (JSC::FunctionExecutable::FunctionExecutable):
+ * runtime/Executable.h:
+ (JSC::ScriptExecutable::ScriptExecutable):
+ (JSC::FunctionExecutable::jsName):
+ * runtime/JSFunction.cpp:
+ (JSC::JSFunction::JSFunction):
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::reset):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::namedFunctionStructure):
+ (JSC::JSGlobalObject::functionNameOffset):
+
2011-08-02 Filip Pizlo <[email protected]>
JSC GC uses dummy cells to avoid having to remember which cells
Modified: trunk/Source/_javascript_Core/runtime/Executable.cpp (92249 => 92250)
--- trunk/Source/_javascript_Core/runtime/Executable.cpp 2011-08-03 00:04:06 UTC (rev 92249)
+++ trunk/Source/_javascript_Core/runtime/Executable.cpp 2011-08-03 00:41:11 UTC (rev 92250)
@@ -144,6 +144,7 @@
{
m_firstLine = firstLine;
m_lastLine = lastLine;
+ m_nameValue.set(globalData, this, jsString(&globalData, name.ustring()));
}
FunctionExecutable::FunctionExecutable(ExecState* exec, const Identifier& name, const SourceCode& source, bool forceUsesArguments, FunctionParameters* parameters, bool inStrictContext, int firstLine, int lastLine)
@@ -156,6 +157,7 @@
{
m_firstLine = firstLine;
m_lastLine = lastLine;
+ m_nameValue.set(exec->globalData(), this, jsString(&exec->globalData(), name.ustring()));
}
@@ -439,6 +441,8 @@
COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
ASSERT(structure()->typeInfo().overridesVisitChildren());
ScriptExecutable::visitChildren(visitor);
+ if (m_nameValue)
+ visitor.append(&m_nameValue);
if (m_codeBlockForCall)
m_codeBlockForCall->visitAggregate(visitor);
if (m_codeBlockForConstruct)
Modified: trunk/Source/_javascript_Core/runtime/Executable.h (92249 => 92250)
--- trunk/Source/_javascript_Core/runtime/Executable.h 2011-08-03 00:04:06 UTC (rev 92249)
+++ trunk/Source/_javascript_Core/runtime/Executable.h 2011-08-03 00:41:11 UTC (rev 92250)
@@ -226,7 +226,7 @@
{
#if ENABLE(CODEBLOCK_SAMPLING)
if (SamplingTool* sampler = globalData.interpreter->sampler())
- sampler->notifyOfScope(*globalData, this);
+ sampler->notifyOfScope(globalData, this);
#else
UNUSED_PARAM(globalData);
#endif
@@ -478,6 +478,7 @@
}
const Identifier& name() { return m_name; }
+ JSString* nameValue() const { return m_nameValue.get(); }
size_t parameterCount() const { return m_parameters->size(); }
unsigned capturedVariableCount() const { return m_numCapturedVariables; }
UString paramString() const;
@@ -509,6 +510,7 @@
OwnPtr<FunctionCodeBlock> m_codeBlockForCall;
OwnPtr<FunctionCodeBlock> m_codeBlockForConstruct;
Identifier m_name;
+ WriteBarrier<JSString> m_nameValue;
SharedSymbolTable* m_symbolTable;
};
Modified: trunk/Source/_javascript_Core/runtime/JSFunction.cpp (92249 => 92250)
--- trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2011-08-03 00:04:06 UTC (rev 92249)
+++ trunk/Source/_javascript_Core/runtime/JSFunction.cpp 2011-08-03 00:41:11 UTC (rev 92250)
@@ -90,8 +90,8 @@
, m_scopeChain(exec->globalData(), this, scopeChainNode)
{
ASSERT(inherits(&s_info));
- const Identifier& name = static_cast<FunctionExecutable*>(m_executable.get())->name();
- putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum);
+ setStructure(exec->globalData(), scopeChainNode->globalObject->namedFunctionStructure());
+ putDirectOffset(exec->globalData(), scopeChainNode->globalObject->functionNameOffset(), executable->nameValue());
}
JSFunction::~JSFunction()
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (92249 => 92250)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2011-08-03 00:04:06 UTC (rev 92249)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2011-08-03 00:41:11 UTC (rev 92250)
@@ -187,6 +187,7 @@
m_functionPrototype.set(exec->globalData(), this, FunctionPrototype::create(exec, this, FunctionPrototype::createStructure(exec->globalData(), jsNull()))); // The real prototype will be set once ObjectPrototype is created.
m_functionStructure.set(exec->globalData(), this, JSFunction::createStructure(exec->globalData(), m_functionPrototype.get()));
+ m_namedFunctionStructure.set(exec->globalData(), this, Structure::addPropertyTransition(exec->globalData(), m_functionStructure.get(), exec->globalData().propertyNames->name, DontDelete | ReadOnly | DontEnum, 0, m_functionNameOffset));
m_internalFunctionStructure.set(exec->globalData(), this, InternalFunction::createStructure(exec->globalData(), m_functionPrototype.get()));
JSFunction* callFunction = 0;
JSFunction* applyFunction = 0;
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (92249 => 92250)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2011-08-03 00:04:06 UTC (rev 92249)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2011-08-03 00:41:11 UTC (rev 92250)
@@ -116,6 +116,8 @@
WriteBarrier<Structure> m_nullPrototypeObjectStructure;
WriteBarrier<Structure> m_errorStructure;
WriteBarrier<Structure> m_functionStructure;
+ WriteBarrier<Structure> m_namedFunctionStructure;
+ size_t m_functionNameOffset;
WriteBarrier<Structure> m_numberObjectStructure;
WriteBarrier<Structure> m_regExpMatchesArrayStructure;
WriteBarrier<Structure> m_regExpStructure;
@@ -229,6 +231,8 @@
Structure* nullPrototypeObjectStructure() const { return m_nullPrototypeObjectStructure.get(); }
Structure* errorStructure() const { return m_errorStructure.get(); }
Structure* functionStructure() const { return m_functionStructure.get(); }
+ Structure* namedFunctionStructure() const { return m_namedFunctionStructure.get(); }
+ size_t functionNameOffset() const { return m_functionNameOffset; }
Structure* numberObjectStructure() const { return m_numberObjectStructure.get(); }
Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }