source: webkit/trunk/JavaScriptCore/parser/Nodes.cpp@ 67583

Last change on this file since 67583 was 67583, checked in by [email protected], 15 years ago

2010-09-15 Oliver Hunt <[email protected]>

Reviewed by Geoffrey Garen.

Use free variable analysis to improve activation performance
https://bugs.webkit.org/show_bug.cgi?id=45837

Adds free and captured variable tracking to the JS parser. This
allows us to avoid construction of an activation object in some
cases. Future patches will make more use of this information to
improve those cases where activations are still needed.

  • parser/ASTBuilder.h:
  • parser/JSParser.cpp: (JSC::JSParser::Scope::Scope): (JSC::JSParser::Scope::declareVariable): (JSC::JSParser::Scope::useVariable): (JSC::JSParser::Scope::collectFreeVariables): (JSC::JSParser::Scope::capturedVariables): (JSC::JSParser::ScopeRef::ScopeRef): (JSC::JSParser::ScopeRef::operator->): (JSC::JSParser::ScopeRef::index): (JSC::JSParser::currentScope): (JSC::JSParser::pushScope): (JSC::JSParser::popScope): (JSC::JSParser::parseProgram): (JSC::JSParser::parseVarDeclarationList): (JSC::JSParser::parseConstDeclarationList): (JSC::JSParser::parseTryStatement): (JSC::JSParser::parseFormalParameters): (JSC::JSParser::parseFunctionInfo): (JSC::JSParser::parseFunctionDeclaration): (JSC::JSParser::parsePrimaryExpression):
  • parser/Nodes.cpp: (JSC::ScopeNodeData::ScopeNodeData): (JSC::ScopeNode::ScopeNode): (JSC::ProgramNode::ProgramNode): (JSC::ProgramNode::create): (JSC::EvalNode::EvalNode): (JSC::EvalNode::create): (JSC::FunctionBodyNode::FunctionBodyNode): (JSC::FunctionBodyNode::create):
  • parser/Nodes.h: (JSC::ScopeNode::needsActivation): (JSC::ScopeNode::hasCapturedVariables):
  • parser/Parser.cpp: (JSC::Parser::didFinishParsing):
  • parser/Parser.h: (JSC::Parser::parse):
  • parser/SyntaxChecker.h:
  • runtime/Executable.cpp: (JSC::EvalExecutable::compileInternal): (JSC::ProgramExecutable::compileInternal): (JSC::FunctionExecutable::compileForCallInternal): (JSC::FunctionExecutable::compileForConstructInternal):
  • runtime/Executable.h: (JSC::ScriptExecutable::needsActivation): (JSC::ScriptExecutable::recordParse):
  • Property svn:eol-style set to native
