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

Unified Diff: src/parser.cc

Issue 3356010: Avoid collecting symbol info for one-off preparsing. (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') | no next file » | 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 7667e89a3cbdd35971282d42c920a52aa61f2597..11e2eb559e79d01328b1494d68a19da5df29626a 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -872,11 +872,14 @@ class ParserLog BASE_EMBEDDED {
// Records the occurrence of a function.
virtual FunctionEntry LogFunction(int start) { return FunctionEntry(); }
virtual void LogSymbol(int start, Vector<const char> symbol) {}
+ virtual void LogError() { }
// Return the current position in the function entry log.
virtual int function_position() { return 0; }
virtual int symbol_position() { return 0; }
virtual int symbol_ids() { return 0; }
- virtual void LogError() { }
+ virtual Vector<unsigned> ExtractData() {
+ return Vector<unsigned>();
+ };
};
@@ -889,9 +892,14 @@ class AstBuildingParserFactory : public ParserFactory {
virtual Handle<String> LookupSymbol(int symbol_id,
Vector<const char> string) {
- // If there is no preparse data, we have no simpler way to identify similar
- // symbols.
- if (symbol_id < 0) return Factory::LookupSymbol(string);
+ // Length of symbol cache is the number of identified symbols.
+ // If we are larger than that, or negative, it's not a cached symbol.
+ // This might also happen if there is no preparser symbol data, even
+ // if there is some preparser data.
+ if (static_cast<unsigned>(symbol_id)
+ >= static_cast<unsigned>(symbol_cache_.length())) {
+ return Factory::LookupSymbol(string);
+ }
return LookupCachedSymbol(symbol_id, string);
}
@@ -933,10 +941,55 @@ class AstBuildingParserFactory : public ParserFactory {
};
-class ParserRecorder: public ParserLog {
+// Record only functions.
+class PartialParserRecorder: public ParserLog {
public:
- ParserRecorder();
+ PartialParserRecorder();
virtual FunctionEntry LogFunction(int start);
+
+ virtual int function_position() { return function_store_.size(); }
+
+ virtual void LogError() { }
+
+ virtual void LogMessage(Scanner::Location loc,
+ const char* message,
+ Vector<const char*> args);
+
+ virtual Vector<unsigned> ExtractData() {
+ int function_size = function_store_.size();
+ int total_size = ScriptDataImpl::kHeaderSize + function_size;
+ Vector<unsigned> data = Vector<unsigned>::New(total_size);
+ preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size;
+ preamble_[ScriptDataImpl::kSymbolCountOffset] = 0;
+ memcpy(data.start(), preamble_, sizeof(preamble_));
+ int symbol_start = ScriptDataImpl::kHeaderSize + function_size;
+ if (function_size > 0) {
+ function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize,
+ symbol_start));
+ }
+ return data;
+ }
+
+ protected:
+ bool has_error() {
+ return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]);
+ }
+
+ void WriteString(Vector<const char> str);
+
+ Collector<unsigned> function_store_;
+ unsigned preamble_[ScriptDataImpl::kHeaderSize];
+#ifdef DEBUG
+ int prev_start;
+#endif
+};
+
+
+// Record both functions and symbols.
+class CompleteParserRecorder: public PartialParserRecorder {
+ public:
+ CompleteParserRecorder();
+
virtual void LogSymbol(int start, Vector<const char> literal) {
int hash = vector_hash(literal);
HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true);
@@ -953,11 +1006,8 @@ class ParserRecorder: public ParserLog {
symbol_store_.Add(id - 1);
}
}
- virtual void LogError() { }
- virtual void LogMessage(Scanner::Location loc,
- const char* message,
- Vector<const char*> args);
- Vector<unsigned> ExtractData() {
+
+ virtual Vector<unsigned> ExtractData() {
int function_size = function_store_.size();
int symbol_size = symbol_store_.size();
int total_size = ScriptDataImpl::kHeaderSize + function_size + symbol_size;
@@ -976,11 +1026,9 @@ class ParserRecorder: public ParserLog {
return data;
}
- virtual int function_position() { return function_store_.size(); }
virtual int symbol_position() { return symbol_store_.size(); }
virtual int symbol_ids() { return symbol_id_; }
private:
- Collector<unsigned> function_store_;
Collector<unsigned> symbol_store_;
Collector<Vector<const char> > symbol_entries_;
HashMap symbol_table_;
@@ -1004,16 +1052,6 @@ class ParserRecorder: public ParserLog {
if (string2->length() != length) return false;
return memcmp(string1->start(), string2->start(), length) == 0;
}
-
- unsigned preamble_[ScriptDataImpl::kHeaderSize];
-#ifdef DEBUG
- int prev_start;
-#endif
-
- bool has_error() {
- return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]);
- }
- void WriteString(Vector<const char> str);
};
@@ -1088,15 +1126,8 @@ bool ScriptDataImpl::SanityCheck() {
}
-ParserRecorder::ParserRecorder()
- : function_store_(0),
- symbol_store_(0),
- symbol_entries_(0),
- symbol_table_(vector_compare),
- symbol_id_(0) {
-#ifdef DEBUG
- prev_start = -1;
-#endif
+
+PartialParserRecorder::PartialParserRecorder() : function_store_(0) {
preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber;
preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion;
preamble_[ScriptDataImpl::kHasErrorOffset] = false;
@@ -1104,10 +1135,22 @@ ParserRecorder::ParserRecorder()
preamble_[ScriptDataImpl::kSymbolCountOffset] = 0;
preamble_[ScriptDataImpl::kSizeOffset] = 0;
ASSERT_EQ(6, ScriptDataImpl::kHeaderSize);
+#ifdef DEBUG
+ prev_start = -1;
+#endif
}
-void ParserRecorder::WriteString(Vector<const char> str) {
+CompleteParserRecorder::CompleteParserRecorder()
+ : PartialParserRecorder(),
+ symbol_store_(0),
+ symbol_entries_(0),
+ symbol_table_(vector_compare),
+ symbol_id_(0) {
+}
+
+
+void PartialParserRecorder::WriteString(Vector<const char> str) {
function_store_.Add(str.length());
for (int i = 0; i < str.length(); i++) {
function_store_.Add(str[i]);
@@ -1127,8 +1170,9 @@ const char* ScriptDataImpl::ReadString(unsigned* start, int* chars) {
}
-void ParserRecorder::LogMessage(Scanner::Location loc, const char* message,
- Vector<const char*> args) {
+void PartialParserRecorder::LogMessage(Scanner::Location loc,
+ const char* message,
+ Vector<const char*> args) {
if (has_error()) return;
preamble_[ScriptDataImpl::kHasErrorOffset] = true;
function_store_.Reset();
@@ -1183,7 +1227,7 @@ unsigned* ScriptDataImpl::ReadAddress(int position) {
}
-FunctionEntry ParserRecorder::LogFunction(int start) {
+FunctionEntry PartialParserRecorder::LogFunction(int start) {
#ifdef DEBUG
ASSERT(start > prev_start);
prev_start = start;
@@ -1206,7 +1250,7 @@ class AstBuildingParser : public Parser {
factory(),
log(),
pre_data),
- factory_(pre_data ? pre_data->symbol_count() : 16) { }
+ factory_(pre_data ? pre_data->symbol_count() : 0) { }
virtual void ReportMessageAt(Scanner::Location loc, const char* message,
Vector<const char*> args);
virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
@@ -1223,23 +1267,44 @@ class AstBuildingParser : public Parser {
class PreParser : public Parser {
public:
PreParser(Handle<Script> script, bool allow_natives_syntax,
- v8::Extension* extension)
+ v8::Extension* extension, ParserLog* recorder)
: Parser(script, allow_natives_syntax, extension, PREPARSE,
- factory(), recorder(), NULL),
+ factory(), recorder, NULL),
factory_(true) { }
virtual void ReportMessageAt(Scanner::Location loc, const char* message,
Vector<const char*> args);
virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
FunctionLiteral* fun, bool resolve, bool* ok);
ParserFactory* factory() { return &factory_; }
- ParserRecorder* recorder() { return &recorder_; }
+ virtual PartialParserRecorder* recorder() = 0;
private:
- ParserRecorder recorder_;
ParserFactory factory_;
};
+class CompletePreParser : public PreParser {
+ public:
+ CompletePreParser(Handle<Script> script, bool allow_natives_syntax,
+ v8::Extension* extension)
+ : PreParser(script, allow_natives_syntax, extension, &recorder_) { }
+ virtual PartialParserRecorder* recorder() { return &recorder_; }
+ private:
+ CompleteParserRecorder recorder_;
+};
+
+
+class PartialPreParser : public PreParser {
+ public:
+ PartialPreParser(Handle<Script> script, bool allow_natives_syntax,
+ v8::Extension* extension)
+ : PreParser(script, allow_natives_syntax, extension, &recorder_) { }
+ virtual PartialParserRecorder* recorder() { return &recorder_; }
+ private:
+ PartialParserRecorder recorder_;
+};
+
+
Scope* AstBuildingParserFactory::NewScope(Scope* parent, Scope::Type type,
bool inside_with) {
Scope* result = new Scope(parent, type);
@@ -5413,6 +5478,25 @@ bool ScriptDataImpl::HasError() {
}
+// Preparse, but only collect data that is immediately useful,
+// even if the preparser data is only used once.
+ScriptDataImpl* PartialPreParse(Handle<String> source,
+ unibrow::CharacterStream* stream,
+ v8::Extension* extension) {
+ Handle<Script> no_script;
+ bool allow_natives_syntax =
+ always_allow_natives_syntax ||
+ FLAG_allow_natives_syntax ||
+ Bootstrapper::IsActive();
+ PartialPreParser parser(no_script, allow_natives_syntax, extension);
+ if (!parser.PreParseProgram(source, stream)) return NULL;
+ // Extract the accumulated data from the recorder as a single
+ // contiguous vector that we are responsible for disposing.
+ Vector<unsigned> store = parser.recorder()->ExtractData();
+ return new ScriptDataImpl(store);
+}
+
+
ScriptDataImpl* PreParse(Handle<String> source,
unibrow::CharacterStream* stream,
v8::Extension* extension) {
@@ -5421,7 +5505,7 @@ ScriptDataImpl* PreParse(Handle<String> source,
always_allow_natives_syntax ||
FLAG_allow_natives_syntax ||
Bootstrapper::IsActive();
- PreParser parser(no_script, allow_natives_syntax, extension);
+ CompletePreParser parser(no_script, allow_natives_syntax, extension);
if (!parser.PreParseProgram(source, stream)) return NULL;
// Extract the accumulated data from the recorder as a single
// contiguous vector that we are responsible for disposing.
« no previous file with comments | « src/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698