Commit 58b12f63 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[offthread] Unify compiler.cc finalization logic

This patch unfies the finalization logic between the various unoptimized
compilation paths in compiler.cc, taking the various post-processings and
fixups needed for off-thread finalization and performing them in the same
order for the other finalizations.

It also unifies the general compilation path between streaming script
compilation, main-thread script compilation, and main-thread lazy
compilation, making the main-thread paths both use an iterative execution
and finalization, and making all three use the same job helper methods
and overall finalization helper.

Bug: chromium:1011762
Change-Id: Ibe56f6d2f75a2deffbe9e0b600ded8a02293b722
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2172790
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67609}
parent 65d738d4
...@@ -224,7 +224,7 @@ class AsmJsCompilationJob final : public UnoptimizedCompilationJob { ...@@ -224,7 +224,7 @@ class AsmJsCompilationJob final : public UnoptimizedCompilationJob {
UnoptimizedCompilationJob::Status AsmJsCompilationJob::ExecuteJobImpl() { UnoptimizedCompilationJob::Status AsmJsCompilationJob::ExecuteJobImpl() {
// Step 1: Translate asm.js module to WebAssembly module. // Step 1: Translate asm.js module to WebAssembly module.
Zone* compile_zone = compilation_info()->zone(); Zone* compile_zone = &zone_;
Zone translate_zone(allocator_, ZONE_NAME); Zone translate_zone(allocator_, ZONE_NAME);
Utf16CharacterStream* stream = parse_info()->character_stream(); Utf16CharacterStream* stream = parse_info()->character_stream();
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "src/ast/ast-value-factory.h" #include "src/ast/ast-value-factory.h"
#include "src/base/logging.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/execution/off-thread-isolate.h" #include "src/execution/off-thread-isolate.h"
#include "src/heap/factory-inl.h" #include "src/heap/factory-inl.h"
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <forward_list> #include <forward_list>
#include "src/base/hashmap.h" #include "src/base/hashmap.h"
#include "src/base/logging.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/heap/factory.h" #include "src/heap/factory.h"
#include "src/numbers/conversions.h" #include "src/numbers/conversions.h"
......
This diff is collapsed.
...@@ -276,6 +276,13 @@ class UnoptimizedCompilationJob : public CompilationJob { ...@@ -276,6 +276,13 @@ class UnoptimizedCompilationJob : public CompilationJob {
uintptr_t stack_limit() const { return stack_limit_; } uintptr_t stack_limit() const { return stack_limit_; }
base::TimeDelta time_taken_to_execute() const {
return time_taken_to_execute_;
}
base::TimeDelta time_taken_to_finalize() const {
return time_taken_to_finalize_;
}
bool can_off_thread_finalize() const { return can_off_thread_finalize_; } bool can_off_thread_finalize() const { return can_off_thread_finalize_; }
protected: protected:
...@@ -354,6 +361,15 @@ class OptimizedCompilationJob : public CompilationJob { ...@@ -354,6 +361,15 @@ class OptimizedCompilationJob : public CompilationJob {
const char* compiler_name_; const char* compiler_name_;
}; };
struct FinalizeUnoptimizedCompilationData {
int function_literal_id;
base::TimeDelta time_taken_to_execute;
base::TimeDelta time_taken_to_finalize;
};
using FinalizeUnoptimizedCompilationDataList =
std::vector<FinalizeUnoptimizedCompilationData>;
class V8_EXPORT_PRIVATE BackgroundCompileTask { class V8_EXPORT_PRIVATE BackgroundCompileTask {
public: public:
// Creates a new task that when run will parse and compile the streamed // Creates a new task that when run will parse and compile the streamed
...@@ -386,18 +402,14 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask { ...@@ -386,18 +402,14 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
return &inner_function_jobs_; return &inner_function_jobs_;
} }
UnoptimizedCompileFlags flags() const { return flags_; } UnoptimizedCompileFlags flags() const { return flags_; }
const UnoptimizedCompileState* compile_state() const {
return &compile_state_;
}
LanguageMode language_mode() { return language_mode_; } LanguageMode language_mode() { return language_mode_; }
bool collected_source_positions() { return collected_source_positions_; }
bool finalize_on_background_thread() { bool finalize_on_background_thread() {
return finalize_on_background_thread_; return finalize_on_background_thread_;
} }
OffThreadIsolate* off_thread_isolate() { return off_thread_isolate_.get(); } OffThreadIsolate* off_thread_isolate() { return off_thread_isolate_.get(); }
PendingCompilationErrorHandler* pending_error_handler() {
return compile_state_.pending_error_handler();
}
UnoptimizedCompileState::ParallelTasks* parallel_tasks() {
return compile_state_.parallel_tasks();
}
MaybeHandle<SharedFunctionInfo> outer_function_sfi() { MaybeHandle<SharedFunctionInfo> outer_function_sfi() {
DCHECK_NOT_NULL(off_thread_isolate_); DCHECK_NOT_NULL(off_thread_isolate_);
return outer_function_sfi_.ToHandle(); return outer_function_sfi_.ToHandle();
...@@ -406,6 +418,10 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask { ...@@ -406,6 +418,10 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
DCHECK_NOT_NULL(off_thread_isolate_); DCHECK_NOT_NULL(off_thread_isolate_);
return script_.ToHandle(); return script_.ToHandle();
} }
FinalizeUnoptimizedCompilationDataList*
finalize_unoptimized_compilation_data() {
return &finalize_unoptimized_compilation_data_;
}
private: private:
// Data needed for parsing, and data needed to to be passed between thread // Data needed for parsing, and data needed to to be passed between thread
...@@ -427,6 +443,7 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask { ...@@ -427,6 +443,7 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
std::unique_ptr<OffThreadIsolate> off_thread_isolate_; std::unique_ptr<OffThreadIsolate> off_thread_isolate_;
OffThreadTransferMaybeHandle<SharedFunctionInfo> outer_function_sfi_; OffThreadTransferMaybeHandle<SharedFunctionInfo> outer_function_sfi_;
OffThreadTransferHandle<Script> script_; OffThreadTransferHandle<Script> script_;
FinalizeUnoptimizedCompilationDataList finalize_unoptimized_compilation_data_;
// Single function data for top-level function compilation. // Single function data for top-level function compilation.
int start_position_; int start_position_;
...@@ -437,7 +454,6 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask { ...@@ -437,7 +454,6 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats_; WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats_;
TimedHistogram* timer_; TimedHistogram* timer_;
LanguageMode language_mode_; LanguageMode language_mode_;
bool collected_source_positions_;
// True if the background compilation should be finalized on the background // True if the background compilation should be finalized on the background
// thread. When this is true, the ParseInfo, Parser and compilation jobs are // thread. When this is true, the ParseInfo, Parser and compilation jobs are
......
...@@ -18,7 +18,7 @@ namespace internal { ...@@ -18,7 +18,7 @@ namespace internal {
UnoptimizedCompilationInfo::UnoptimizedCompilationInfo(Zone* zone, UnoptimizedCompilationInfo::UnoptimizedCompilationInfo(Zone* zone,
ParseInfo* parse_info, ParseInfo* parse_info,
FunctionLiteral* literal) FunctionLiteral* literal)
: flags_(parse_info->flags()), zone_(zone), feedback_vector_spec_(zone) { : flags_(parse_info->flags()), feedback_vector_spec_(zone) {
// NOTE: The parse_info passed here represents the global information gathered // NOTE: The parse_info passed here represents the global information gathered
// during parsing, but does not represent specific details of the actual // during parsing, but does not represent specific details of the actual
// function literal being compiled for this OptimizedCompilationInfo. As such, // function literal being compiled for this OptimizedCompilationInfo. As such,
......
...@@ -34,8 +34,6 @@ class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final { ...@@ -34,8 +34,6 @@ class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final {
UnoptimizedCompilationInfo(Zone* zone, ParseInfo* parse_info, UnoptimizedCompilationInfo(Zone* zone, ParseInfo* parse_info,
FunctionLiteral* literal); FunctionLiteral* literal);
Zone* zone() { return zone_; }
const UnoptimizedCompileFlags& flags() const { return flags_; } const UnoptimizedCompileFlags& flags() const { return flags_; }
// Accessors for the input data of the function being compiled. // Accessors for the input data of the function being compiled.
...@@ -87,10 +85,6 @@ class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final { ...@@ -87,10 +85,6 @@ class V8_EXPORT_PRIVATE UnoptimizedCompilationInfo final {
// Compilation flags. // Compilation flags.
const UnoptimizedCompileFlags flags_; const UnoptimizedCompileFlags flags_;
// The zone from which the compilation pipeline working on this
// OptimizedCompilationInfo allocates.
Zone* zone_;
// The root AST node of the function literal being compiled. // The root AST node of the function literal being compiled.
FunctionLiteral* literal_; FunctionLiteral* literal_;
......
...@@ -504,10 +504,14 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source, ...@@ -504,10 +504,14 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
i_isolate, true, i::construct_language_mode(i::FLAG_use_strict), i_isolate, true, i::construct_language_mode(i::FLAG_use_strict),
i::REPLMode::kNo); i::REPLMode::kNo);
if (options.compile_options == v8::ScriptCompiler::kEagerCompile) {
flags.set_is_eager(true);
}
i::ParseInfo parse_info(i_isolate, flags, &compile_state); i::ParseInfo parse_info(i_isolate, flags, &compile_state);
i::Handle<i::Script> script = parse_info.CreateScript( i::Handle<i::Script> script = parse_info.CreateScript(
i_isolate, str, i::kNullMaybeHandle, options.compile_options); i_isolate, str, i::kNullMaybeHandle, ScriptOriginOptions());
if (!i::parsing::ParseProgram(&parse_info, script, i_isolate)) { if (!i::parsing::ParseProgram(&parse_info, script, i_isolate)) {
fprintf(stderr, "Failed parsing\n"); fprintf(stderr, "Failed parsing\n");
return false; return false;
......
...@@ -105,6 +105,8 @@ class V8_EXPORT_PRIVATE OffThreadIsolate final ...@@ -105,6 +105,8 @@ class V8_EXPORT_PRIVATE OffThreadIsolate final
// on the main thread. // on the main thread.
void Publish(Isolate* isolate); void Publish(Isolate* isolate);
bool has_pending_exception() const { return false; }
template <typename T> template <typename T>
Handle<T> Throw(Handle<Object> exception) { Handle<T> Throw(Handle<Object> exception) {
UNREACHABLE(); UNREACHABLE();
......
...@@ -1040,10 +1040,10 @@ static bool IsInEagerLiterals( ...@@ -1040,10 +1040,10 @@ static bool IsInEagerLiterals(
#endif // DEBUG #endif // DEBUG
BytecodeGenerator::BytecodeGenerator( BytecodeGenerator::BytecodeGenerator(
UnoptimizedCompilationInfo* info, Zone* compile_zone, UnoptimizedCompilationInfo* info,
const AstStringConstants* ast_string_constants, const AstStringConstants* ast_string_constants,
std::vector<FunctionLiteral*>* eager_inner_literals) std::vector<FunctionLiteral*>* eager_inner_literals)
: zone_(info->zone()), : zone_(compile_zone),
builder_(zone(), info->num_parameters_including_this(), builder_(zone(), info->num_parameters_including_this(),
info->scope()->num_stack_slots(), info->feedback_vector_spec(), info->scope()->num_stack_slots(), info->feedback_vector_spec(),
info->SourcePositionRecordingMode()), info->SourcePositionRecordingMode()),
......
...@@ -32,7 +32,7 @@ class BytecodeJumpTable; ...@@ -32,7 +32,7 @@ class BytecodeJumpTable;
class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
public: public:
explicit BytecodeGenerator( explicit BytecodeGenerator(
UnoptimizedCompilationInfo* info, Zone* zone, UnoptimizedCompilationInfo* info,
const AstStringConstants* ast_string_constants, const AstStringConstants* ast_string_constants,
std::vector<FunctionLiteral*>* eager_inner_literals); std::vector<FunctionLiteral*>* eager_inner_literals);
......
...@@ -152,7 +152,7 @@ InterpreterCompilationJob::InterpreterCompilationJob( ...@@ -152,7 +152,7 @@ InterpreterCompilationJob::InterpreterCompilationJob(
&compilation_info_, CanOffThreadFinalize::kYes), &compilation_info_, CanOffThreadFinalize::kYes),
zone_(allocator, ZONE_NAME), zone_(allocator, ZONE_NAME),
compilation_info_(&zone_, parse_info, literal), compilation_info_(&zone_, parse_info, literal),
generator_(&compilation_info_, parse_info->ast_string_constants(), generator_(&zone_, &compilation_info_, parse_info->ast_string_constants(),
eager_inner_literals) {} eager_inner_literals) {}
InterpreterCompilationJob::Status InterpreterCompilationJob::ExecuteJobImpl() { InterpreterCompilationJob::Status InterpreterCompilationJob::ExecuteJobImpl() {
......
...@@ -4907,14 +4907,14 @@ Object Script::GetNameOrSourceURL() { ...@@ -4907,14 +4907,14 @@ Object Script::GetNameOrSourceURL() {
template <typename LocalIsolate> template <typename LocalIsolate>
MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo( MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
LocalIsolate* isolate, const FunctionLiteral* fun) { LocalIsolate* isolate, int function_literal_id) {
CHECK_NE(fun->function_literal_id(), kFunctionLiteralIdInvalid); CHECK_NE(function_literal_id, kFunctionLiteralIdInvalid);
// If this check fails, the problem is most probably the function id // If this check fails, the problem is most probably the function id
// renumbering done by AstFunctionLiteralIdReindexer; in particular, that // renumbering done by AstFunctionLiteralIdReindexer; in particular, that
// AstTraversalVisitor doesn't recurse properly in the construct which // AstTraversalVisitor doesn't recurse properly in the construct which
// triggers the mismatch. // triggers the mismatch.
CHECK_LT(fun->function_literal_id(), shared_function_infos().length()); CHECK_LT(function_literal_id, shared_function_infos().length());
MaybeObject shared = shared_function_infos().Get(fun->function_literal_id()); MaybeObject shared = shared_function_infos().Get(function_literal_id);
HeapObject heap_object; HeapObject heap_object;
if (!shared->GetHeapObject(&heap_object) || if (!shared->GetHeapObject(&heap_object) ||
heap_object.IsUndefined(isolate)) { heap_object.IsUndefined(isolate)) {
...@@ -4923,9 +4923,9 @@ MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo( ...@@ -4923,9 +4923,9 @@ MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
return handle(SharedFunctionInfo::cast(heap_object), isolate); return handle(SharedFunctionInfo::cast(heap_object), isolate);
} }
template MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo( template MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
Isolate* isolate, const FunctionLiteral* fun); Isolate* isolate, int function_literal_id);
template MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo( template MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
OffThreadIsolate* isolate, const FunctionLiteral* fun); OffThreadIsolate* isolate, int function_literal_id);
Script::Iterator::Iterator(Isolate* isolate) Script::Iterator::Iterator(Isolate* isolate)
: iterator_(isolate->heap()->script_list()) {} : iterator_(isolate->heap()->script_list()) {}
......
...@@ -201,7 +201,7 @@ class Script : public Struct { ...@@ -201,7 +201,7 @@ class Script : public Struct {
// that matches the function literal. Return empty handle if not found. // that matches the function literal. Return empty handle if not found.
template <typename LocalIsolate> template <typename LocalIsolate>
MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo( MaybeHandle<SharedFunctionInfo> FindSharedFunctionInfo(
LocalIsolate* isolate, const FunctionLiteral* fun); LocalIsolate* isolate, int function_literal_id);
// Iterate over all script objects on the heap. // Iterate over all script objects on the heap.
class V8_EXPORT_PRIVATE Iterator { class V8_EXPORT_PRIVATE Iterator {
......
...@@ -188,6 +188,9 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileState { ...@@ -188,6 +188,9 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileState {
PendingCompilationErrorHandler* pending_error_handler() { PendingCompilationErrorHandler* pending_error_handler() {
return &pending_error_handler_; return &pending_error_handler_;
} }
const PendingCompilationErrorHandler* pending_error_handler() const {
return &pending_error_handler_;
}
ParallelTasks* parallel_tasks() const { return parallel_tasks_.get(); } ParallelTasks* parallel_tasks() const { return parallel_tasks_.get(); }
private: private:
......
...@@ -27,8 +27,9 @@ void MaybeReportErrorsAndStatistics(ParseInfo* info, Handle<Script> script, ...@@ -27,8 +27,9 @@ void MaybeReportErrorsAndStatistics(ParseInfo* info, Handle<Script> script,
ReportErrorsAndStatisticsMode mode) { ReportErrorsAndStatisticsMode mode) {
if (mode == ReportErrorsAndStatisticsMode::kYes) { if (mode == ReportErrorsAndStatisticsMode::kYes) {
if (info->literal() == nullptr) { if (info->literal() == nullptr) {
info->pending_error_handler()->ReportErrors(isolate, script, info->pending_error_handler()->PrepareErrors(isolate,
info->ast_value_factory()); info->ast_value_factory());
info->pending_error_handler()->ReportErrors(isolate, script);
} }
parser->UpdateStatistics(isolate, script); parser->UpdateStatistics(isolate, script);
} }
......
...@@ -9,35 +9,63 @@ ...@@ -9,35 +9,63 @@
#include "src/debug/debug.h" #include "src/debug/debug.h"
#include "src/execution/isolate.h" #include "src/execution/isolate.h"
#include "src/execution/messages.h" #include "src/execution/messages.h"
#include "src/execution/off-thread-isolate.h"
#include "src/handles/handles.h" #include "src/handles/handles.h"
#include "src/heap/off-thread-factory-inl.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
void PendingCompilationErrorHandler::MessageDetails::TransferOffThreadHandle( void PendingCompilationErrorHandler::MessageDetails::SetString(
OffThreadIsolate* isolate) { Handle<String> string, Isolate* isolate) {
DCHECK_NE(type_, kMainThreadHandle); DCHECK_NE(type_, kMainThreadHandle);
if (type_ != kAstRawString) return; DCHECK_NE(type_, kOffThreadTransferHandle);
arg_transfer_handle_ = isolate->TransferHandle(arg_->string()); type_ = kMainThreadHandle;
arg_handle_ = string;
}
void PendingCompilationErrorHandler::MessageDetails::SetString(
Handle<String> string, OffThreadIsolate* isolate) {
DCHECK_NE(type_, kMainThreadHandle);
DCHECK_NE(type_, kOffThreadTransferHandle);
type_ = kOffThreadTransferHandle; type_ = kOffThreadTransferHandle;
arg_transfer_handle_ = isolate->TransferHandle(string);
} }
Handle<String> PendingCompilationErrorHandler::MessageDetails::ArgumentString( template <typename LocalIsolate>
Isolate* isolate) const { void PendingCompilationErrorHandler::MessageDetails::Prepare(
LocalIsolate* isolate) {
switch (type_) { switch (type_) {
case kAstRawString: case kAstRawString:
return arg_->string(); return SetString(arg_->string(), isolate);
case kNone: case kNone:
return isolate->factory()->undefined_string();
case kConstCharString: case kConstCharString:
return isolate->factory() // We can delay allocation until ArgumentString(isolate).
->NewStringFromUtf8(CStrVector(char_arg_)) // TODO(leszeks): We don't actually have to transfer this string, since
.ToHandleChecked(); // it's a root.
return;
case kMainThreadHandle:
case kOffThreadTransferHandle:
UNREACHABLE();
}
}
Handle<String> PendingCompilationErrorHandler::MessageDetails::ArgumentString(
Isolate* isolate) const {
switch (type_) {
case kMainThreadHandle: case kMainThreadHandle:
return arg_handle_; return arg_handle_;
case kOffThreadTransferHandle: case kOffThreadTransferHandle:
return arg_transfer_handle_.ToHandle(); return arg_transfer_handle_.ToHandle();
case kNone:
return isolate->factory()->undefined_string();
case kConstCharString:
return isolate->factory()
->NewStringFromUtf8(CStrVector(char_arg_), AllocationType::kOld)
.ToHandleChecked();
case kAstRawString:
UNREACHABLE();
} }
} }
...@@ -74,8 +102,20 @@ void PendingCompilationErrorHandler::ReportWarningAt(int start_position, ...@@ -74,8 +102,20 @@ void PendingCompilationErrorHandler::ReportWarningAt(int start_position,
MessageDetails(start_position, end_position, message, arg)); MessageDetails(start_position, end_position, message, arg));
} }
void PendingCompilationErrorHandler::ReportWarnings(Isolate* isolate, template <typename LocalIsolate>
Handle<Script> script) { void PendingCompilationErrorHandler::PrepareWarnings(LocalIsolate* isolate) {
DCHECK(!has_pending_error());
for (MessageDetails& warning : warning_messages_) {
warning.Prepare(isolate);
}
}
template void PendingCompilationErrorHandler::PrepareWarnings(Isolate* isolate);
template void PendingCompilationErrorHandler::PrepareWarnings(
OffThreadIsolate* isolate);
void PendingCompilationErrorHandler::ReportWarnings(
Isolate* isolate, Handle<Script> script) const {
DCHECK(!has_pending_error()); DCHECK(!has_pending_error());
for (const MessageDetails& warning : warning_messages_) { for (const MessageDetails& warning : warning_messages_) {
...@@ -89,53 +129,33 @@ void PendingCompilationErrorHandler::ReportWarnings(Isolate* isolate, ...@@ -89,53 +129,33 @@ void PendingCompilationErrorHandler::ReportWarnings(Isolate* isolate,
} }
} }
void PendingCompilationErrorHandler::ReportWarnings(OffThreadIsolate* isolate, template <typename LocalIsolate>
Handle<Script> script) { void PendingCompilationErrorHandler::PrepareErrors(
// Change any AstRawStrings to raw object pointers before the Ast Zone dies, LocalIsolate* isolate, AstValueFactory* ast_value_factory) {
// re-report later on the main thread. if (stack_overflow()) return;
DCHECK(!has_pending_error());
for (MessageDetails& warning : warning_messages_) {
warning.TransferOffThreadHandle(isolate);
}
}
void PendingCompilationErrorHandler::ReportErrors(
Isolate* isolate, Handle<Script> script,
AstValueFactory* ast_value_factory) {
if (stack_overflow()) {
isolate->StackOverflow();
} else {
DCHECK(has_pending_error()); DCHECK(has_pending_error());
// Internalize ast values for throwing the pending error. // Internalize ast values for throwing the pending error.
ast_value_factory->Internalize(isolate); ast_value_factory->Internalize(isolate);
ThrowPendingError(isolate, script); error_details_.Prepare(isolate);
}
} }
template void PendingCompilationErrorHandler::PrepareErrors(
Isolate* isolate, AstValueFactory* ast_value_factory);
template void PendingCompilationErrorHandler::PrepareErrors(
OffThreadIsolate* isolate, AstValueFactory* ast_value_factory);
void PendingCompilationErrorHandler::PrepareErrorsOffThread( void PendingCompilationErrorHandler::ReportErrors(Isolate* isolate,
OffThreadIsolate* isolate, Handle<Script> script, Handle<Script> script) const {
AstValueFactory* ast_value_factory) {
if (!stack_overflow()) {
DCHECK(has_pending_error());
// Internalize ast values for later throwing the pending error.
ast_value_factory->Internalize(isolate);
error_details_.TransferOffThreadHandle(isolate);
}
}
void PendingCompilationErrorHandler::ReportErrorsAfterOffThreadFinalization(
Isolate* isolate, Handle<Script> script) {
if (stack_overflow()) { if (stack_overflow()) {
isolate->StackOverflow(); isolate->StackOverflow();
} else { } else {
DCHECK(has_pending_error()); DCHECK(has_pending_error());
// Ast values should already be internalized.
ThrowPendingError(isolate, script); ThrowPendingError(isolate, script);
} }
} }
void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate, void PendingCompilationErrorHandler::ThrowPendingError(
Handle<Script> script) { Isolate* isolate, Handle<Script> script) const {
if (!has_pending_error_) return; if (!has_pending_error_) return;
MessageLocation location = error_details_.GetLocation(script); MessageLocation location = error_details_.GetLocation(script);
...@@ -149,7 +169,8 @@ void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate, ...@@ -149,7 +169,8 @@ void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate,
} }
Handle<String> PendingCompilationErrorHandler::FormatErrorMessageForTest( Handle<String> PendingCompilationErrorHandler::FormatErrorMessageForTest(
Isolate* isolate) const { Isolate* isolate) {
error_details_.Prepare(isolate);
return MessageFormatter::Format(isolate, error_details_.message(), return MessageFormatter::Format(isolate, error_details_.message(),
error_details_.ArgumentString(isolate)); error_details_.ArgumentString(isolate));
} }
......
...@@ -48,23 +48,16 @@ class PendingCompilationErrorHandler { ...@@ -48,23 +48,16 @@ class PendingCompilationErrorHandler {
bool has_pending_warnings() const { return !warning_messages_.empty(); } bool has_pending_warnings() const { return !warning_messages_.empty(); }
// Handle errors detected during parsing. // Handle errors detected during parsing.
void ReportErrors(Isolate* isolate, Handle<Script> script, template <typename LocalIsolate>
AstValueFactory* ast_value_factory); void PrepareErrors(LocalIsolate* isolate, AstValueFactory* ast_value_factory);
// Prepare errors detected during off-thread parsing, to be reported later on void ReportErrors(Isolate* isolate, Handle<Script> script) const;
// the main thread.
void PrepareErrorsOffThread(OffThreadIsolate* isolate, Handle<Script> script,
AstValueFactory* ast_value_factory);
// Report errors detected during off-thread parsing, which were prepared
// off-thread during finalization by the above method.
void ReportErrorsAfterOffThreadFinalization(Isolate* isolate,
Handle<Script> script);
// Handle warnings detected during compilation. // Handle warnings detected during compilation.
void ReportWarnings(Isolate* isolate, Handle<Script> script); template <typename LocalIsolate>
void ReportWarnings(OffThreadIsolate* isolate, Handle<Script> script); void PrepareWarnings(LocalIsolate* isolate);
void ReportWarnings(Isolate* isolate, Handle<Script> script) const;
V8_EXPORT_PRIVATE Handle<String> FormatErrorMessageForTest( V8_EXPORT_PRIVATE Handle<String> FormatErrorMessageForTest(Isolate* isolate);
Isolate* isolate) const;
void set_unidentifiable_error() { void set_unidentifiable_error() {
has_pending_error_ = true; has_pending_error_ = true;
...@@ -106,32 +99,34 @@ class PendingCompilationErrorHandler { ...@@ -106,32 +99,34 @@ class PendingCompilationErrorHandler {
MessageLocation GetLocation(Handle<Script> script) const; MessageLocation GetLocation(Handle<Script> script) const;
MessageTemplate message() const { return message_; } MessageTemplate message() const { return message_; }
// After off-thread finalization, the Ast Zone will be deleted, so before template <typename LocalIsolate>
// that happens we have to transfer any string handles. void Prepare(LocalIsolate* isolate);
void TransferOffThreadHandle(OffThreadIsolate* isolate);
private: private:
enum Type { enum Type {
kNone, kNone,
kAstRawString, kAstRawString,
kConstCharString, kConstCharString,
kOffThreadTransferHandle, kMainThreadHandle,
kMainThreadHandle kOffThreadTransferHandle
}; };
void SetString(Handle<String> string, Isolate* isolate);
void SetString(Handle<String> string, OffThreadIsolate* isolate);
int start_position_; int start_position_;
int end_position_; int end_position_;
MessageTemplate message_; MessageTemplate message_;
union { union {
const AstRawString* arg_; const AstRawString* arg_;
const char* char_arg_; const char* char_arg_;
OffThreadTransferHandle<String> arg_transfer_handle_;
Handle<String> arg_handle_; Handle<String> arg_handle_;
OffThreadTransferHandle<String> arg_transfer_handle_;
}; };
Type type_; Type type_;
}; };
void ThrowPendingError(Isolate* isolate, Handle<Script> script); void ThrowPendingError(Isolate* isolate, Handle<Script> script) const;
bool has_pending_error_; bool has_pending_error_;
bool stack_overflow_; bool stack_overflow_;
......
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