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

Unified Diff: src/parser.cc

Issue 3412034: Avoid logging preparse-data inside lazily compiled functions. (Closed)
Patch Set: Addressed review comments. Created 10 years, 3 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/parser.h ('k') | src/scopes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index aebcc9ae2ca069e2a84da3f9ed545d78bd83adee..2674929c75fa0f13fa39f205b3d4f7909636a6af 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -877,12 +877,30 @@ class ParserLog BASE_EMBEDDED {
virtual int function_position() { return 0; }
virtual int symbol_position() { return 0; }
virtual int symbol_ids() { return 0; }
+ virtual void PauseRecording() {}
+ virtual void ResumeRecording() {}
virtual Vector<unsigned> ExtractData() {
return Vector<unsigned>();
};
};
+
+class ConditionalLogPauseScope {
+ public:
+ ConditionalLogPauseScope(bool pause, ParserLog* log)
+ : log_(log), pause_(pause) {
+ if (pause) log->PauseRecording();
+ }
+ ~ConditionalLogPauseScope() {
+ if (pause_) log_->ResumeRecording();
+ }
+ private:
+ ParserLog* log_;
+ bool pause_;
+};
+
+
class AstBuildingParserFactory : public ParserFactory {
public:
explicit AstBuildingParserFactory(int expected_symbols)
@@ -970,15 +988,31 @@ class PartialParserRecorder: public ParserLog {
return data;
}
+ virtual void PauseRecording() {
+ pause_count_++;
+ is_recording_ = false;
+ }
+
+ virtual void ResumeRecording() {
+ ASSERT(pause_count_ > 0);
+ if (--pause_count_ == 0) is_recording_ = !has_error();
+ }
+
protected:
bool has_error() {
return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]);
}
+ bool is_recording() {
+ return is_recording_;
+ }
void WriteString(Vector<const char> str);
Collector<unsigned> function_store_;
unsigned preamble_[ScriptDataImpl::kHeaderSize];
+ bool is_recording_;
+ int pause_count_;
+
#ifdef DEBUG
int prev_start;
#endif
@@ -991,6 +1025,7 @@ class CompleteParserRecorder: public PartialParserRecorder {
CompleteParserRecorder();
virtual void LogSymbol(int start, Vector<const char> literal) {
+ if (!is_recording_) return;
int hash = vector_hash(literal);
HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true);
int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
@@ -1061,13 +1096,6 @@ class CompleteParserRecorder: public PartialParserRecorder {
};
-void ScriptDataImpl::SkipFunctionEntry(int start) {
- ASSERT(function_index_ + FunctionEntry::kSize <= store_.length());
- ASSERT(static_cast<int>(store_[function_index_]) == start);
- function_index_ += FunctionEntry::kSize;
-}
-
-
FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
// The current pre-data entry must be a FunctionEntry with the given
// start position.
@@ -1126,7 +1154,10 @@ bool ScriptDataImpl::SanityCheck() {
-PartialParserRecorder::PartialParserRecorder() : function_store_(0) {
+PartialParserRecorder::PartialParserRecorder()
+ : function_store_(0),
+ is_recording_(true),
+ pause_count_(0) {
preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber;
preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion;
preamble_[ScriptDataImpl::kHasErrorOffset] = false;
@@ -1202,6 +1233,7 @@ void PartialParserRecorder::LogMessage(Scanner::Location loc,
for (int i = 0; i < args.length(); i++) {
WriteString(CStrVector(args[i]));
}
+ is_recording_ = false;
}
@@ -1248,7 +1280,7 @@ FunctionEntry PartialParserRecorder::LogFunction(int start) {
ASSERT(start > prev_start);
prev_start = start;
#endif
- if (has_error()) return FunctionEntry();
+ if (!is_recording_) return FunctionEntry();
FunctionEntry result(function_store_.AddBlock(FunctionEntry::kSize, 0));
result.set_start_pos(start);
return result;
@@ -1343,6 +1375,8 @@ Scope* ParserFactory::NewScope(Scope* parent, Scope::Type type,
bool inside_with) {
ASSERT(parent != NULL);
parent->type_ = type;
+ // Initialize function is hijacked by DummyScope to increment scope depth.
+ parent->Initialize(inside_with);
return parent;
}
@@ -1415,6 +1449,7 @@ class LexicalScope BASE_EMBEDDED {
}
~LexicalScope() {
+ parser_->top_scope_->Leave();
parser_->top_scope_ = prev_scope_;
parser_->with_nesting_level_ = prev_level_;
}
@@ -1480,7 +1515,8 @@ bool Parser::PreParseProgram(Handle<String> source,
NoHandleAllocation no_handle_allocation;
scanner_.Initialize(source, stream, JAVASCRIPT);
ASSERT(target_stack_ == NULL);
- mode_ = PARSE_EAGERLY;
+ mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY;
+ if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY;
DummyScope top_scope;
LexicalScope scope(this, &top_scope);
TemporaryScope temp_scope(this);
@@ -1658,7 +1694,10 @@ void Parser::ReportMessage(const char* type, Vector<const char*> args) {
Handle<String> Parser::GetSymbol(bool* ok) {
- log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal());
+ if (is_pre_parsing_) {
+ log()->LogSymbol(scanner_.location().beg_pos, scanner_.literal());
+ return Handle<String>::null();
+ }
int symbol_id = -1;
if (pre_data() != NULL) {
symbol_id = pre_data()->GetSymbolIdentifier();
@@ -1971,7 +2010,7 @@ void* Parser::ParseSourceElements(ZoneListWrapper<Statement>* processor,
}
// Propagate the collected information on this property assignments.
- if (top_scope_->is_function_scope()) {
+ if (!is_pre_parsing_ && top_scope_->is_function_scope()) {
bool only_simple_this_property_assignments =
this_property_assignment_finder.only_simple_this_property_assignments()
&& top_scope_->declarations()->length() == 0;
@@ -4123,8 +4162,8 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
int num_parameters = 0;
// Parse function body.
- { Scope::Type type = Scope::FUNCTION_SCOPE;
- Scope* scope = factory()->NewScope(top_scope_, type, inside_with());
+ { Scope* scope =
+ factory()->NewScope(top_scope_, Scope::FUNCTION_SCOPE, inside_with());
LexicalScope lexical_scope(this, scope);
TemporaryScope temp_scope(this);
top_scope_->SetScopeName(name);
@@ -4155,7 +4194,9 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
// NOTE: We create a proxy and resolve it here so that in the
// future we can change the AST to only refer to VariableProxies
// instead of Variables and Proxis as is the case now.
- if (!function_name.is_null() && function_name->length() > 0) {
+ if (!is_pre_parsing_
+ && !function_name.is_null()
+ && function_name->length() > 0) {
Variable* fvar = top_scope_->DeclareFunctionVar(function_name);
VariableProxy* fproxy =
top_scope_->NewUnresolved(function_name, inside_with());
@@ -4189,22 +4230,18 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
}
Counters::total_preparse_skipped.Increment(end_pos - function_block_pos);
scanner_.SeekForward(end_pos);
- pre_data()->Skip(entry.predata_function_skip(),
- entry.predata_symbol_skip());
materialized_literal_count = entry.literal_count();
expected_property_count = entry.property_count();
only_simple_this_property_assignments = false;
this_property_assignments = Factory::empty_fixed_array();
Expect(Token::RBRACE, CHECK_OK);
} else {
- if (pre_data() != NULL) {
- // Skip pre-data entry for non-lazily compiled function.
- pre_data()->SkipFunctionEntry(function_block_pos);
+ FunctionEntry entry;
+ if (is_lazily_compiled) entry = log()->LogFunction(function_block_pos);
+ {
+ ConditionalLogPauseScope pause_if(is_lazily_compiled, log());
+ ParseSourceElements(&body, Token::RBRACE, CHECK_OK);
}
- FunctionEntry entry = log()->LogFunction(function_block_pos);
- int predata_function_position_before = log()->function_position();
- int predata_symbol_position_before = log()->symbol_position();
- ParseSourceElements(&body, Token::RBRACE, CHECK_OK);
materialized_literal_count = temp_scope.materialized_literal_count();
expected_property_count = temp_scope.expected_property_count();
only_simple_this_property_assignments =
@@ -4214,13 +4251,11 @@ FunctionLiteral* Parser::ParseFunctionLiteral(Handle<String> var_name,
Expect(Token::RBRACE, CHECK_OK);
end_pos = scanner_.location().end_pos;
if (entry.is_valid()) {
+ ASSERT(is_lazily_compiled);
+ ASSERT(is_pre_parsing_);
entry.set_end_pos(end_pos);
entry.set_literal_count(materialized_literal_count);
entry.set_property_count(expected_property_count);
- entry.set_predata_function_skip(
- log()->function_position() - predata_function_position_before);
- entry.set_predata_symbol_skip(
- log()->symbol_position() - predata_symbol_position_before);
}
}
@@ -5625,8 +5660,6 @@ FunctionLiteral* MakeLazyAST(Handle<Script> script,
return result;
}
-
#undef NEW
-
} } // namespace v8::internal
« no previous file with comments | « src/parser.h ('k') | src/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698