Index: src/compiler-dispatcher/compiler-dispatcher-job.cc |
diff --git a/src/compiler-dispatcher/compiler-dispatcher-job.cc b/src/compiler-dispatcher/compiler-dispatcher-job.cc |
index 8234ae214092ee4a99363c04b661bc34bb3942bf..fbf91ab7417a905805a7dd7aff968936798bf883 100644 |
--- a/src/compiler-dispatcher/compiler-dispatcher-job.cc |
+++ b/src/compiler-dispatcher/compiler-dispatcher-job.cc |
@@ -33,6 +33,8 @@ CompilerDispatcherJob::CompilerDispatcherJob(Isolate* isolate, |
CompilerDispatcherJob::~CompilerDispatcherJob() { |
DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); |
+ DCHECK(status_ == CompileJobStatus::kInitial || |
+ status_ == CompileJobStatus::kDone); |
i::GlobalHandles::Destroy(Handle<Object>::cast(function_).location()); |
} |
@@ -46,19 +48,20 @@ void CompilerDispatcherJob::PrepareToParseOnMainThread() { |
Handle<Script> script(Script::cast(shared->script()), isolate_); |
Handle<String> source(String::cast(script->source()), isolate_); |
if (source->IsExternalTwoByteString()) { |
- can_parse_on_background_thread_ = true; |
character_stream_.reset(new ExternalTwoByteStringUtf16CharacterStream( |
Handle<ExternalTwoByteString>::cast(source), shared->start_position(), |
shared->end_position())); |
} else if (source->IsExternalOneByteString()) { |
- can_parse_on_background_thread_ = true; |
character_stream_.reset(new ExternalOneByteStringUtf16CharacterStream( |
Handle<ExternalOneByteString>::cast(source), shared->start_position(), |
shared->end_position())); |
} else { |
- can_parse_on_background_thread_ = false; |
+ source = String::Flatten(source); |
+ // Have to globalize the reference here, so it survives between function |
+ // calls. |
+ source_ = Handle<String>::cast(isolate_->global_handles()->Create(*source)); |
character_stream_.reset(new GenericStringUtf16CharacterStream( |
- source, shared->start_position(), shared->end_position())); |
+ source_, shared->start_position(), shared->end_position())); |
} |
parse_info_.reset(new ParseInfo(zone_.get())); |
parse_info_->set_isolate(isolate_); |
@@ -76,7 +79,12 @@ void CompilerDispatcherJob::Parse() { |
DisallowHeapAllocation no_allocation; |
DisallowHandleAllocation no_handles; |
- DisallowHandleDereference no_deref; |
+ std::unique_ptr<DisallowHandleDereference> no_deref; |
+ // If we can't parse on a background thread, we need to be able to deref the |
+ // source string. |
+ if (can_parse_on_background_thread_) { |
+ no_deref.reset(new DisallowHandleDereference()); |
+ } |
// Nullify the Isolate temporarily so that the parser doesn't accidentally |
// use it. |
@@ -93,5 +101,75 @@ void CompilerDispatcherJob::Parse() { |
status_ = CompileJobStatus::kParsed; |
} |
+void CompilerDispatcherJob::FinalizeParsingOnMainThread() { |
+ DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); |
+ DCHECK(status() == CompileJobStatus::kParsed); |
+ |
+ if (!source_.is_null()) { |
+ i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location()); |
+ source_ = Handle<String>::null(); |
+ } |
+ |
+ if (parse_info_->literal() == nullptr) { |
+ status_ = CompileJobStatus::kFailed; |
+ return; |
+ } |
+ |
+ InternalizeParsingResult(); |
+ |
+ status_ = CompileJobStatus::kReadyToCompile; |
+} |
+ |
+void CompilerDispatcherJob::ReportErrorsOnMainThread() { |
+ DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); |
+ DCHECK(status() == CompileJobStatus::kFailed); |
+ |
+ // Internalizing the parsing result will throw the error. |
+ InternalizeParsingResult(); |
+ |
+ status_ = CompileJobStatus::kDone; |
+} |
+ |
+void CompilerDispatcherJob::ResetOnMainThread() { |
+ DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); |
+ |
+ parser_.reset(); |
+ unicode_cache_.reset(); |
+ character_stream_.reset(); |
+ parse_info_.reset(); |
+ zone_.reset(); |
+ |
+ if (!source_.is_null()) { |
+ i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location()); |
+ source_ = Handle<String>::null(); |
+ } |
+ |
+ status_ = CompileJobStatus::kInitial; |
+} |
+ |
+void CompilerDispatcherJob::InternalizeParsingResult() { |
+ DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); |
+ DCHECK(status() == CompileJobStatus::kParsed || |
+ status() == CompileJobStatus::kFailed); |
+ |
+ HandleScope scope(isolate_); |
+ Handle<SharedFunctionInfo> shared(function_->shared(), isolate_); |
+ Handle<Script> script(Script::cast(shared->script()), isolate_); |
+ |
+ parse_info_->set_script(script); |
+ parse_info_->set_context(handle(function_->context(), isolate_)); |
+ |
+ // Do the parsing tasks which need to be done on the main thread. This will |
+ // also handle parse errors. |
+ parser_->Internalize(isolate_, script, parse_info_->literal() == nullptr); |
+ parser_->HandleSourceURLComments(isolate_, script); |
+ |
+ parse_info_->set_character_stream(nullptr); |
+ parse_info_->set_unicode_cache(nullptr); |
+ parser_.reset(); |
+ unicode_cache_.reset(); |
+ character_stream_.reset(); |
+} |
+ |
} // namespace internal |
} // namespace v8 |