Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(844)

Unified Diff: src/parser.cc

Issue 115402: Reduced malloc/free operations in the parser. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/jump-target.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
===================================================================
--- src/parser.cc (revision 1968)
+++ src/parser.cc (working copy)
@@ -42,9 +42,50 @@
class ParserFactory;
class ParserLog;
class TemporaryScope;
+class Target;
+
template <typename T> class ZoneListWrapper;
+// PositionStack is used for on-stack allocation of token positions for
+// new expressions. Please look at ParseNewExpression.
+
+class PositionStack {
+ public:
+ PositionStack() : top_(NULL) {}
+ ~PositionStack() { }
+
+ class Element {
Kasper Lund 2009/05/15 13:37:11 Couldn't the entire Element class be private?
+ public:
+ Element(PositionStack* stack, int value) {
+ previous_ = stack->top();
+ value_ = value;
+ stack->set_top(this);
+ }
+ protected:
Kasper Lund 2009/05/15 13:37:11 How about a newline before protected: and private:
Kasper Lund 2009/05/15 13:37:11 Why do you have both private and protected? Do you
+ Element* previous() { return previous_; }
+ int value() { return value_; }
+ friend class PositionStack;
+ private:
+ Element* previous_;
+ int value_;
+ };
+
+ bool is_empty() { return top_ == NULL; }
+ int pop() {
+ ASSERT(!is_empty());
+ int result = top_->value();
+ top_ = top_->previous();
+ return result;
+ }
+ protected:
+ Element* top() { return top_; }
+ void set_top(Element* value) { top_ = value; }
+ private:
+ Element* top_;
+};
+
+
class Parser {
public:
Parser(Handle<Script> script, bool allow_natives_syntax,
@@ -93,7 +134,8 @@
TemporaryScope* temp_scope_;
Mode mode_;
- List<Node*>* target_stack_; // for break, continue statements
+
+ Target* target_stack_; // for break, continue statements
bool allow_natives_syntax_;
v8::Extension* extension_;
ParserFactory* factory_;
@@ -150,7 +192,8 @@
Expression* ParseLeftHandSideExpression(bool* ok);
Expression* ParseNewExpression(bool* ok);
Expression* ParseMemberExpression(bool* ok);
- Expression* ParseMemberWithNewPrefixesExpression(List<int>* new_prefixes,
+ Expression* ParseNewPrefix(PositionStack* stack, bool* ok);
+ Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
bool* ok);
Expression* ParsePrimaryExpression(bool* ok);
Expression* ParseArrayLiteral(bool* ok);
@@ -208,7 +251,7 @@
BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
- void RegisterTargetUse(BreakTarget* target, int index);
+ void RegisterTargetUse(BreakTarget* target, Target* stop);
// Create a number literal.
Literal* NewNumberLiteral(double value);
@@ -971,35 +1014,39 @@
class Target BASE_EMBEDDED {
public:
- Target(Parser* parser, Node* node) : parser_(parser) {
- parser_->target_stack_->Add(node);
+ Target(Parser* parser, Node* node)
+ : parser_(parser), node_(node), previous_(parser_->target_stack_) {
+ parser_->target_stack_ = this;
}
~Target() {
- parser_->target_stack_->RemoveLast();
+ parser_->target_stack_ = previous_;
}
+ Target* previous() { return previous_; }
+ Node* node() { return node_; }
+
private:
Parser* parser_;
+ Node* node_;
+ Target* previous_;
};
class TargetScope BASE_EMBEDDED {
public:
explicit TargetScope(Parser* parser)
- : parser_(parser), previous_(parser->target_stack_), stack_(0) {
- parser_->target_stack_ = &stack_;
+ : parser_(parser), previous_(parser->target_stack_) {
+ parser->target_stack_ = NULL;
}
~TargetScope() {
- ASSERT(stack_.is_empty());
parser_->target_stack_ = previous_;
}
private:
Parser* parser_;
- List<Node*>* previous_;
- List<Node*> stack_;
+ Target* previous_;
};
@@ -2792,7 +2839,8 @@
}
-Expression* Parser::ParseNewExpression(bool* ok) {
+
+Expression* Parser::ParseNewPrefix(PositionStack* stack, bool* ok) {
// NewExpression ::
// ('new')+ MemberExpression
@@ -2804,32 +2852,36 @@
// many we have parsed. This information is then passed on to the
// member expression parser, which is only allowed to match argument
// lists as long as it has 'new' prefixes left
- List<int> new_positions(4);
- while (peek() == Token::NEW) {
- Consume(Token::NEW);
- new_positions.Add(scanner().location().beg_pos);
+ Expect(Token::NEW, CHECK_OK);
+ PositionStack::Element pos(stack, scanner().location().beg_pos);
+
+ Expression* result;
+ if (peek() == Token::NEW) {
+ result = ParseNewPrefix(stack, CHECK_OK);
+ } else {
+ result = ParseMemberWithNewPrefixesExpression(stack, CHECK_OK);
}
- ASSERT(new_positions.length() > 0);
- Expression* result =
- ParseMemberWithNewPrefixesExpression(&new_positions, CHECK_OK);
- while (!new_positions.is_empty()) {
- int last = new_positions.RemoveLast();
- result = NEW(CallNew(result, new ZoneList<Expression*>(0), last));
+ if (!stack->is_empty()) {
+ result = NEW(CallNew(result, new ZoneList<Expression*>(0), stack->pop()));
}
return result;
}
+Expression* Parser::ParseNewExpression(bool* ok) {
+ PositionStack stack;
+ return ParseNewPrefix(&stack, ok);
+}
+
+
Expression* Parser::ParseMemberExpression(bool* ok) {
- static List<int> new_positions(0);
- return ParseMemberWithNewPrefixesExpression(&new_positions, ok);
+ return ParseMemberWithNewPrefixesExpression(NULL, ok);
}
-Expression* Parser::ParseMemberWithNewPrefixesExpression(
- List<int>* new_positions,
- bool* ok) {
+Expression* Parser::ParseMemberWithNewPrefixesExpression(PositionStack* stack,
+ bool* ok) {
// MemberExpression ::
// (PrimaryExpression | FunctionLiteral)
// ('[' Expression ']' | '.' Identifier | Arguments)*
@@ -2865,11 +2917,10 @@
break;
}
case Token::LPAREN: {
- if (new_positions->is_empty()) return result;
+ if ((stack == NULL) || stack->is_empty()) return result;
// Consume one of the new prefixes (already parsed).
ZoneList<Expression*>* args = ParseArguments(CHECK_OK);
- int last = new_positions->RemoveLast();
- result = NEW(CallNew(result, args, last));
+ result = NEW(CallNew(result, args, stack->pop()));
break;
}
default:
@@ -3548,8 +3599,8 @@
bool Parser::TargetStackContainsLabel(Handle<String> label) {
- for (int i = target_stack_->length(); i-- > 0;) {
- BreakableStatement* stat = target_stack_->at(i)->AsBreakableStatement();
+ for (Target* t = target_stack_; t != NULL; t = t->previous()) {
+ BreakableStatement* stat = t->node()->AsBreakableStatement();
if (stat != NULL && ContainsLabel(stat->labels(), label))
return true;
}
@@ -3559,13 +3610,12 @@
BreakableStatement* Parser::LookupBreakTarget(Handle<String> label, bool* ok) {
bool anonymous = label.is_null();
- for (int i = target_stack_->length(); i-- > 0;) {
- BreakableStatement* stat = target_stack_->at(i)->AsBreakableStatement();
+ for (Target* t = target_stack_; t != NULL; t = t->previous()) {
+ BreakableStatement* stat = t->node()->AsBreakableStatement();
if (stat == NULL) continue;
-
if ((anonymous && stat->is_target_for_anonymous()) ||
(!anonymous && ContainsLabel(stat->labels(), label))) {
- RegisterTargetUse(stat->break_target(), i);
+ RegisterTargetUse(stat->break_target(), t->previous());
return stat;
}
}
@@ -3576,13 +3626,13 @@
IterationStatement* Parser::LookupContinueTarget(Handle<String> label,
bool* ok) {
bool anonymous = label.is_null();
- for (int i = target_stack_->length(); i-- > 0;) {
- IterationStatement* stat = target_stack_->at(i)->AsIterationStatement();
+ for (Target* t = target_stack_; t != NULL; t = t->previous()) {
+ IterationStatement* stat = t->node()->AsIterationStatement();
if (stat == NULL) continue;
ASSERT(stat->is_target_for_anonymous());
if (anonymous || ContainsLabel(stat->labels(), label)) {
- RegisterTargetUse(stat->continue_target(), i);
+ RegisterTargetUse(stat->continue_target(), t->previous());
return stat;
}
}
@@ -3590,12 +3640,12 @@
}
-void Parser::RegisterTargetUse(BreakTarget* target, int index) {
- // Register that a break target found at the given index in the
+void Parser::RegisterTargetUse(BreakTarget* target, Target* stop) {
+ // Register that a break target found at the given stop in the
// target stack has been used from the top of the target stack. Add
// the break target to any TargetCollectors passed on the stack.
- for (int i = target_stack_->length(); i-- > index;) {
- TargetCollector* collector = target_stack_->at(i)->AsTargetCollector();
+ for (Target* t = target_stack_; t != stop; t = t->previous()) {
+ TargetCollector* collector = t->node()->AsTargetCollector();
if (collector != NULL) collector->AddTarget(target);
}
}
« no previous file with comments | « src/jump-target.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698