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

Unified Diff: src/parser.cc

Issue 214883002: Two-threaded parser (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: code review (svenpanne) Created 6 years, 8 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
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 9d37c88bf4aad9fbb03830440c58453c77f6402f..a93d3218eee384e745e7cf9890e0fadaa808b2e9 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -35,6 +35,7 @@
#include "compiler.h"
#include "messages.h"
#include "parser.h"
+#include "parser-thread.h"
#include "platform.h"
#include "preparser.h"
#include "runtime.h"
@@ -839,6 +840,7 @@ Parser::Parser(CompilationInfo* info)
info->isolate()->stack_guard()->real_climit(),
info->extension(),
NULL,
+ NULL,
info->zone(),
this),
isolate_(info->isolate()),
@@ -875,22 +877,54 @@ FunctionLiteral* Parser::ParseProgram() {
}
fni_ = new(zone()) FuncNameInferrer(isolate(), zone());
- // Initialize parser state.
+ source = String::Flatten(source);
+
CompleteParserRecorder recorder;
if (cached_data_mode_ == PRODUCE_CACHED_DATA) {
+ ASSERT(allow_lazy());
log_ = &recorder;
+ if (source->length() >= FLAG_min_parallel_parse_length) {
+ // Start a thread for doing a fast pass over the script to find lazy
+ // functions with PreParser. Restrictions: 1) PreParser cannot yet parse
+ // everything that Parser can (e.g., harmony modules). So here we are on
+ // the safe side, and only use the FastParserThread when we're sure that
+ // the script is good (i.e., for scripts for which we produce cached
+ // data). TODO(marja): Use FastParserThread for other kinds of
+ // compilations too. 2) The thread cannot use the Isolate, or Handles, so
+ // this will only work if the actual data is kept outside the V8 heap as
+ // an external string.
+ if (source->IsExternalAsciiString()) {
+ thread_ = new FastParserThread(
+ new ExternalOneByteStringUtf16CharacterStream(
Sven Panne 2014/04/16 11:55:35 Extract the creation of the Utf16CharacterStream*
marja 2014/04/16 14:33:10 Extracted the Stream creation. But I don't get wha
+ Handle<ExternalAsciiString>::cast(source)->GetChars(), 0,
+ source->length()),
+ allow_harmony_scoping(), allow_modules(), allow_natives_syntax(),
+ allow_generators(), allow_for_of(),
+ allow_harmony_numeric_literals());
+ thread_->Start();
+ } else if (source->IsExternalTwoByteString()) {
+ thread_ = new FastParserThread(
+ new ExternalTwoByteStringUtf16CharacterStream(
+ Handle<ExternalTwoByteString>::cast(source)->GetTwoByteData(0),
+ 0, source->length()),
+ allow_harmony_scoping(), allow_modules(), allow_natives_syntax(),
+ allow_generators(), allow_for_of(),
+ allow_harmony_numeric_literals());
+ thread_->Start();
+ }
+ }
} else if (cached_data_mode_ == CONSUME_CACHED_DATA) {
(*cached_data_)->Initialize();
}
- source = String::Flatten(source);
FunctionLiteral* result;
if (source->IsExternalTwoByteString()) {
// Notice that the stream is destroyed at the end of the branch block.
// The last line of the blocks can't be moved outside, even though they're
// identical calls.
ExternalTwoByteStringUtf16CharacterStream stream(
- Handle<ExternalTwoByteString>::cast(source), 0, source->length());
+ Handle<ExternalTwoByteString>::cast(source)->GetTwoByteData(0), 0,
+ source->length());
scanner_.Initialize(&stream);
result = DoParseProgram(info(), source);
} else {
@@ -916,6 +950,11 @@ FunctionLiteral* Parser::ParseProgram() {
Vector<unsigned> store = recorder.ExtractData();
*cached_data_ = new ScriptData(store);
log_ = NULL;
+ if (thread_) {
Sven Panne 2014/04/16 11:55:35 Lift this block out into a separate method, it's u
marja 2014/04/16 14:33:10 Done, and I also added a function for (possibly) s
+ thread_->Join();
+ delete thread_;
+ thread_ = NULL;
+ }
}
return result;
}
@@ -1026,7 +1065,7 @@ FunctionLiteral* Parser::ParseLazy() {
FunctionLiteral* result;
if (source->IsExternalTwoByteString()) {
ExternalTwoByteStringUtf16CharacterStream stream(
- Handle<ExternalTwoByteString>::cast(source),
+ Handle<ExternalTwoByteString>::cast(source)->GetTwoByteData(0),
shared_info->start_position(),
shared_info->end_position());
result = ParseLazy(&stream);
@@ -3500,6 +3539,49 @@ void Parser::SkipLazyFunctionBody(Handle<String> function_name,
ReportInvalidCachedData(function_name, ok);
return;
}
+ } else if (thread_) {
Sven Panne 2014/04/16 11:55:35 Hmmm, the block below contains some heavy copy-n-p
marja 2014/04/16 14:33:10 Done.
+ int start, end;
+ StrictMode strict_mode;
+ // This will wait until the background thread has found the lazy function.
+ thread_->Consume(&start, &end, materialized_literal_count,
+ expected_property_count, &strict_mode);
+ ASSERT(log_);
+ log_->LogFunction(start, end, *materialized_literal_count,
+ *expected_property_count, strict_mode);
+ if (start == function_block_pos) {
+ scanner()->SeekForward(end - 1);
+ scope_->set_end_position(end);
+ Expect(Token::RBRACE, ok);
+ if (!ok) {
+ return;
+ }
+ isolate()->counters()->total_preparse_skipped()->Increment(end - start);
+ scope_->SetStrictMode(strict_mode);
+ } else {
+ // The thread might have found an error. Handle it.
+ const SingletonLogger* logger = thread_->recorder();
+ if (thread_->GetResult() == PreParser::kPreParseStackOverflow) {
+ set_stack_overflow();
+ } else if (logger->has_error()) {
+ const char* arg = logger->argument_opt();
+ Vector<const char*> args;
+ if (arg != NULL) {
+ args = Vector<const char*>(&arg, 1);
+ }
+ ParserTraits::ReportMessageAt(
+ Scanner::Location(logger->start(), logger->end()),
+ logger->message(), args, logger->is_reference_error());
+ } else {
+ // The thread produced data for a lazy function which was not the
+ // function we expected. This should never happen.
+ ASSERT(false);
+ }
+ thread_->Join();
+ delete thread_;
+ thread_ = NULL;
+ *ok = false;
+ return;
+ }
} else {
// With no cached data, we partially parse the function, without building an
// AST. This gathers the data needed to build a lazy function.
@@ -3613,7 +3695,7 @@ PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser(
if (reusable_preparser_ == NULL) {
intptr_t stack_limit = isolate()->stack_guard()->real_climit();
- reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit);
+ reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit, NULL);
reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping());
reusable_preparser_->set_allow_modules(allow_modules());
reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax());
« no previous file with comments | « src/flag-definitions.h ('k') | src/parser-thread.h » ('j') | src/parser-thread.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698