Commit 6458a529 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[compile] Add an UnoptimizedCompileState class

Move the persistent compilation state and Isolate inputs (such as the
allocator, shared AST constants, hash seed, logger, etc.) which survives
across both parse and compile, out of ParseInfo and into a new
UnoptimizedCompileState class. Also add UnoptimizedCompilePerThreadState
for per-thread state such as stack limit and RCS.

In particular, this new state survives the ParseInfo being destructed,
which means it is available after off-thread finalization. This allows a
followup to access the PendingCompilationErrorHandler after finalization
and report errors on merge.

Bug: v8:10314
Change-Id: Ia186bc0f267c704efd771aa1895f50a4525a8364
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2105636
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67329}
parent b9c3921d
......@@ -1154,14 +1154,14 @@ BackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* streamed_data,
: flags_(UnoptimizedCompileFlags::ForToplevelCompile(
isolate, true, construct_language_mode(FLAG_use_strict),
REPLMode::kNo)),
info_(std::make_unique<ParseInfo>(isolate, flags_)),
compile_state_(isolate),
info_(std::make_unique<ParseInfo>(isolate, flags_, &compile_state_)),
start_position_(0),
end_position_(0),
function_literal_id_(kFunctionLiteralIdTopLevel),
stack_size_(i::FLAG_stack_size),
worker_thread_runtime_call_stats_(
isolate->counters()->worker_thread_runtime_call_stats()),
allocator_(isolate->allocator()),
timer_(isolate->counters()->compile_script_on_background()),
language_mode_(info_->language_mode()),
collected_source_positions_(false) {
......@@ -1185,25 +1185,27 @@ BackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* streamed_data,
}
BackgroundCompileTask::BackgroundCompileTask(
AccountingAllocator* allocator, const ParseInfo* outer_parse_info,
const AstRawString* function_name, const FunctionLiteral* function_literal,
const ParseInfo* outer_parse_info, const AstRawString* function_name,
const FunctionLiteral* function_literal,
WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
TimedHistogram* timer, int max_stack_size)
: flags_(UnoptimizedCompileFlags::ForToplevelFunction(
outer_parse_info->flags(), function_literal)),
info_(ParseInfo::FromParent(outer_parse_info, flags_, allocator,
function_literal, function_name)),
compile_state_(*outer_parse_info->state()),
info_(ParseInfo::ForToplevelFunction(flags_, &compile_state_,
function_literal, function_name)),
start_position_(function_literal->start_position()),
end_position_(function_literal->end_position()),
function_literal_id_(function_literal->function_literal_id()),
stack_size_(max_stack_size),
worker_thread_runtime_call_stats_(worker_thread_runtime_stats),
allocator_(allocator),
timer_(timer),
language_mode_(info_->language_mode()),
collected_source_positions_(false),
finalize_on_background_thread_(false) {
DCHECK(outer_parse_info->flags().is_toplevel());
DCHECK_EQ(outer_parse_info->parameters_end_pos(), kNoSourcePosition);
DCHECK_NULL(outer_parse_info->extension());
DCHECK(!function_literal->is_toplevel());
// Clone the character stream so both can be accessed independently.
......@@ -1237,14 +1239,14 @@ class OffThreadParseInfoScope {
original_runtime_call_stats_(parse_info_->runtime_call_stats()),
original_stack_limit_(parse_info_->stack_limit()),
worker_thread_scope_(worker_thread_runtime_stats) {
parse_info_->set_runtime_call_stats(worker_thread_scope_.Get());
parse_info_->set_stack_limit(GetCurrentStackPosition() - stack_size * KB);
parse_info_->SetPerThreadState(GetCurrentStackPosition() - stack_size * KB,
worker_thread_scope_.Get());
}
~OffThreadParseInfoScope() {
DCHECK_NOT_NULL(parse_info_);
parse_info_->set_stack_limit(original_stack_limit_);
parse_info_->set_runtime_call_stats(original_runtime_call_stats_);
parse_info_->SetPerThreadState(original_stack_limit_,
original_runtime_call_stats_);
}
private:
......@@ -1286,8 +1288,8 @@ void BackgroundCompileTask::Run() {
function_literal_id_);
if (info_->literal() != nullptr) {
// Parsing has succeeded, compile.
outer_function_job_ = CompileOnBackgroundThread(info_.get(), allocator_,
&inner_function_jobs_);
outer_function_job_ = CompileOnBackgroundThread(
info_.get(), compile_state_.allocator(), &inner_function_jobs_);
// Save the language mode and record whether we collected source positions.
language_mode_ = info_->language_mode();
collected_source_positions_ = info_->flags().collect_source_positions();
......@@ -1404,7 +1406,8 @@ bool Compiler::CollectSourcePositions(Isolate* isolate,
flags.set_collect_source_positions(true);
flags.set_allow_natives_syntax(FLAG_allow_natives_syntax);
ParseInfo parse_info(isolate, flags);
UnoptimizedCompileState compile_state(isolate);
ParseInfo parse_info(isolate, flags, &compile_state);
// Parse and update ParseInfo with the results. Don't update parsing
// statistics since we've already parsed the code before.
......@@ -1488,7 +1491,8 @@ bool Compiler::Compile(Handle<SharedFunctionInfo> shared_info,
UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared_info);
flags.set_is_lazy_compile(true);
ParseInfo parse_info(isolate, flags);
UnoptimizedCompileState compile_state(isolate);
ParseInfo parse_info(isolate, flags, &compile_state);
// Check if the compiler dispatcher has shared_info enqueued for compile.
CompilerDispatcher* dispatcher = isolate->compiler_dispatcher();
......@@ -1741,7 +1745,8 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
flags.set_is_eval(true);
flags.set_parse_restriction(restriction);
ParseInfo parse_info(isolate, flags);
UnoptimizedCompileState compile_state(isolate);
ParseInfo parse_info(isolate, flags, &compile_state);
parse_info.set_parameters_end_pos(parameters_end_pos);
DCHECK(!parse_info.flags().is_module());
......@@ -2280,7 +2285,8 @@ MaybeHandle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
flags.set_is_module(origin_options.IsModule());
flags.set_is_eager(compile_options == ScriptCompiler::kEagerCompile);
ParseInfo parse_info(isolate, flags);
UnoptimizedCompileState compile_state(isolate);
ParseInfo parse_info(isolate, flags, &compile_state);
parse_info.set_extension(extension);
Handle<Script> script = NewScript(isolate, &parse_info, source,
......@@ -2360,7 +2366,9 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
flags.set_collect_source_positions(true);
// flags.set_eager(compile_options == ScriptCompiler::kEagerCompile);
ParseInfo parse_info(isolate, flags);
UnoptimizedCompileState compile_state(isolate);
ParseInfo parse_info(isolate, flags, &compile_state);
MaybeHandle<ScopeInfo> maybe_outer_scope_info;
if (!context->IsNativeContext()) {
maybe_outer_scope_info = handle(context->scope_info(), isolate);
......
......@@ -364,8 +364,7 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
// |function_literal| and can be finalized with
// Compiler::FinalizeBackgroundCompileTask.
BackgroundCompileTask(
AccountingAllocator* allocator, const ParseInfo* outer_parse_info,
const AstRawString* function_name,
const ParseInfo* outer_parse_info, const AstRawString* function_name,
const FunctionLiteral* function_literal,
WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
TimedHistogram* timer, int max_stack_size);
......@@ -401,6 +400,7 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
// between parsing and compilation. These need to be initialized before the
// compilation starts.
UnoptimizedCompileFlags flags_;
UnoptimizedCompileState compile_state_;
std::unique_ptr<ParseInfo> info_;
std::unique_ptr<Parser> parser_;
......@@ -423,7 +423,6 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
int stack_size_;
WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats_;
AccountingAllocator* allocator_;
TimedHistogram* timer_;
LanguageMode language_mode_;
bool collected_source_positions_;
......
......@@ -27,7 +27,6 @@ CompilerDispatcher::Job::~Job() = default;
CompilerDispatcher::CompilerDispatcher(Isolate* isolate, Platform* platform,
size_t max_stack_size)
: isolate_(isolate),
allocator_(isolate->allocator()),
worker_thread_runtime_call_stats_(
isolate->counters()->worker_thread_runtime_call_stats()),
background_compile_timer_(
......@@ -66,7 +65,7 @@ base::Optional<CompilerDispatcher::JobId> CompilerDispatcher::Enqueue(
if (!IsEnabled()) return base::nullopt;
std::unique_ptr<Job> job = std::make_unique<Job>(new BackgroundCompileTask(
allocator_, outer_parse_info, function_name, function_literal,
outer_parse_info, function_name, function_literal,
worker_thread_runtime_call_stats_, background_compile_timer_,
static_cast<int>(max_stack_size_)));
JobMap::const_iterator it = InsertJob(std::move(job));
......
......@@ -151,7 +151,6 @@ class V8_EXPORT_PRIVATE CompilerDispatcher {
JobMap::const_iterator RemoveJob(JobMap::const_iterator job);
Isolate* isolate_;
AccountingAllocator* allocator_;
WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats_;
TimedHistogram* background_compile_timer_;
std::shared_ptr<v8::TaskRunner> taskrunner_;
......
......@@ -544,12 +544,14 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
i::Handle<i::String> str = Utils::OpenHandle(*(source));
// Set up ParseInfo.
i::UnoptimizedCompileState compile_state(i_isolate);
i::UnoptimizedCompileFlags flags =
i::UnoptimizedCompileFlags::ForToplevelCompile(
i_isolate, true, i::construct_language_mode(i::FLAG_use_strict),
i::REPLMode::kNo);
i::ParseInfo parse_info(i_isolate, flags);
i::ParseInfo parse_info(i_isolate, flags, &compile_state);
i::Handle<i::Script> script = parse_info.CreateScript(
i_isolate, str, i::kNullMaybeHandle, options.compile_options);
......
......@@ -262,7 +262,9 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
scope_info->scope_type() == FUNCTION_SCOPE);
}
info_ = std::make_unique<ParseInfo>(isolate_, flags);
UnoptimizedCompileState compile_state(isolate_);
info_ = std::make_unique<ParseInfo>(isolate_, flags, &compile_state);
const bool parse_result =
flags.is_toplevel()
......
......@@ -1057,20 +1057,22 @@ void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
return;
}
UnoptimizedCompileState compile_state(isolate);
UnoptimizedCompileFlags flags =
UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
flags.set_is_eager(true);
ParseInfo parse_info(isolate, flags);
ParseInfo parse_info(isolate, flags, &compile_state);
std::vector<FunctionLiteral*> literals;
if (!ParseScript(isolate, script, &parse_info, false, &literals, result))
return;
Handle<Script> new_script = isolate->factory()->CloneScript(script);
new_script->set_source(*new_source);
UnoptimizedCompileState new_compile_state(isolate);
UnoptimizedCompileFlags new_flags =
UnoptimizedCompileFlags::ForScriptCompile(isolate, *new_script);
new_flags.set_is_eager(true);
ParseInfo new_parse_info(isolate, new_flags);
ParseInfo new_parse_info(isolate, new_flags, &new_compile_state);
std::vector<FunctionLiteral*> new_literals;
if (!ParseScript(isolate, new_script, &new_parse_info, true, &new_literals,
result)) {
......
......@@ -1252,8 +1252,10 @@ Handle<String> RenderCallSite(Isolate* isolate, Handle<Object> object,
MessageLocation* location,
CallPrinter::ErrorHint* hint) {
if (ComputeLocation(isolate, location)) {
ParseInfo info(isolate, i::UnoptimizedCompileFlags::ForFunctionCompile(
isolate, *location->shared()));
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForFunctionCompile(
isolate, *location->shared());
UnoptimizedCompileState compile_state(isolate);
ParseInfo info(isolate, flags, &compile_state);
if (parsing::ParseAny(&info, location->shared(), isolate)) {
info.ast_value_factory()->Internalize(isolate);
CallPrinter printer(isolate, location->shared()->IsUserJavaScript());
......@@ -1311,8 +1313,10 @@ Object ErrorUtils::ThrowSpreadArgIsNullOrUndefinedError(Isolate* isolate,
MessageLocation location;
Handle<String> callsite;
if (ComputeLocation(isolate, &location)) {
ParseInfo info(isolate, i::UnoptimizedCompileFlags::ForFunctionCompile(
isolate, *location.shared()));
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForFunctionCompile(
isolate, *location.shared());
UnoptimizedCompileState compile_state(isolate);
ParseInfo info(isolate, flags, &compile_state);
if (parsing::ParseAny(&info, location.shared(), isolate)) {
info.ast_value_factory()->Internalize(isolate);
CallPrinter printer(isolate, location.shared()->IsUserJavaScript(),
......@@ -1387,8 +1391,10 @@ Object ErrorUtils::ThrowLoadFromNullOrUndefined(Isolate* isolate,
if (ComputeLocation(isolate, &location)) {
location_computed = true;
ParseInfo info(isolate, i::UnoptimizedCompileFlags::ForFunctionCompile(
isolate, *location.shared()));
UnoptimizedCompileFlags flags = UnoptimizedCompileFlags::ForFunctionCompile(
isolate, *location.shared());
UnoptimizedCompileState compile_state(isolate);
ParseInfo info(isolate, flags, &compile_state);
if (parsing::ParseAny(&info, location.shared(), isolate)) {
info.ast_value_factory()->Internalize(isolate);
CallPrinter printer(isolate, location.shared()->IsUserJavaScript());
......
......@@ -156,19 +156,36 @@ void UnoptimizedCompileFlags::SetFlagsForFunctionFromScript(Script script) {
script.IsUserJavaScript());
}
ParseInfo::ParseInfo(AccountingAllocator* zone_allocator,
UnoptimizedCompileFlags flags)
UnoptimizedCompileState::UnoptimizedCompileState(Isolate* isolate)
: hash_seed_(HashSeed(isolate)),
allocator_(isolate->allocator()),
ast_string_constants_(isolate->ast_string_constants()),
logger_(isolate->logger()),
parallel_tasks_(isolate->compiler_dispatcher()->IsEnabled()
? new ParallelTasks(isolate->compiler_dispatcher())
: nullptr) {}
UnoptimizedCompileState::UnoptimizedCompileState(
const UnoptimizedCompileState& other) V8_NOEXCEPT
: hash_seed_(other.hash_seed()),
allocator_(other.allocator()),
ast_string_constants_(other.ast_string_constants()),
logger_(other.logger()),
// TODO(leszeks): Should this create a new ParallelTasks instance?
parallel_tasks_(nullptr) {}
ParseInfo::ParseInfo(const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state)
: flags_(flags),
zone_(std::make_unique<Zone>(zone_allocator, ZONE_NAME)),
state_(state),
zone_(std::make_unique<Zone>(state->allocator(), ZONE_NAME)),
extension_(nullptr),
script_scope_(nullptr),
stack_limit_(0),
hash_seed_(0),
parameters_end_pos_(kNoSourcePosition),
max_function_literal_id_(kFunctionLiteralIdInvalid),
character_stream_(nullptr),
ast_value_factory_(nullptr),
ast_string_constants_(nullptr),
function_name_(nullptr),
runtime_call_stats_(nullptr),
source_range_map_(nullptr),
......@@ -181,32 +198,18 @@ ParseInfo::ParseInfo(AccountingAllocator* zone_allocator,
}
}
ParseInfo::ParseInfo(Isolate* isolate, UnoptimizedCompileFlags flags)
: ParseInfo(isolate->allocator(), flags) {
set_hash_seed(HashSeed(isolate));
set_stack_limit(isolate->stack_guard()->real_climit());
set_runtime_call_stats(isolate->counters()->runtime_call_stats());
set_logger(isolate->logger());
set_ast_string_constants(isolate->ast_string_constants());
if (isolate->compiler_dispatcher()->IsEnabled()) {
parallel_tasks_.reset(new ParallelTasks(isolate->compiler_dispatcher()));
}
ParseInfo::ParseInfo(Isolate* isolate, const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state)
: ParseInfo(flags, state) {
SetPerThreadState(isolate->stack_guard()->real_climit(),
isolate->counters()->runtime_call_stats());
}
// static
std::unique_ptr<ParseInfo> ParseInfo::FromParent(
const ParseInfo* outer_parse_info, const UnoptimizedCompileFlags flags,
AccountingAllocator* zone_allocator, const FunctionLiteral* literal,
const AstRawString* function_name) {
std::unique_ptr<ParseInfo> result(new ParseInfo(zone_allocator, flags));
// Replicate shared state of the outer_parse_info.
result->set_logger(outer_parse_info->logger());
result->set_ast_string_constants(outer_parse_info->ast_string_constants());
result->set_hash_seed(outer_parse_info->hash_seed());
DCHECK_EQ(outer_parse_info->parameters_end_pos(), kNoSourcePosition);
DCHECK_NULL(outer_parse_info->extension());
std::unique_ptr<ParseInfo> ParseInfo::ForToplevelFunction(
const UnoptimizedCompileFlags flags, UnoptimizedCompileState* compile_state,
const FunctionLiteral* literal, const AstRawString* function_name) {
std::unique_ptr<ParseInfo> result(new ParseInfo(flags, compile_state));
// Clone the function_name AstRawString into the ParseInfo's own
// AstValueFactory.
......@@ -320,9 +323,9 @@ void ParseInfo::CheckFlagsForFunctionFromScript(Script script) {
source_range_map() != nullptr);
}
void ParseInfo::ParallelTasks::Enqueue(ParseInfo* outer_parse_info,
const AstRawString* function_name,
FunctionLiteral* literal) {
void UnoptimizedCompileState::ParallelTasks::Enqueue(
ParseInfo* outer_parse_info, const AstRawString* function_name,
FunctionLiteral* literal) {
base::Optional<CompilerDispatcher::JobId> job_id =
dispatcher_->Enqueue(outer_parse_info, function_name, literal);
if (job_id) {
......
......@@ -12,6 +12,7 @@
#include "include/v8.h"
#include "src/base/bit-field.h"
#include "src/base/export-template.h"
#include "src/base/logging.h"
#include "src/common/globals.h"
#include "src/handles/handles.h"
#include "src/objects/function-kind.h"
......@@ -146,17 +147,68 @@ class V8_EXPORT_PRIVATE UnoptimizedCompileFlags {
};
#undef FLAG_FIELDS
class ParseInfo;
// The mutable state for a parse + unoptimized compile operation.
class V8_EXPORT_PRIVATE UnoptimizedCompileState {
public:
explicit UnoptimizedCompileState(Isolate*);
UnoptimizedCompileState(const UnoptimizedCompileState& other) V8_NOEXCEPT;
class ParallelTasks {
public:
explicit ParallelTasks(CompilerDispatcher* compiler_dispatcher)
: dispatcher_(compiler_dispatcher) {
DCHECK_NOT_NULL(dispatcher_);
}
void Enqueue(ParseInfo* outer_parse_info, const AstRawString* function_name,
FunctionLiteral* literal);
using EnqueuedJobsIterator =
std::forward_list<std::pair<FunctionLiteral*, uintptr_t>>::iterator;
EnqueuedJobsIterator begin() { return enqueued_jobs_.begin(); }
EnqueuedJobsIterator end() { return enqueued_jobs_.end(); }
CompilerDispatcher* dispatcher() { return dispatcher_; }
private:
CompilerDispatcher* dispatcher_;
std::forward_list<std::pair<FunctionLiteral*, uintptr_t>> enqueued_jobs_;
};
uint64_t hash_seed() const { return hash_seed_; }
AccountingAllocator* allocator() const { return allocator_; }
const AstStringConstants* ast_string_constants() const {
return ast_string_constants_;
}
Logger* logger() const { return logger_; }
PendingCompilationErrorHandler* pending_error_handler() {
return &pending_error_handler_;
}
ParallelTasks* parallel_tasks() const { return parallel_tasks_.get(); }
private:
uint64_t hash_seed_;
AccountingAllocator* allocator_;
const AstStringConstants* ast_string_constants_;
PendingCompilationErrorHandler pending_error_handler_;
Logger* logger_;
std::unique_ptr<ParallelTasks> parallel_tasks_;
};
// A container for the inputs, configuration options, and outputs of parsing.
class V8_EXPORT_PRIVATE ParseInfo {
public:
ParseInfo(Isolate*, const UnoptimizedCompileFlags flags);
ParseInfo(Isolate* isolate, const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state);
// Creates a new parse info based on parent top-level |outer_parse_info| for
// function |literal|.
static std::unique_ptr<ParseInfo> FromParent(
const ParseInfo* outer_parse_info, const UnoptimizedCompileFlags flags,
AccountingAllocator* zone_allocator, const FunctionLiteral* literal,
static std::unique_ptr<ParseInfo> ForToplevelFunction(
const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* compile_state, const FunctionLiteral* literal,
const AstRawString* function_name);
~ParseInfo();
......@@ -176,6 +228,30 @@ class V8_EXPORT_PRIVATE ParseInfo {
const UnoptimizedCompileFlags& flags() const { return flags_; }
// Getters for state.
uint64_t hash_seed() const { return state_->hash_seed(); }
AccountingAllocator* allocator() const { return state_->allocator(); }
const AstStringConstants* ast_string_constants() const {
return state_->ast_string_constants();
}
Logger* logger() const { return state_->logger(); }
PendingCompilationErrorHandler* pending_error_handler() {
return state_->pending_error_handler();
}
UnoptimizedCompileState::ParallelTasks* parallel_tasks() const {
return state_->parallel_tasks();
}
const UnoptimizedCompileState* state() const { return state_; }
// Accessors for per-thread state.
uintptr_t stack_limit() const { return stack_limit_; }
RuntimeCallStats* runtime_call_stats() const { return runtime_call_stats_; }
void SetPerThreadState(uintptr_t stack_limit,
RuntimeCallStats* runtime_call_stats) {
stack_limit_ = stack_limit;
runtime_call_stats_ = runtime_call_stats;
}
// Accessor methods for output flags.
bool allow_eval_cache() const { return allow_eval_cache_; }
void set_allow_eval_cache(bool value) { allow_eval_cache_ = value; }
......@@ -221,12 +297,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
DeclarationScope* scope() const;
uintptr_t stack_limit() const { return stack_limit_; }
void set_stack_limit(uintptr_t stack_limit) { stack_limit_ = stack_limit; }
uint64_t hash_seed() const { return hash_seed_; }
void set_hash_seed(uint64_t hash_seed) { hash_seed_ = hash_seed; }
int parameters_end_pos() const { return parameters_end_pos_; }
void set_parameters_end_pos(int parameters_end_pos) {
parameters_end_pos_ = parameters_end_pos;
......@@ -241,71 +311,29 @@ class V8_EXPORT_PRIVATE ParseInfo {
max_function_literal_id_ = max_function_literal_id;
}
const AstStringConstants* ast_string_constants() const {
return ast_string_constants_;
}
void set_ast_string_constants(
const AstStringConstants* ast_string_constants) {
ast_string_constants_ = ast_string_constants;
}
RuntimeCallStats* runtime_call_stats() const { return runtime_call_stats_; }
void set_runtime_call_stats(RuntimeCallStats* runtime_call_stats) {
runtime_call_stats_ = runtime_call_stats;
}
Logger* logger() const { return logger_; }
void set_logger(Logger* logger) { logger_ = logger; }
void AllocateSourceRangeMap();
SourceRangeMap* source_range_map() const { return source_range_map_; }
void set_source_range_map(SourceRangeMap* source_range_map) {
source_range_map_ = source_range_map;
}
PendingCompilationErrorHandler* pending_error_handler() {
return &pending_error_handler_;
}
class ParallelTasks {
public:
explicit ParallelTasks(CompilerDispatcher* compiler_dispatcher)
: dispatcher_(compiler_dispatcher) {
DCHECK(dispatcher_);
}
void Enqueue(ParseInfo* outer_parse_info, const AstRawString* function_name,
FunctionLiteral* literal);
using EnqueuedJobsIterator =
std::forward_list<std::pair<FunctionLiteral*, uintptr_t>>::iterator;
EnqueuedJobsIterator begin() { return enqueued_jobs_.begin(); }
EnqueuedJobsIterator end() { return enqueued_jobs_.end(); }
CompilerDispatcher* dispatcher() { return dispatcher_; }
private:
CompilerDispatcher* dispatcher_;
std::forward_list<std::pair<FunctionLiteral*, uintptr_t>> enqueued_jobs_;
};
ParallelTasks* parallel_tasks() { return parallel_tasks_.get(); }
void CheckFlagsForFunctionFromScript(Script script);
private:
ParseInfo(AccountingAllocator* zone_allocator, UnoptimizedCompileFlags flags);
ParseInfo(const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state);
void CheckFlagsForToplevelCompileFromScript(Script script,
bool is_collecting_type_profile);
//------------- Inputs to parsing and scope analysis -----------------------
const UnoptimizedCompileFlags flags_;
UnoptimizedCompileState* state_;
std::unique_ptr<Zone> zone_;
v8::Extension* extension_;
DeclarationScope* script_scope_;
uintptr_t stack_limit_;
uint64_t hash_seed_;
int parameters_end_pos_;
int max_function_literal_id_;
......@@ -313,16 +341,12 @@ class V8_EXPORT_PRIVATE ParseInfo {
std::unique_ptr<Utf16CharacterStream> character_stream_;
std::unique_ptr<ConsumedPreparseData> consumed_preparse_data_;
std::unique_ptr<AstValueFactory> ast_value_factory_;
const class AstStringConstants* ast_string_constants_;
const AstRawString* function_name_;
RuntimeCallStats* runtime_call_stats_;
Logger* logger_;
SourceRangeMap* source_range_map_; // Used when block coverage is enabled.
std::unique_ptr<ParallelTasks> parallel_tasks_;
//----------- Output of parsing and scope analysis ------------------------
FunctionLiteral* literal_;
PendingCompilationErrorHandler pending_error_handler_;
bool allow_eval_cache_ : 1;
bool contains_asm_module_ : 1;
LanguageMode language_mode_ : 1;
......
......@@ -712,7 +712,8 @@ TEST(PreParserScopeAnalysis) {
flags.set_is_lazy_compile(true);
// Parse the lazy function using the scope data.
i::ParseInfo using_scope_data(isolate, flags);
i::UnoptimizedCompileState using_scope_state(isolate);
i::ParseInfo using_scope_data(isolate, flags, &using_scope_state);
using_scope_data.set_consumed_preparse_data(
i::ConsumedPreparseData::For(isolate, produced_data_on_heap));
CHECK(i::parsing::ParseFunction(&using_scope_data, shared, isolate));
......@@ -727,7 +728,8 @@ TEST(PreParserScopeAnalysis) {
CHECK(i::DeclarationScope::Analyze(&using_scope_data));
// Parse the lazy function again eagerly to produce baseline data.
i::ParseInfo not_using_scope_data(isolate, flags);
i::UnoptimizedCompileState not_using_scope_state(isolate);
i::ParseInfo not_using_scope_data(isolate, flags, &not_using_scope_state);
CHECK(i::parsing::ParseFunction(&not_using_scope_data, shared, isolate));
// Verify that we didn't skip anything (there's no preparsed scope data,
......@@ -761,9 +763,10 @@ TEST(Regress753896) {
i::Handle<i::String> source = factory->InternalizeUtf8String(
"function lazy() { let v = 0; if (true) { var v = 0; } }");
i::Handle<i::Script> script = factory->NewScript(source);
i::UnoptimizedCompileState state(isolate);
i::UnoptimizedCompileFlags flags =
i::UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
i::ParseInfo info(isolate, flags);
i::ParseInfo info(isolate, flags, &state);
// We don't assert that parsing succeeded or that it failed; currently the
// error is not detected inside lazy functions, but it might be in the future.
......
This diff is collapsed.
......@@ -80,10 +80,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
v8::internal::Handle<v8::internal::Script> script =
factory->NewScript(source.ToHandleChecked());
v8::internal::UnoptimizedCompileState state(i_isolate);
v8::internal::UnoptimizedCompileFlags flags =
v8::internal::UnoptimizedCompileFlags::ForScriptCompile(i_isolate,
*script);
v8::internal::ParseInfo info(i_isolate, flags);
v8::internal::ParseInfo info(i_isolate, flags, &state);
if (!v8::internal::parsing::ParseProgram(&info, script, i_isolate)) {
i_isolate->OptionalRescheduleException(true);
}
......
......@@ -69,8 +69,9 @@ class CompilerDispatcherTest : public TestWithNativeContext {
static base::Optional<CompilerDispatcher::JobId> EnqueueUnoptimizedCompileJob(
CompilerDispatcher* dispatcher, Isolate* isolate,
Handle<SharedFunctionInfo> shared) {
UnoptimizedCompileState state(isolate);
std::unique_ptr<ParseInfo> outer_parse_info =
test::OuterParseInfoForShared(isolate, shared);
test::OuterParseInfoForShared(isolate, shared, &state);
AstValueFactory* ast_value_factory =
outer_parse_info->GetOrCreateAstValueFactory();
AstNodeFactory ast_node_factory(ast_value_factory,
......
......@@ -56,10 +56,13 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
public:
OffThreadFactoryTest()
: TestWithIsolateAndZone(),
parse_info_(isolate(), UnoptimizedCompileFlags::ForToplevelCompile(
isolate(), true,
construct_language_mode(FLAG_use_strict),
REPLMode::kNo)),
state_(isolate()),
parse_info_(
isolate(),
UnoptimizedCompileFlags::ForToplevelCompile(
isolate(), true, construct_language_mode(FLAG_use_strict),
REPLMode::kNo),
&state_),
off_thread_isolate_(isolate(), parse_info_.zone()) {}
FunctionLiteral* ParseProgram(const char* source) {
......@@ -118,6 +121,7 @@ class OffThreadFactoryTest : public TestWithIsolateAndZone {
}
private:
UnoptimizedCompileState state_;
ParseInfo parse_info_;
OffThreadIsolate off_thread_isolate_;
Handle<String> source_string_;
......
......@@ -48,8 +48,9 @@ class BackgroundCompileTaskTest : public TestWithNativeContext {
BackgroundCompileTask* NewBackgroundCompileTask(
Isolate* isolate, Handle<SharedFunctionInfo> shared,
size_t stack_size = FLAG_stack_size) {
UnoptimizedCompileState state(isolate);
std::unique_ptr<ParseInfo> outer_parse_info =
test::OuterParseInfoForShared(isolate, shared);
test::OuterParseInfoForShared(isolate, shared, &state);
AstValueFactory* ast_value_factory =
outer_parse_info->GetOrCreateAstValueFactory();
AstNodeFactory ast_node_factory(ast_value_factory,
......@@ -75,7 +76,7 @@ class BackgroundCompileTaskTest : public TestWithNativeContext {
shared->function_literal_id(), nullptr);
return new BackgroundCompileTask(
allocator(), outer_parse_info.get(), function_name, function_literal,
outer_parse_info.get(), function_name, function_literal,
isolate->counters()->worker_thread_runtime_call_stats(),
isolate->counters()->compile_function_on_background(), FLAG_stack_size);
}
......
......@@ -54,13 +54,15 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
}
std::unique_ptr<ParseInfo> OuterParseInfoForShared(
Isolate* isolate, Handle<SharedFunctionInfo> shared) {
Isolate* isolate, Handle<SharedFunctionInfo> shared,
UnoptimizedCompileState* state) {
Script script = Script::cast(shared->script());
std::unique_ptr<ParseInfo> result = std::make_unique<ParseInfo>(
isolate, i::UnoptimizedCompileFlags::ForScriptCompile(isolate, script));
isolate, i::UnoptimizedCompileFlags::ForScriptCompile(isolate, script),
state);
// Create a character stream to simulate the parser having done so for the
// to-level ParseProgram.
// top-level ParseProgram.
Handle<String> source(String::cast(script.source()), isolate);
std::unique_ptr<Utf16CharacterStream> stream(
ScannerStream::For(isolate, source));
......
......@@ -46,7 +46,8 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
Isolate* isolate,
v8::String::ExternalOneByteStringResource* maybe_resource);
std::unique_ptr<ParseInfo> OuterParseInfoForShared(
Isolate* isolate, Handle<SharedFunctionInfo> shared);
Isolate* isolate, Handle<SharedFunctionInfo> shared,
UnoptimizedCompileState* state);
} // namespace test
} // namespace internal
......
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