Title: [110039] trunk/Source/_javascript_Core
Revision
110039
Author
wi...@igalia.com
Date
2012-03-07 02:18:43 -0800 (Wed, 07 Mar 2012)

Log Message

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.

Modified Paths

Diff

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();

Modified: trunk/Source/_javascript_Core/parser/ParserArena.h (110038 => 110039)


--- trunk/Source/_javascript_Core/parser/ParserArena.h	2012-03-07 10:11:47 UTC (rev 110038)
+++ trunk/Source/_javascript_Core/parser/ParserArena.h	2012-03-07 10:18:43 UTC (rev 110039)
@@ -161,7 +161,12 @@
         bool isEmpty() const;
         JS_EXPORT_PRIVATE void reset();
 
-        IdentifierArena& identifierArena() { return *m_identifierArena; }
+        IdentifierArena& identifierArena()
+        {
+            if (UNLIKELY (!m_identifierArena))
+                m_identifierArena = adoptPtr(new IdentifierArena);
+            return *m_identifierArena;
+        }
 
     private:
         static const size_t freeablePoolSize = 8000;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to