Changeset 38635 in webkit for trunk/JavaScriptCore/parser/Nodes.h


Ignore:
Timestamp:
Nov 20, 2008, 3:23:59 PM (17 years ago)
Author:
[email protected]
Message:

2008-11-20 Sam Weinig <[email protected]>

Reviewed by Darin Adler.

Patch for https://bugs.webkit.org/show_bug.cgi?id=22385
<rdar://problem/6390179>
Lazily reparse FunctionBodyNodes on first execution.

  • Saves 57MB on Membuster head.
  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::generate): Remove vector shrinking since this is now handled by destroying the ScopeNodeData after generation.
  • parser/Grammar.y: Add alternate NoNode version of the grammar that does not create nodes. This is used to lazily create FunctionBodyNodes on first execution.
  • parser/Lexer.cpp: (JSC::Lexer::setCode): Fix bug where on reparse, the Lexer was confused about what position and length meant. Position is the current position in the original data buffer (important for getting correct line/column information) and length the end offset in the original buffer.
  • parser/Lexer.h: (JSC::Lexer::sourceCode): Positions are relative to the beginning of the buffer.
  • parser/Nodes.cpp: (JSC::ScopeNodeData::ScopeNodeData): Move initialization of ScopeNode data here. (JSC::ScopeNode::ScopeNode): Add constructor that only sets the JSGlobalData for FunctionBodyNode stubs. (JSC::ScopeNode::~ScopeNode): Release m_children now that we don't inherit from BlockNode. (JSC::ScopeNode::releaseNodes): Ditto. (JSC::EvalNode::generateBytecode): Only shrink m_children, as we need to keep around the rest of the data. (JSC::FunctionBodyNode::FunctionBodyNode): Add constructor that only sets the JSGlobalData. (JSC::FunctionBodyNode::create): Ditto. (JSC::FunctionBodyNode::generateBytecode): If we don't have the data, do a reparse to construct it. Then after generation, destroy the data. (JSC::ProgramNode::generateBytecode): After generation, destroy the AST data.
  • parser/Nodes.h: (JSC::ExpressionNode::): Add isFuncExprNode for FunctionConstructor. (JSC::StatementNode::): Add isExprStatementNode for FunctionConstructor. (JSC::ExprStatementNode::): Ditto. (JSC::ExprStatementNode::expr): Add accessor for FunctionConstructor. (JSC::FuncExprNode::): Add isFuncExprNode for FunctionConstructor

