Revision: 9933
Author: [email protected]
Date: Wed Nov 9 05:54:26 2011
Log: A small collection of cleanup in the parser and AST.
* Remove a couple of unused fields from the FunctionLiteral, ensure that all
the bools are packed.
* Rename SaveScope and LexicalScope in the parser.
* Use an enum to generate the numbers 0..N and the dependent count, rather
than static const ints. This is simpler to extend (coming in a future
change).
[email protected],[email protected]
BUG=
TEST=
Review URL: http://codereview.chromium.org/8505012
http://code.google.com/p/v8/source/detail?r=9933
Modified:
/branches/bleeding_edge/src/ast.h
/branches/bleeding_edge/src/compiler.cc
/branches/bleeding_edge/src/liveedit.cc
/branches/bleeding_edge/src/parser.cc
/branches/bleeding_edge/src/parser.h
=======================================
--- /branches/bleeding_edge/src/ast.h Wed Nov 9 03:32:54 2011
+++ /branches/bleeding_edge/src/ast.h Wed Nov 9 05:54:26 2011
@@ -440,7 +440,6 @@
IterationStatement(Isolate* isolate, ZoneStringList* labels)
: BreakableStatement(isolate, labels, TARGET_FOR_ANONYMOUS),
body_(NULL),
- continue_target_(),
osr_entry_id_(GetNextId(isolate)) {
}
@@ -1647,25 +1646,26 @@
int expected_property_count,
bool has_only_simple_this_property_assignments,
Handle<FixedArray> this_property_assignments,
- int num_parameters,
+ int parameter_count,
Type type,
bool has_duplicate_parameters)
: Expression(isolate),
name_(name),
scope_(scope),
body_(body),
+ this_property_assignments_(this_property_assignments),
+ inferred_name_(isolate->factory()->empty_string()),
materialized_literal_count_(materialized_literal_count),
expected_property_count_(expected_property_count),
- has_only_simple_this_property_assignments_(
- has_only_simple_this_property_assignments),
- this_property_assignments_(this_property_assignments),
- num_parameters_(num_parameters),
- function_token_position_(RelocInfo::kNoPosition),
- inferred_name_(HEAP->empty_string()),
- is_expression_(type != DECLARATION),
- is_anonymous_(type == ANONYMOUS_EXPRESSION),
- pretenure_(false),
- has_duplicate_parameters_(has_duplicate_parameters) {
+ parameter_count_(parameter_count),
+ function_token_position_(RelocInfo::kNoPosition) {
+ bitfield_ =
+ HasOnlySimpleThisPropertyAssignments::encode(
+ has_only_simple_this_property_assignments) |
+ IsExpression::encode(type != DECLARATION) |
+ IsAnonymous::encode(type == ANONYMOUS_EXPRESSION) |
+ Pretenure::encode(false) |
+ HasDuplicateParameters::encode(has_duplicate_parameters);
}
DECLARE_NODE_TYPE(FunctionLiteral)
@@ -1677,20 +1677,20 @@
int function_token_position() const { return function_token_position_; }
int start_position() const;
int end_position() const;
- bool is_expression() const { return is_expression_; }
- bool is_anonymous() const { return is_anonymous_; }
+ bool is_expression() const { return IsExpression::decode(bitfield_); }
+ bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
bool strict_mode() const { return strict_mode_flag() == kStrictMode; }
StrictModeFlag strict_mode_flag() const;
int materialized_literal_count() { return materialized_literal_count_; }
int expected_property_count() { return expected_property_count_; }
bool has_only_simple_this_property_assignments() {
- return has_only_simple_this_property_assignments_;
+ return HasOnlySimpleThisPropertyAssignments::decode(bitfield_);
}
Handle<FixedArray> this_property_assignments() {
return this_property_assignments_;
}
- int num_parameters() { return num_parameters_; }
+ int parameter_count() { return parameter_count_; }
bool AllowsLazyCompilation();
@@ -1704,29 +1704,32 @@
inferred_name_ = inferred_name;
}
- bool pretenure() { return pretenure_; }
- void set_pretenure(bool value) { pretenure_ = value; }
+ bool pretenure() { return Pretenure::decode(bitfield_); }
+ void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
virtual bool IsInlineable() const;
- bool has_duplicate_parameters() { return has_duplicate_parameters_; }
+ bool has_duplicate_parameters() {
+ return HasDuplicateParameters::decode(bitfield_);
+ }
private:
Handle<String> name_;
Scope* scope_;
ZoneList<Statement*>* body_;
+ Handle<FixedArray> this_property_assignments_;
+ Handle<String> inferred_name_;
+
int materialized_literal_count_;
int expected_property_count_;
- bool has_only_simple_this_property_assignments_;
- Handle<FixedArray> this_property_assignments_;
- int num_parameters_;
- int start_position_;
- int end_position_;
+ int parameter_count_;
int function_token_position_;
- Handle<String> inferred_name_;
- bool is_expression_;
- bool is_anonymous_;
- bool pretenure_;
- bool has_duplicate_parameters_;
+
+ unsigned bitfield_;
+ class HasOnlySimpleThisPropertyAssignments: public BitField<bool, 0, 1>
{};
+ class IsExpression: public BitField<bool, 1, 1> {};
+ class IsAnonymous: public BitField<bool, 2, 1> {};
+ class Pretenure: public BitField<bool, 3, 1> {};
+ class HasDuplicateParameters: public BitField<bool, 4, 1> {};
};
=======================================
--- /branches/bleeding_edge/src/compiler.cc Thu Nov 3 03:36:55 2011
+++ /branches/bleeding_edge/src/compiler.cc Wed Nov 9 05:54:26 2011
@@ -734,8 +734,8 @@
FunctionLiteral* lit,
bool is_toplevel,
Handle<Script> script) {
- function_info->set_length(lit->num_parameters());
- function_info->set_formal_parameter_count(lit->num_parameters());
+ function_info->set_length(lit->parameter_count());
+ function_info->set_formal_parameter_count(lit->parameter_count());
function_info->set_script(*script);
function_info->set_function_token_position(lit->function_token_position());
function_info->set_start_position(lit->start_position());
=======================================
--- /branches/bleeding_edge/src/liveedit.cc Thu Nov 3 07:50:19 2011
+++ /branches/bleeding_edge/src/liveedit.cc Wed Nov 9 05:54:26 2011
@@ -797,7 +797,7 @@
HandleScope scope;
FunctionInfoWrapper info = FunctionInfoWrapper::Create();
info.SetInitialProperties(fun->name(), fun->start_position(),
- fun->end_position(), fun->num_parameters(),
+ fun->end_position(), fun->parameter_count(),
current_parent_index_);
current_parent_index_ = len_;
SetElementNonStrict(result_, len_, info.GetJSArray());
=======================================
--- /branches/bleeding_edge/src/parser.cc Wed Nov 9 03:32:54 2011
+++ /branches/bleeding_edge/src/parser.cc Wed Nov 9 05:54:26 2011
@@ -459,44 +459,39 @@
//
----------------------------------------------------------------------------
-// LexicalScope and SaveScope are stack allocated support classes to
facilitate
-// anipulation of the Parser's scope stack. The constructor sets the
parser's
-// top scope to the incoming scope, and the destructor resets it.
Additionally,
-// LexicalScope stores transient information used during parsing.
-
-
-class SaveScope BASE_EMBEDDED {
+// FunctionState and BlockState together implement the parser's scope
stack.
+// The parser's current scope is in top_scope_. The BlockState and
+// FunctionState constructors push on the scope stack and the destructors
+// pop. They are also used to hold the parser's per-function and per-block
+// state.
+
+class Parser::BlockState BASE_EMBEDDED {
public:
- SaveScope(Parser* parser, Scope* scope)
+ BlockState(Parser* parser, Scope* scope)
: parser_(parser),
- previous_top_scope_(parser->top_scope_) {
+ outer_scope_(parser->top_scope_) {
parser->top_scope_ = scope;
}
- ~SaveScope() {
- parser_->top_scope_ = previous_top_scope_;
- }
+ ~BlockState() { parser_->top_scope_ = outer_scope_; }
private:
- // Bookkeeping
Parser* parser_;
- // Previous values
- Scope* previous_top_scope_;
+ Scope* outer_scope_;
};
-class LexicalScope BASE_EMBEDDED {
+class Parser::FunctionState BASE_EMBEDDED {
public:
- LexicalScope(Parser* parser, Scope* scope, Isolate* isolate);
- ~LexicalScope();
+ FunctionState(Parser* parser, Scope* scope, Isolate* isolate);
+ ~FunctionState();
int NextMaterializedLiteralIndex() {
- int next_index =
- materialized_literal_count_ + JSFunction::kLiteralsPrefixSize;
- materialized_literal_count_++;
- return next_index;
- }
- int materialized_literal_count() { return materialized_literal_count_; }
+ return next_materialized_literal_index_++;
+ }
+ int materialized_literal_count() {
+ return next_materialized_literal_index_ -
JSFunction::kLiteralsPrefixSize;
+ }
void SetThisPropertyAssignmentInfo(
bool only_simple_this_property_assignments,
@@ -516,10 +511,10 @@
int expected_property_count() { return expected_property_count_; }
private:
- // Captures the number of literals that need materialization in the
- // function. Includes regexp literals, and boilerplate for object
- // and array literals.
- int materialized_literal_count_;
+ // Used to assign an index to each literal that needs materialization in
+ // the function. Includes regexp literals, and boilerplate for object
and
+ // array literals.
+ int next_materialized_literal_index_;
// Properties count estimation.
int expected_property_count_;
@@ -529,34 +524,34 @@
bool only_simple_this_property_assignments_;
Handle<FixedArray> this_property_assignments_;
- // Bookkeeping
Parser* parser_;
- // Previous values
- LexicalScope* lexical_scope_parent_;
- Scope* previous_scope_;
- unsigned previous_ast_node_id_;
+ FunctionState* outer_function_state_;
+ Scope* outer_scope_;
+ unsigned saved_ast_node_id_;
};
-LexicalScope::LexicalScope(Parser* parser, Scope* scope, Isolate* isolate)
- : materialized_literal_count_(0),
- expected_property_count_(0),
- only_simple_this_property_assignments_(false),
- this_property_assignments_(isolate->factory()->empty_fixed_array()),
- parser_(parser),
- lexical_scope_parent_(parser->lexical_scope_),
- previous_scope_(parser->top_scope_),
- previous_ast_node_id_(isolate->ast_node_id()) {
+Parser::FunctionState::FunctionState(Parser* parser,
+ Scope* scope,
+ Isolate* isolate)
+ : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
+ expected_property_count_(0),
+ only_simple_this_property_assignments_(false),
+ this_property_assignments_(isolate->factory()->empty_fixed_array()),
+ parser_(parser),
+ outer_function_state_(parser->current_function_state_),
+ outer_scope_(parser->top_scope_),
+ saved_ast_node_id_(isolate->ast_node_id()) {
parser->top_scope_ = scope;
- parser->lexical_scope_ = this;
+ parser->current_function_state_ = this;
isolate->set_ast_node_id(AstNode::kDeclarationsId + 1);
}
-LexicalScope::~LexicalScope() {
- parser_->top_scope_ = previous_scope_;
- parser_->lexical_scope_ = lexical_scope_parent_;
- parser_->isolate()->set_ast_node_id(previous_ast_node_id_);
+Parser::FunctionState::~FunctionState() {
+ parser_->top_scope_ = outer_scope_;
+ parser_->current_function_state_ = outer_function_state_;
+ parser_->isolate()->set_ast_node_id(saved_ast_node_id_);
}
@@ -592,7 +587,7 @@
script_(script),
scanner_(isolate_->unicode_cache()),
top_scope_(NULL),
- lexical_scope_(NULL),
+ current_function_state_(NULL),
target_stack_(NULL),
allow_natives_syntax_(allow_natives_syntax),
extension_(extension),
@@ -651,7 +646,7 @@
{ Scope* scope = NewScope(top_scope_, type);
scope->set_start_position(0);
scope->set_end_position(source->length());
- LexicalScope lexical_scope(this, scope, isolate());
+ FunctionState function_state(this, scope, isolate());
ASSERT(top_scope_->strict_mode_flag() == kNonStrictMode);
top_scope_->SetStrictModeFlag(strict_mode);
ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16);
@@ -672,10 +667,10 @@
no_name,
top_scope_,
body,
- lexical_scope.materialized_literal_count(),
- lexical_scope.expected_property_count(),
- lexical_scope.only_simple_this_property_assignments(),
- lexical_scope.this_property_assignments(),
+ function_state.materialized_literal_count(),
+ function_state.expected_property_count(),
+ function_state.only_simple_this_property_assignments(),
+ function_state.this_property_assignments(),
0,
FunctionLiteral::ANONYMOUS_EXPRESSION,
false); // Does not have duplicate parameters.
@@ -742,7 +737,7 @@
if (!info->closure().is_null()) {
scope = Scope::DeserializeScopeChain(info, scope);
}
- LexicalScope lexical_scope(this, scope, isolate());
+ FunctionState function_state(this, scope, isolate());
ASSERT(scope->strict_mode_flag() == kNonStrictMode ||
scope->strict_mode_flag() == info->strict_mode_flag());
ASSERT(info->strict_mode_flag() == shared_info->strict_mode_flag());
@@ -1217,7 +1212,7 @@
this_property_assignment_finder.only_simple_this_property_assignments()
&& top_scope_->declarations()->length() == 0;
if (only_simple_this_property_assignments) {
- lexical_scope_->SetThisPropertyAssignmentInfo(
+ current_function_state_->SetThisPropertyAssignmentInfo(
only_simple_this_property_assignments,
this_property_assignment_finder.GetThisPropertyAssignments());
}
@@ -1609,7 +1604,7 @@
// Parse the statements and collect escaping labels.
Expect(Token::LBRACE, CHECK_OK);
block_scope->set_start_position(scanner().location().beg_pos);
- { SaveScope save_scope(this, block_scope);
+ { BlockState block_state(this, block_scope);
TargetCollector collector;
Target target(&this->target_stack_, &collector);
Target target_body(&this->target_stack_, body);
@@ -2151,7 +2146,7 @@
top_scope_->DeclarationScope()->RecordWithStatement();
Scope* with_scope = NewScope(top_scope_, WITH_SCOPE);
Statement* stmt;
- { SaveScope save_scope(this, with_scope);
+ { BlockState block_state(this, with_scope);
with_scope->set_start_position(scanner().peek_location().beg_pos);
stmt = ParseStatement(labels, CHECK_OK);
with_scope->set_end_position(scanner().location().end_pos);
@@ -2298,7 +2293,7 @@
catch_variable =
catch_scope->DeclareLocal(name, mode, kCreatedInitialized);
- SaveScope save_scope(this, catch_scope);
+ BlockState block_state(this, catch_scope);
catch_block = ParseBlock(NULL, CHECK_OK);
} else {
Expect(Token::LBRACE, CHECK_OK);
@@ -2649,13 +2644,13 @@
property != NULL &&
property->obj()->AsVariableProxy() != NULL &&
property->obj()->AsVariableProxy()->is_this()) {
- lexical_scope_->AddProperty();
+ current_function_state_->AddProperty();
}
// If we assign a function literal to a property we pretenure the
// literal so it can be added as a constant function property.
if (property != NULL && right->AsFunctionLiteral() != NULL) {
- right->AsFunctionLiteral()->set_pretenure(true);
+ right->AsFunctionLiteral()->set_pretenure();
}
if (fni_ != NULL) {
@@ -3309,7 +3304,7 @@
Expect(Token::RBRACK, CHECK_OK);
// Update the scope information before the pre-parsing bailout.
- int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
+ int literal_index =
current_function_state_->NextMaterializedLiteralIndex();
// Allocate a fixed array to hold all the object literals.
Handle<FixedArray> object_literals =
@@ -3789,7 +3784,7 @@
// literal so it can be added as a constant function property.
if (value->AsFunctionLiteral() != NULL) {
has_function = true;
- value->AsFunctionLiteral()->set_pretenure(true);
+ value->AsFunctionLiteral()->set_pretenure();
}
// Count CONSTANT or COMPUTED properties to maintain the enumeration
order.
@@ -3809,7 +3804,7 @@
Expect(Token::RBRACE, CHECK_OK);
// Computation of literal_index must happen before pre parse bailout.
- int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
+ int literal_index =
current_function_state_->NextMaterializedLiteralIndex();
Handle<FixedArray> constant_properties =
isolate()->factory()->NewFixedArray(
number_of_boilerplate_properties * 2, TENURED);
@@ -3841,7 +3836,7 @@
return NULL;
}
- int literal_index = lexical_scope_->NextMaterializedLiteralIndex();
+ int literal_index =
current_function_state_->NextMaterializedLiteralIndex();
Handle<String> js_pattern = NextLiteralString(TENURED);
scanner().ScanRegExpFlags();
@@ -3909,7 +3904,7 @@
Handle<FixedArray> this_property_assignments;
bool has_duplicate_parameters = false;
// Parse function body.
- { LexicalScope lexical_scope(this, scope, isolate());
+ { FunctionState function_state(this, scope, isolate());
top_scope_->SetScopeName(function_name);
// FormalParameterList ::
@@ -4020,11 +4015,11 @@
if (!is_lazily_compiled) {
ParseSourceElements(body, Token::RBRACE, CHECK_OK);
- materialized_literal_count =
lexical_scope.materialized_literal_count();
- expected_property_count = lexical_scope.expected_property_count();
+ materialized_literal_count =
function_state.materialized_literal_count();
+ expected_property_count = function_state.expected_property_count();
only_simple_this_property_assignments =
- lexical_scope.only_simple_this_property_assignments();
- this_property_assignments =
lexical_scope.this_property_assignments();
+ function_state.only_simple_this_property_assignments();
+ this_property_assignments =
function_state.this_property_assignments();
Expect(Token::RBRACE, CHECK_OK);
scope->set_end_position(scanner().location().end_pos);
=======================================
--- /branches/bleeding_edge/src/parser.h Tue Nov 1 00:47:15 2011
+++ /branches/bleeding_edge/src/parser.h Wed Nov 9 05:54:26 2011
@@ -43,8 +43,6 @@
class ParserLog;
class PositionStack;
class Target;
-class LexicalScope;
-class SaveScope;
template <typename T> class ZoneListWrapper;
@@ -69,30 +67,32 @@
class FunctionEntry BASE_EMBEDDED {
public:
+ enum {
+ kStartPositionIndex,
+ kEndPositionIndex,
+ kLiteralCountIndex,
+ kPropertyCountIndex,
+ kStrictModeIndex,
+ kSize
+ };
+
explicit FunctionEntry(Vector<unsigned> backing) : backing_(backing) { }
FunctionEntry() : backing_(Vector<unsigned>::empty()) { }
- int start_pos() { return backing_[kStartPosOffset]; }
- int end_pos() { return backing_[kEndPosOffset]; }
- int literal_count() { return backing_[kLiteralCountOffset]; }
- int property_count() { return backing_[kPropertyCountOffset]; }
+ int start_pos() { return backing_[kStartPositionIndex]; }
+ int end_pos() { return backing_[kEndPositionIndex]; }
+ int literal_count() { return backing_[kLiteralCountIndex]; }
+ int property_count() { return backing_[kPropertyCountIndex]; }
StrictModeFlag strict_mode_flag() {
- ASSERT(backing_[kStrictModeOffset] == kStrictMode ||
- backing_[kStrictModeOffset] == kNonStrictMode);
- return static_cast<StrictModeFlag>(backing_[kStrictModeOffset]);
+ ASSERT(backing_[kStrictModeIndex] == kStrictMode ||
+ backing_[kStrictModeIndex] == kNonStrictMode);
+ return static_cast<StrictModeFlag>(backing_[kStrictModeIndex]);
}
- bool is_valid() { return backing_.length() > 0; }
-
- static const int kSize = 5;
+ bool is_valid() { return !backing_.is_empty(); }
private:
Vector<unsigned> backing_;
- static const int kStartPosOffset = 0;
- static const int kEndPosOffset = 1;
- static const int kLiteralCountOffset = 2;
- static const int kPropertyCountOffset = 3;
- static const int kStrictModeOffset = 4;
};
@@ -451,9 +451,7 @@
// should be checked.
static const int kMaxNumFunctionParameters = 32766;
static const int kMaxNumFunctionLocals = 32767;
- FunctionLiteral* ParseLazy(CompilationInfo* info,
- UC16CharacterStream* source,
- ZoneScope* zone_scope);
+
enum Mode {
PARSE_LAZILY,
PARSE_EAGERLY
@@ -471,6 +469,13 @@
kHasNoInitializers
};
+ class BlockState;
+ class FunctionState;
+
+ FunctionLiteral* ParseLazy(CompilationInfo* info,
+ UC16CharacterStream* source,
+ ZoneScope* zone_scope);
+
Isolate* isolate() { return isolate_; }
Zone* zone() { return isolate_->zone(); }
@@ -730,7 +735,7 @@
Scope* top_scope_;
- LexicalScope* lexical_scope_;
+ FunctionState* current_function_state_;
Mode mode_;
Target* target_stack_; // for break, continue statements
@@ -747,8 +752,8 @@
bool parenthesized_function_;
bool harmony_scoping_;
- friend class LexicalScope;
- friend class SaveScope;
+ friend class BlockState;
+ friend class FunctionState;
};
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev