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() {
status_ = CompileJobStatus::kParsed;
}
void CompilerDispatcherJob::FinalizeParsingOnMainThread() {
bool CompilerDispatcherJob::FinalizeParsingOnMainThread() {
DCHECK(ThreadId::Current().Equals(isolate_->thread_id()));
DCHECK(status() == CompileJobStatus::kParsed);
......@@ -130,22 +130,37 @@ void CompilerDispatcherJob::FinalizeParsingOnMainThread() {
if (parse_info_->literal() == nullptr) {
status_ = CompileJobStatus::kFailed;
return;
} else {
status_ = CompileJobStatus::kReadyToCompile;
}
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();
DeferredHandleScope 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();
}
handles_from_parsing_.reset(scope.Detach());
status_ = CompileJobStatus::kDone;
return status_ != CompileJobStatus::kFailed;
}
void CompilerDispatcherJob::ResetOnMainThread() {
......@@ -156,6 +171,7 @@ void CompilerDispatcherJob::ResetOnMainThread() {
character_stream_.reset();
parse_info_.reset();
zone_.reset();
handles_from_parsing_.reset();
if (!source_.is_null()) {
i::GlobalHandles::Destroy(Handle<Object>::cast(source_).location());
......@@ -165,35 +181,5 @@ void CompilerDispatcherJob::ResetOnMainThread() {
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 v8
......@@ -50,11 +50,9 @@ class CompilerDispatcherJob {
// Transition from kReadyToParse to kParsed.
void Parse();
// Transition from kParsed to kReadyToCompile (or kFailed).
void FinalizeParsingOnMainThread();
// Transition from kFailed to kDone.
void ReportErrorsOnMainThread();
// Transition from kParsed to kReadyToCompile (or kFailed). Returns false
// when transitioning to kFailed. In that case, an exception is pending.
bool FinalizeParsingOnMainThread();
// Transition from any state to kInitial and free all resources.
void ResetOnMainThread();
......@@ -62,8 +60,6 @@ class CompilerDispatcherJob {
private:
FRIEND_TEST(CompilerDispatcherJobTest, ScopeChain);
void InternalizeParsingResult();
CompileJobStatus status_ = CompileJobStatus::kInitial;
Isolate* isolate_;
Handle<JSFunction> function_; // Global handle.
......@@ -76,6 +72,7 @@ class CompilerDispatcherJob {
std::unique_ptr<Utf16CharacterStream> character_stream_;
std::unique_ptr<ParseInfo> parse_info_;
std::unique_ptr<Parser> parser_;
std::unique_ptr<DeferredHandles> handles_from_parsing_;
bool can_parse_on_background_thread_;
......
......@@ -92,7 +92,7 @@ TEST_F(CompilerDispatcherJobTest, StateTransitions) {
ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToParse);
job->Parse();
ASSERT_TRUE(job->status() == CompileJobStatus::kParsed);
job->FinalizeParsingOnMainThread();
ASSERT_TRUE(job->FinalizeParsingOnMainThread());
ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToCompile);
job->ResetOnMainThread();
ASSERT_TRUE(job->status() == CompileJobStatus::kInitial);
......@@ -105,14 +105,14 @@ TEST_F(CompilerDispatcherJobTest, SyntaxError) {
job->PrepareToParseOnMainThread();
job->Parse();
job->FinalizeParsingOnMainThread();
ASSERT_FALSE(job->FinalizeParsingOnMainThread());
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());
i_isolate()->clear_pending_exception();
job->ResetOnMainThread();
ASSERT_TRUE(job->status() == CompileJobStatus::kInitial);
}
TEST_F(CompilerDispatcherJobTest, ScopeChain) {
......@@ -133,7 +133,7 @@ TEST_F(CompilerDispatcherJobTest, ScopeChain) {
job->PrepareToParseOnMainThread();
job->Parse();
job->FinalizeParsingOnMainThread();
ASSERT_TRUE(job->FinalizeParsingOnMainThread());
ASSERT_TRUE(job->status() == CompileJobStatus::kReadyToCompile);
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