File size: 7.3 KB
Line 
1/*
2* Copyright (C) 1999-2002 Harri Porten ([email protected])
3* Copyright (C) 2001 Peter Kelly ([email protected])
4* Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5* Copyright (C) 2007 Cameron Zwarich ([email protected])
6* Copyright (C) 2007 Maks Orlovich
7* Copyright (C) 2007 Eric Seidel <[email protected]>
8*
9* This library is free software; you can redistribute it and/or
10* modify it under the terms of the GNU Library General Public
11* License as published by the Free Software Foundation; either
12* version 2 of the License, or (at your option) any later version.
13*
14* This library is distributed in the hope that it will be useful,
15* but WITHOUT ANY WARRANTY; without even the implied warranty of
16* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17* Library General Public License for more details.
18*
19* You should have received a copy of the GNU Library General Public License
20* along with this library; see the file COPYING.LIB. If not, write to
21* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22* Boston, MA 02110-1301, USA.
23*
24*/
25
26#include "config.h"
27#include "Nodes.h"
28#include "NodeConstructors.h"
29
30#include "BytecodeGenerator.h"
31#include "CallFrame.h"
32#include "Debugger.h"
33#include "JIT.h"
34#include "JSFunction.h"
35#include "JSGlobalObject.h"
36#include "JSStaticScopeObject.h"
37#include "LabelScope.h"
38#include "Lexer.h"
39#include "Operations.h"
40#include "Parser.h"
41#include "PropertyNameArray.h"
42#include "RegExpObject.h"
43#include "SamplingTool.h"
44#include <wtf/Assertions.h>
45#include <wtf/RefCountedLeakCounter.h>
46#include <wtf/Threading.h>
47
48using namespace WTF;
49
50namespace JSC {
51
52
53// ------------------------------ StatementNode --------------------------------
54
55void StatementNode::setLoc(int firstLine, int lastLine)
56{
57 m_line = firstLine;
58 m_lastLine = lastLine;
59}
60
61// ------------------------------ SourceElements --------------------------------
62
63void SourceElements::append(StatementNode* statement)
64{
65 if (statement->isEmptyStatement())
66 return;
67 m_statements.append(statement);
68}
69
70StatementNode* SourceElements::singleStatement() const
71{
72 size_t size = m_statements.size();
73 return size == 1 ? m_statements[0] : 0;
74}
75
76// -----------------------------ScopeNodeData ---------------------------
77
78ScopeNodeData::ScopeNodeData(ParserArena& arena, SourceElements* statements, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, int numConstants)
79 : m_numConstants(numConstants)
80 , m_statements(statements)
81{
82 m_arena.swap(arena);
83 if (varStack)
84 m_varStack.swap(*varStack);
85 if (funcStack)
86 m_functionStack.swap(*funcStack);
87 m_capturedVariables.swap(capturedVariables);
88}
89
90// ------------------------------ ScopeNode -----------------------------
91
92ScopeNode::ScopeNode(JSGlobalData* globalData)
93 : StatementNode(globalData)
94 , ParserArenaRefCounted(globalData)
95 , m_features(NoFeatures)
96{
97}
98
99ScopeNode::ScopeNode(JSGlobalData* globalData, const SourceCode& source, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, CodeFeatures features, int numConstants)
100 : StatementNode(globalData)
101 , ParserArenaRefCounted(globalData)
102 , m_data(adoptPtr(new ScopeNodeData(globalData->parser->arena(), children, varStack, funcStack, capturedVariables, numConstants)))
103 , m_features(features)
104 , m_source(source)
105{
106}
107
108StatementNode* ScopeNode::singleStatement() const
109{
110 return m_data->m_statements ? m_data->m_statements->singleStatement() : 0;
111}
112
113// ------------------------------ ProgramNode -----------------------------
114
115inline ProgramNode::ProgramNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
116 : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants)
117{
118}
119
120PassRefPtr<ProgramNode> ProgramNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
121{
122 RefPtr<ProgramNode> node = new ProgramNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants);
123
124 ASSERT(node->data()->m_arena.last() == node);
125 node->data()->m_arena.removeLast();
126 ASSERT(!node->data()->m_arena.contains(node.get()));
127
128 return node.release();
129}
130
131// ------------------------------ EvalNode -----------------------------
132
133inline EvalNode::EvalNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
134 : ScopeNode(globalData, source, children, varStack, funcStack, capturedVariables, features, numConstants)
135{
136}
137
138PassRefPtr<EvalNode> EvalNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& source, CodeFeatures features, int numConstants)
139{
140 RefPtr<EvalNode> node = new EvalNode(globalData, children, varStack, funcStack, capturedVariables, source, features, numConstants);
141
142 ASSERT(node->data()->m_arena.last() == node);
143 node->data()->m_arena.removeLast();
144 ASSERT(!node->data()->m_arena.contains(node.get()));
145
146 return node.release();
147}
148
149// ------------------------------ FunctionBodyNode -----------------------------
150
151FunctionParameters::FunctionParameters(ParameterNode* firstParameter)
152{
153 for (ParameterNode* parameter = firstParameter; parameter; parameter = parameter->nextParam())
154 append(parameter->ident());
155}
156
157inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData)
158 : ScopeNode(globalData)
159{
160}
161
162inline FunctionBodyNode::FunctionBodyNode(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
163 : ScopeNode(globalData, sourceCode, children, varStack, funcStack, capturedVariables, features, numConstants)
164{
165}
166
167void FunctionBodyNode::finishParsing(const SourceCode& source, ParameterNode* firstParameter, const Identifier& ident)
168{
169 setSource(source);
170 finishParsing(FunctionParameters::create(firstParameter), ident);
171}
172
173void FunctionBodyNode::finishParsing(PassRefPtr<FunctionParameters> parameters, const Identifier& ident)
174{
175 ASSERT(!source().isNull());
176 m_parameters = parameters;
177 m_ident = ident;
178}
179
180FunctionBodyNode* FunctionBodyNode::create(JSGlobalData* globalData)
181{
182 return new FunctionBodyNode(globalData);
183}
184
185PassRefPtr<FunctionBodyNode> FunctionBodyNode::create(JSGlobalData* globalData, SourceElements* children, VarStack* varStack, FunctionStack* funcStack, IdentifierSet& capturedVariables, const SourceCode& sourceCode, CodeFeatures features, int numConstants)
186{
187 RefPtr<FunctionBodyNode> node = new FunctionBodyNode(globalData, children, varStack, funcStack, capturedVariables, sourceCode, features, numConstants);
188
189 ASSERT(node->data()->m_arena.last() == node);
190 node->data()->m_arena.removeLast();
191 ASSERT(!node->data()->m_arena.contains(node.get()));
192
193 return node.release();
194}
195
196} // namespace JSC
Note: See TracBrowser for help on using the repository browser.