Commit b79259f6 authored by jochen's avatar jochen Committed by Commit bot

Finalizing parsing in a compile job should immediately report errors

When preparing compilation, we can't delay error reporting either.

Also put handles during internalization into a deferred handle scope.

BUG=v8:5215
R=marja@chromium.org,rmcilory@chromium.org

Review-Url: https://codereview.chromium.org/2268983002
Cr-Commit-Position: refs/heads/master@{#38817}
parent f5b86867
...@@ -119,7 +119,7 @@ void CompilerDispatcherJob::Parse() { ...@@ -119,7 +119,7 @@ void CompilerDispatcherJob::Parse() {
status_ = CompileJobStatus::kParsed; status_ = CompileJobStatus::kParsed;
} }
void CompilerDispatcherJob::FinalizeParsingOnMainThread() { bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
DCHECK(ThreadId::Current().Equals(isolate_->thread_id())); DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
DCHECK(status() == CompileJobStatus::kParsed); DCHECK(status() == CompileJobStatus::kParsed);
...@@ -130,22 +130,37 @@ void CompilerDispatcherJob::FinalizeParsingOnMainThread() { ...@@ -130,22 +130,37 @@ void CompilerDispatcherJob::FinalizeParsingOnMainThread() {
if (parse_info_->literal() == nullptr) { if (parse_info_->literal() == nullptr) {
status_ = CompileJobStatus::kFailed; status_ = CompileJobStatus::kFailed;
return; } else {
status_ = CompileJobStatus::kReadyToCompile;
} }
InternalizeParsingResult(); DeferredHandleScope scope(isolate_);
{
status_ = CompileJobStatus::kReadyToCompile; // Create a canonical handle scope before internalizing parsed values if
} // compiling bytecode. This is required for off-thread bytecode generation.
std::unique_ptr<CanonicalHandleScope> canonical;
void CompilerDispatcherJob::ReportErrorsOnMainThread() { if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(isolate_));
DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
DCHECK(status() == CompileJobStatus::kFailed); Handle<SharedFunctionInfo> shared(function_->shared(), isolate_);
Handle<Script> script(Script::cast(shared->script()), isolate_);
// Internalizing the parsing result will throw the error.
InternalizeParsingResult(); 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();
}
handles_from_parsing_.reset(scope.Detach());
status_ = CompileJobStatus::kDone; return status_ != CompileJobStatus::kFailed;
} }
void CompilerDispatcherJob::ResetOnMainThread() { void CompilerDispatcherJob::ResetOnMainThread() {
...@@ -156,6 +171,7 @@ void CompilerDispatcherJob::ResetOnMainThread() { ...@@ -156,6 +171,7 @@ void CompilerDispatcherJob::ResetOnMainThread() {
character_stream_.reset(); character_stream_.reset();
parse_info_.reset(); parse_info_.reset();
zone_.reset(); zone_.reset();
handles_from_parsing_.reset();
if (!source_.is_null()) { if (!source_.is_null()) {
i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location()); i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location());
...@@ -165,35 +181,5 @@ void CompilerDispatcherJob::ResetOnMainThread() { ...@@ -165,35 +181,5 @@ void CompilerDispatcherJob::ResetOnMainThread() {
status_ = CompileJobStatus::kInitial; status_ = CompileJobStatus::kInitial;
} }
void CompilerDispatcherJob::InternalizeParsingResult() {
DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
DCHECK(status() == CompileJobStatus::kParsed ||
status() == CompileJobStatus::kFailed);
HandleScope scope(isolate_);
// Create a canonical handle scope before internalizing parsed values if
// compiling bytecode. This is required for off-thread bytecode generation.
std::unique_ptr<CanonicalHandleScope> canonical;
if (FLAG_ignition) canonical.reset(new CanonicalHandleScope(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 internal
} // namespace v8 } // namespace v8
...@@ -50,11 +50,9 @@ class CompilerDispatcherJob { ...@@ -50,11 +50,9 @@ class CompilerDispatcherJob {
// Transition from kReadyToParse to kParsed. // Transition from kReadyToParse to kParsed.
void Parse(); void Parse();
// Transition from kParsed to kReadyToCompile (or kFailed). // Transition from kParsed to kReadyToCompile (or kFailed). Returns false
void FinalizeParsingOnMainThread(); // when transitioning to kFailed. In that case, an exception is pending.
bool FinalizeParsingOnMainThread();
// Transition from kFailed to kDone.
void ReportErrorsOnMainThread();
// Transition from any state to kInitial and free all resources. // Transition from any state to kInitial and free all resources.
void ResetOnMainThread(); void ResetOnMainThread();
...@@ -62,8 +60,6 @@ class CompilerDispatcherJob { ...@@ -62,8 +60,6 @@ class CompilerDispatcherJob {
private: private:
FRIEND_TEST(CompilerDispatcherJobTest, ScopeChain); FRIEND_TEST(CompilerDispatcherJobTest, ScopeChain);
void InternalizeParsingResult();
CompileJobStatus status_ = CompileJobStatus::kInitial; CompileJobStatus status_ = CompileJobStatus::kInitial;
Isolate* isolate_; Isolate* isolate_;
Handle<JSFunction> function_; // Global handle. Handle<JSFunction> function_; // Global handle.
...@@ -76,6 +72,7 @@ class CompilerDispatcherJob { ...@@ -76,6 +72,7 @@ class CompilerDispatcherJob {
std::unique_ptr<Utf16CharacterStream> character_stream_; std::unique_ptr<Utf16CharacterStream> character_stream_;
std::unique_ptr<ParseInfo> parse_info_; std::unique_ptr<ParseInfo> parse_info_;
std::unique_ptr<Parser> parser_; std::unique_ptr<Parser> parser_;
std::unique_ptr<DeferredHandles> handles_from_parsing_;
bool can_parse_on_background_thread_; bool can_parse_on_background_thread_;
......
...@@ -92,7 +92,7 @@ TEST_F(CompilerDispatcherJobTest, StateTransitions) { ...@@ -92,7 +92,7 @@ TEST_F(CompilerDispatcherJobTest, StateTransitions) {
ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToParse); ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToParse);
job->Parse(); job->Parse();
ASSERT_TRUE(job->status() == CompileJobStatus::kParsed); ASSERT_TRUE(job->status() == CompileJobStatus::kParsed);
job->FinalizeParsingOnMainThread(); ASSERT_TRUE(job->FinalizeParsingOnMainThread());
ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToCompile); ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToCompile);
job->ResetOnMainThread(); job->ResetOnMainThread();
ASSERT_TRUE(job->status() == CompileJobStatus::kInitial); ASSERT_TRUE(job->status() == CompileJobStatus::kInitial);
...@@ -105,14 +105,14 @@ TEST_F(CompilerDispatcherJobTest, SyntaxError) { ...@@ -105,14 +105,14 @@ TEST_F(CompilerDispatcherJobTest, SyntaxError) {
job->PrepareToParseOnMainThread(); job->PrepareToParseOnMainThread();
job->Parse(); job->Parse();
job->FinalizeParsingOnMainThread(); ASSERT_FALSE(job->FinalizeParsingOnMainThread());
ASSERT_TRUE(job->status() == CompileJobStatus::kFailed); ASSERT_TRUE(job->status() == CompileJobStatus::kFailed);
ASSERT_FALSE(i_isolate()->has_pending_exception());
job->ReportErrorsOnMainThread();
ASSERT_TRUE(job->status() == CompileJobStatus::kDone);
ASSERT_TRUE(i_isolate()->has_pending_exception()); ASSERT_TRUE(i_isolate()->has_pending_exception());
i_isolate()->clear_pending_exception(); i_isolate()->clear_pending_exception();
job->ResetOnMainThread();
ASSERT_TRUE(job->status() == CompileJobStatus::kInitial);
} }
TEST_F(CompilerDispatcherJobTest, ScopeChain) { TEST_F(CompilerDispatcherJobTest, ScopeChain) {
...@@ -133,7 +133,7 @@ TEST_F(CompilerDispatcherJobTest, ScopeChain) { ...@@ -133,7 +133,7 @@ TEST_F(CompilerDispatcherJobTest, ScopeChain) {
job->PrepareToParseOnMainThread(); job->PrepareToParseOnMainThread();
job->Parse(); job->Parse();
job->FinalizeParsingOnMainThread(); ASSERT_TRUE(job->FinalizeParsingOnMainThread());
ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToCompile); ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToCompile);
const AstRawString* var_x = const AstRawString* var_x =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment