Modified: trunk/Source/_javascript_Core/ChangeLog (110038 => 110039)
--- trunk/Source/_javascript_Core/ChangeLog 2012-03-07 10:11:47 UTC (rev 110038)
+++ trunk/Source/_javascript_Core/ChangeLog 2012-03-07 10:18:43 UTC (rev 110039)
@@ -1,3 +1,46 @@
+2012-03-07 Andy Wingo <wi...@igalia.com>
+
+ Parser: Inline ScopeNodeData into ScopeNode
+ https://bugs.webkit.org/show_bug.cgi?id=79776
+
+ Reviewed by Geoffrey Garen.
+
+ It used to be that some ScopeNode members were kept in a separate
+ structure because sometimes they wouldn't be needed, and
+ allocating a ParserArena was expensive. This patch makes
+ ParserArena lazily allocate its IdentifierArena, allowing the
+ members to be included directly, which is simpler and easier to
+ reason about.
+
+ * parser/ParserArena.cpp:
+ (JSC::ParserArena::ParserArena):
+ (JSC::ParserArena::reset):
+ (JSC::ParserArena::isEmpty):
+ * parser/ParserArena.h:
+ (JSC::ParserArena::identifierArena): Lazily allocate the
+ IdentifierArena.
+
+ * parser/Nodes.cpp:
+ (JSC::ScopeNode::ScopeNode):
+ (JSC::ScopeNode::singleStatement):
+ (JSC::ProgramNode::create):
+ (JSC::EvalNode::create):
+ (JSC::FunctionBodyNode::create):
+ * parser/Nodes.h:
+ (JSC::ScopeNode::destroyData):
+ (JSC::ScopeNode::needsActivationForMoreThanVariables):
+ (JSC::ScopeNode::needsActivation):
+ (JSC::ScopeNode::hasCapturedVariables):
+ (JSC::ScopeNode::capturedVariableCount):
+ (JSC::ScopeNode::captures):
+ (JSC::ScopeNode::varStack):
+ (JSC::ScopeNode::functionStack):
+ (JSC::ScopeNode::neededConstants):
+ (ScopeNode):
+ * bytecompiler/NodesCodegen.cpp:
+ (JSC::ScopeNode::emitStatementsBytecode): Inline ScopeNodeData
+ into ScopeNode. Adapt accessors.
+
2012-03-06 Eric Seidel <e...@webkit.org>
Make WTF public headers use fully-qualified include paths and remove ForwardingHeaders/wtf
Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (110038 => 110039)
--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2012-03-07 10:11:47 UTC (rev 110038)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp 2012-03-07 10:18:43 UTC (rev 110039)
@@ -2017,8 +2017,8 @@
inline void ScopeNode::emitStatementsBytecode(BytecodeGenerator& generator, RegisterID* dst)
{
- if (m_data->m_statements)
- m_data->m_statements->emitBytecode(generator, dst);
+ if (m_statements)
+ m_statements->emitBytecode(generator, dst);
}
// ------------------------------ ProgramNode -----------------------------
Modified: trunk/Source/_javascript_Core/parser/Nodes.cpp (110038 => 110039)
--- trunk/Source/_javascript_Core/parser/Nodes.cpp 2012-03-07 10:11:47 UTC (rev 110038)
+++ trunk/Source/_javascript_Core/parser/Nodes.cpp 2012-03-07 10:18:43 UTC (rev 110039)
@@ -73,41 +73,36 @@
return size == 1 ? m_statements[0] : 0;
}
-// -----------------------------ScopeNodeData ---------------------------
-
-ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, int numConstants)
- : m_numConstants(numConstants)
- , m_statements(statements)
-{
- m_arena.swap(arena);
- if (varStack)
- m_varStack.swap(*varStack);
- if (funcStack)
- m_functionStack.swap(*funcStack);
- m_capturedVariables.swap(capturedVariables);
-}
-
// ------------------------------ ScopeNode -----------------------------
ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, bool inStrictContext)
: StatementNode(lineNumber)
, ParserArenaRefCounted(globalData)
, m_features(inStrictContext ? StrictModeFeature : NoFeatures)
+ , m_numConstants(0)
+ , m_statements(0)
{
}
ScopeNode::ScopeNode(JSGlobalData* globalData, int lineNumber, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
: StatementNode(lineNumber)
, ParserArenaRefCounted(globalData)
- , m_data(adoptPtr(new ScopeNodeData(*globalData->parserArena, children, varStack, funcStack, capturedVariables, numConstants)))
, m_features(features)
, m_source(source)
+ , m_numConstants(numConstants)
+ , m_statements(children)
{
+ m_arena.swap(*globalData->parserArena);
+ if (varStack)
+ m_varStack.swap(*varStack);
+ if (funcStack)
+ m_functionStack.swap(*funcStack);
+ m_capturedVariables.swap(capturedVariables);
}
StatementNode* ScopeNode::singleStatement() const
{
- return m_data->m_statements ? m_data->m_statements->singleStatement() : 0;
+ return m_statements ? m_statements->singleStatement() : 0;
}
// ------------------------------ ProgramNode -----------------------------
@@ -121,9 +116,9 @@
{
RefPtr<ProgramNode> node = new ProgramNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
- ASSERT(node->data()->m_arena.last() == node);
- node->data()->m_arena.removeLast();
- ASSERT(!node->data()->m_arena.contains(node.get()));
+ ASSERT(node->m_arena.last() == node);
+ node->m_arena.removeLast();
+ ASSERT(!node->m_arena.contains(node.get()));
return node.release();
}
@@ -139,9 +134,9 @@
{
RefPtr<EvalNode> node = new EvalNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, source, features, numConstants);
- ASSERT(node->data()->m_arena.last() == node);
- node->data()->m_arena.removeLast();
- ASSERT(!node->data()->m_arena.contains(node.get()));
+ ASSERT(node->m_arena.last() == node);
+ node->m_arena.removeLast();
+ ASSERT(!node->m_arena.contains(node.get()));
return node.release();
}
@@ -186,9 +181,9 @@
{
RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, lineNumber, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
- ASSERT(node->data()->m_arena.last() == node);
- node->data()->m_arena.removeLast();
- ASSERT(!node->data()->m_arena.contains(node.get()));
+ ASSERT(node->m_arena.last() == node);
+ node->m_arena.removeLast();
+ ASSERT(!node->m_arena.contains(node.get()));
return node.release();
}
Modified: trunk/Source/_javascript_Core/parser/Nodes.h (110038 => 110039)
--- trunk/Source/_javascript_Core/parser/Nodes.h 2012-03-07 10:11:47 UTC (rev 110038)
+++ trunk/Source/_javascript_Core/parser/Nodes.h 2012-03-07 10:18:43 UTC (rev 110039)
@@ -1378,22 +1378,6 @@
ParameterNode* m_next;
};
- struct ScopeNodeData {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- typedef DeclarationStacks::VarStack VarStack;
- typedef DeclarationStacks::FunctionStack FunctionStack;
-
- ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, int numConstants);
-
- ParserArena m_arena;
- VarStack m_varStack;
- FunctionStack m_functionStack;
- int m_numConstants;
- SourceElements* m_statements;
- IdentifierSet m_capturedVariables;
- };
-
class ScopeNode : public StatementNode, public ParserArenaRefCounted {
public:
typedef DeclarationStacks::VarStack VarStack;
@@ -1404,8 +1388,14 @@
using ParserArenaRefCounted::operator new;
- ScopeNodeData* data() const { return m_data.get(); }
- void destroyData() { m_data.clear(); }
+ void destroyData()
+ {
+ m_arena.reset();
+ m_varStack.clear();
+ m_functionStack.clear();
+ m_statements = 0;
+ m_capturedVariables.clear();
+ }
const SourceCode& source() const { return m_source; }
const UString& sourceURL() const { return m_source.provider()->url(); }
@@ -1419,21 +1409,20 @@
bool isStrictMode() const { return m_features & StrictModeFeature; }
void setUsesArguments() { m_features |= ArgumentsFeature; }
bool usesThis() const { return m_features & ThisFeature; }
- bool needsActivationForMoreThanVariables() const { ASSERT(m_data); return m_features & (EvalFeature | WithFeature | CatchFeature); }
- bool needsActivation() const { ASSERT(m_data); return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
- bool hasCapturedVariables() const { return !!m_data->m_capturedVariables.size(); }
- size_t capturedVariableCount() const { return m_data->m_capturedVariables.size(); }
- bool captures(const Identifier& ident) { return m_data->m_capturedVariables.contains(ident.impl()); }
+ bool needsActivationForMoreThanVariables() const { return m_features & (EvalFeature | WithFeature | CatchFeature); }
+ bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
+ bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
+ size_t capturedVariableCount() const { return m_capturedVariables.size(); }
+ bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
- VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
- FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
+ VarStack& varStack() { return m_varStack; }
+ FunctionStack& functionStack() { return m_functionStack; }
int neededConstants()
{
- ASSERT(m_data);
// We may need 2 more constants than the count given by the parser,
// because of the various uses of jsUndefined() and jsNull().
- return m_data->m_numConstants + 2;
+ return m_numConstants + 2;
}
StatementNode* singleStatement() const;
@@ -1442,11 +1431,16 @@
protected:
void setSource(const SourceCode& source) { m_source = source; }
+ ParserArena m_arena;
private:
- OwnPtr<ScopeNodeData> m_data;
CodeFeatures m_features;
SourceCode m_source;
+ VarStack m_varStack;
+ FunctionStack m_functionStack;
+ int m_numConstants;
+ SourceElements* m_statements;
+ IdentifierSet m_capturedVariables;
};
class ProgramNode : public ScopeNode {
Modified: trunk/Source/_javascript_Core/parser/ParserArena.cpp (110038 => 110039)
--- trunk/Source/_javascript_Core/parser/ParserArena.cpp 2012-03-07 10:11:47 UTC (rev 110038)
+++ trunk/Source/_javascript_Core/parser/ParserArena.cpp 2012-03-07 10:18:43 UTC (rev 110039)
@@ -34,7 +34,6 @@
ParserArena::ParserArena()
: m_freeableMemory(0)
, m_freeablePoolEnd(0)
- , m_identifierArena(adoptPtr(new IdentifierArena))
{
}
@@ -88,7 +87,8 @@
m_freeableMemory = 0;
m_freeablePoolEnd = 0;
- m_identifierArena->clear();
+ if (m_identifierArena)
+ m_identifierArena->clear();
m_freeablePools.clear();
m_deletableObjects.clear();
m_refCountedObjects.clear();
@@ -108,7 +108,7 @@
bool ParserArena::isEmpty() const
{
return !m_freeablePoolEnd
- && m_identifierArena->isEmpty()
+ && (!m_identifierArena || m_identifierArena->isEmpty())
&& m_freeablePools.isEmpty()
&& m_deletableObjects.isEmpty()
&& m_refCountedObjects.isEmpty();