(JSC::ScopeNode::adoptData): Adopts a ScopeNodeData.
(JSC::ScopeNode::data): Accessor for ScopeNodeData.
(JSC::ScopeNode::destroyData): Deletes the ScopeNodeData.
(JSC::ScopeNode::setFeatures): Added.
(JSC::ScopeNode::varStack): Added assert.
(JSC::ScopeNode::functionStack): Ditto.
(JSC::ScopeNode::children): Ditto.
(JSC::ScopeNode::neededConstants): Ditto.
Factor m_varStack, m_functionStack, m_children and m_numConstants into ScopeNodeData.

  • parser/Parser.cpp: (JSC::Parser::reparse): Reparse the SourceCode in the FunctionBodyNode and set set up the ScopeNodeData for it.
  • parser/Parser.h:
  • parser/SourceCode.h: (JSC::SourceCode::endOffset): Added for use in the lexer.
  • runtime/FunctionConstructor.cpp: (JSC::getFunctionBody): Assuming a ProgramNode with one FunctionExpression in it, get the FunctionBodyNode. Any issues signifies a parse failure in constructFunction. (JSC::constructFunction): Make parsing functions in the form new Function(""), easier by concatenating the strings together (with some glue) and parsing the function expression as a ProgramNode from which we can receive the FunctionBodyNode. This has the added benefit of not having special parsing code for the arguments and lazily constructing the FunctionBodyNode's AST on first execution.
  • runtime/Identifier.h: (JSC::operator!=): Added.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/parser/Nodes.h

    r38473 r38635  
    171171        virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return false; }
    172172        virtual bool isDotAccessorNode() const JSC_FAST_CALL { return false; }
     173        virtual bool isFuncExprNode() const JSC_FAST_CALL { return false; }
    173174
    174175        virtual ExpressionNode* stripUnaryPlus() { return this; }
     
    192193        virtual bool isEmptyStatement() const JSC_FAST_CALL { return false; }
    193194        virtual bool isReturnNode() const JSC_FAST_CALL { return false; }
     195        virtual bool isExprStatement() const JSC_FAST_CALL { return false; }
    194196
    195197        virtual bool isBlock() const JSC_FAST_CALL { return false; }
     
    17431745        }
    17441746
    1745         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
     1747        virtual bool isExprStatement() const JSC_FAST_CALL { return true; }
     1748
     1749        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
     1750
     1751        ExpressionNode* expr() const { return m_expr.get(); }
    17461752
    17471753    private:
     
    20572063    };
    20582064
    2059     class ScopeNode : public BlockNode {
    2060     public:
     2065    struct ScopeNodeData {
    20612066        typedef DeclarationStacks::VarStack VarStack;
    20622067        typedef DeclarationStacks::FunctionStack FunctionStack;
    20632068
     2069        ScopeNodeData(SourceElements*, VarStack*, FunctionStack*, int numConstants);
     2070
     2071        VarStack m_varStack;
     2072        FunctionStack m_functionStack;
     2073        int m_numConstants;
     2074        StatementVector m_children;
     2075    };
     2076
     2077    class ScopeNode : public StatementNode {
     2078    public:
     2079        typedef DeclarationStacks::VarStack VarStack;
     2080        typedef DeclarationStacks::FunctionStack FunctionStack;
     2081
     2082        ScopeNode(JSGlobalData*) JSC_FAST_CALL;
    20642083        ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL;
     2084        virtual ~ScopeNode();
     2085        virtual void releaseNodes(NodeReleaser&);
     2086
     2087        void adoptData(std::auto_ptr<ScopeNodeData> data) { m_data.adopt(data); }
     2088        ScopeNodeData* data() const { return m_data.get(); }
     2089        void destroyData() { m_data.clear(); }
    20652090
    20662091        const SourceCode& source() const { return m_source; }
     
    20682093        intptr_t sourceID() const { return m_source.provider()->asID(); }
    20692094
     2095        void setFeatures(CodeFeatures features) { m_features = features; }
    20702096        bool usesEval() const { return m_features & EvalFeature; }
    20712097        bool usesArguments() const { return m_features & ArgumentsFeature; }
     
    20742100        bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
    20752101
    2076         VarStack& varStack() { return m_varStack; }
    2077         FunctionStack& functionStack() { return m_functionStack; }
     2102        VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
     2103        FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
     2104
     2105        StatementVector& children() { ASSERT(m_data); return m_data->m_children; }
    20782106
    20792107        int neededConstants()
    20802108        {
     2109            ASSERT(m_data);
    20812110            // We may need 2 more constants than the count given by the parser,
    20822111            // because of the various uses of jsUndefined() and jsNull().
    2083             return m_numConstants + 2;
     2112            return m_data->m_numConstants + 2;
    20842113        }
    20852114
     
    20872116        void setSource(const SourceCode& source) { m_source = source; }
    20882117
    2089         VarStack m_varStack;
    2090         FunctionStack m_functionStack;
    2091 
    2092     private:
     2118    private:
     2119        OwnPtr<ScopeNodeData> m_data;
     2120        CodeFeatures m_features;
    20932121        SourceCode m_source;
    2094         CodeFeatures m_features;
    2095         int m_numConstants;
    20962122    };
    20972123
     
    21422168        friend class JIT;
    21432169    public:
     2170        static FunctionBodyNode* create(JSGlobalData*) JSC_FAST_CALL;
    21442171        static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
    2145         static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL;
    2146         ~FunctionBodyNode();
     2172        virtual ~FunctionBodyNode();
    21472173
    21482174        const Identifier* parameters() const JSC_FAST_CALL { return m_parameters; }
     
    21942220
    21952221    private:
     2222        FunctionBodyNode(JSGlobalData*) JSC_FAST_CALL;
    21962223        FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
    21972224
     
    22172244        virtual ~FuncExprNode();
    22182245        virtual void releaseNodes(NodeReleaser&);
     2246
     2247        virtual bool isFuncExprNode() const JSC_FAST_CALL { return true; }
    22192248
    22202249        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
Note: See TracChangeset for help on using the changeset viewer.