Commit a66c7a38 authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[compiler] Create ParseInfo on BG thread

Rather than creating a ParseInfo when creating a BackgroundCompileTask
(and passing ownership across to the BG thread which deallocates it),
create one when running it.

This allows the ParseInfo Zone to be both allocated and deallocated on
the same thread, which will improve its allocator friendliness.

As a side-effect, we now use the on-heap PreparseData from the
SharedFunctionInfo, rather than cloning the in-Zone PreparseData. This
means that we don't have to copy the PreparseData across Zones, but we
do need to Unpark the LocalHeap when accessing preparse data.

Change-Id: I16d976c1ad54c1090180f2936f40a23a6dbb5904
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3312483Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78228}
parent b4f8578f
......@@ -1382,7 +1382,8 @@ BackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* streamed_data,
isolate, true, construct_language_mode(FLAG_use_strict),
REPLMode::kNo, type, FLAG_lazy_streaming)),
compile_state_(isolate),
info_(std::make_unique<ParseInfo>(isolate, flags_, &compile_state_)),
character_stream_(ScannerStream::For(streamed_data->source_stream.get(),
streamed_data->encoding)),
stack_size_(i::FLAG_stack_size),
worker_thread_runtime_call_stats_(
isolate->counters()->worker_thread_runtime_call_stats()),
......@@ -1390,25 +1391,17 @@ BackgroundCompileTask::BackgroundCompileTask(ScriptStreamingData* streamed_data,
start_position_(0),
end_position_(0),
function_literal_id_(kFunctionLiteralIdTopLevel),
language_mode_(info_->language_mode()) {
language_mode_(flags_.outer_language_mode()) {
VMState<PARSER> state(isolate);
// Prepare the data for the internalization phase and compilation phase, which
// will happen in the main thread after parsing.
LOG(isolate, ScriptEvent(Logger::ScriptEventType::kStreamingCompile,
info_->flags().script_id()));
std::unique_ptr<Utf16CharacterStream> stream(ScannerStream::For(
streamed_data->source_stream.get(), streamed_data->encoding));
info_->set_character_stream(std::move(stream));
flags_.script_id()));
}
BackgroundCompileTask::BackgroundCompileTask(
Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
const UnoptimizedCompileState* compile_state,
std::unique_ptr<Utf16CharacterStream> character_stream,
ProducedPreparseData* preparse_data,
WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
TimedHistogram* timer, int max_stack_size)
: isolate_for_local_isolate_(isolate),
......@@ -1417,7 +1410,7 @@ BackgroundCompileTask::BackgroundCompileTask(
flags_(
UnoptimizedCompileFlags::ForFunctionCompile(isolate, *shared_info)),
compile_state_(*compile_state),
info_(std::make_unique<ParseInfo>(isolate, flags_, &compile_state_)),
character_stream_(std::move(character_stream)),
stack_size_(max_stack_size),
worker_thread_runtime_call_stats_(worker_thread_runtime_stats),
timer_(timer),
......@@ -1425,26 +1418,15 @@ BackgroundCompileTask::BackgroundCompileTask(
start_position_(shared_info->StartPosition()),
end_position_(shared_info->EndPosition()),
function_literal_id_(shared_info->function_literal_id()),
language_mode_(info_->language_mode()) {
language_mode_(flags_.outer_language_mode()) {
DCHECK(!shared_info->is_toplevel());
// Clone the character stream so both can be accessed independently.
character_stream->Seek(start_position_);
info_->set_character_stream(std::move(character_stream));
character_stream_->Seek(start_position_);
// Get the script out of the outer ParseInfo and turn it into a persistent
// handle we can transfer to the background thread.
persistent_handles_ = std::make_unique<PersistentHandles>(isolate);
input_shared_info_ = persistent_handles_->NewHandle(shared_info);
// Get preparsed scope data from the function literal.
if (preparse_data) {
ZonePreparseData* serialized_data = preparse_data->Serialize(info_->zone());
info_->set_consumed_preparse_data(
ConsumedPreparseData::For(info_->zone(), serialized_data));
}
info_->CheckFlagsForFunctionFromScript(Script::cast(shared_info->script()));
}
BackgroundCompileTask::~BackgroundCompileTask() = default;
......@@ -1484,15 +1466,10 @@ void BackgroundCompileTask::Run() {
TimedHistogramScope timer(timer_);
WorkerThreadRuntimeCallStatsScope worker_thread_scope(
worker_thread_runtime_call_stats_);
// Update the per-thread state of the ParseInfo to the off-thread state.
// TODO(leszeks): Fully initialize the ParseInfo here rather than passing it
// across from the main thread.
info_->SetPerThreadState(GetCurrentStackPosition() - stack_size_ * KB,
worker_thread_scope.Get());
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"BackgroundCompileTask::Run");
RCS_SCOPE(info_->runtime_call_stats(),
RCS_SCOPE(worker_thread_scope.Get(),
RuntimeCallCounterId::kCompileBackgroundCompileTask);
bool toplevel_script_compilation = flags_.is_toplevel();
......@@ -1502,15 +1479,19 @@ void BackgroundCompileTask::Run() {
UnparkedScope unparked_scope(&isolate);
LocalHandleScope handle_scope(&isolate);
ParseInfo info(&isolate, flags_, &compile_state_,
GetCurrentStackPosition() - stack_size_ * KB);
info.set_character_stream(std::move(character_stream_));
if (toplevel_script_compilation) {
DCHECK_NULL(persistent_handles_);
DCHECK(input_shared_info_.is_null());
// We don't have the script source, origin, or details yet, so use default
// values for them. These will be fixed up during the main-thread merge.
Handle<Script> script = info_->CreateScript(
Handle<Script> script = info.CreateScript(
&isolate, isolate.factory()->empty_string(), kNullMaybeHandle,
ScriptOriginOptions(false, false, false, info_->flags().is_module()));
ScriptOriginOptions(false, false, false, info.flags().is_module()));
script_ = isolate.heap()->NewPersistentHandle(script);
} else {
DCHECK_NOT_NULL(persistent_handles_);
......@@ -1519,22 +1500,31 @@ void BackgroundCompileTask::Run() {
input_shared_info_.ToHandleChecked();
script_ = isolate.heap()->NewPersistentHandle(
Script::cast(shared_info->script()));
info_->CheckFlagsForFunctionFromScript(*script_);
info.CheckFlagsForFunctionFromScript(*script_);
{
SharedStringAccessGuardIfNeeded access_guard(&isolate);
info.set_function_name(info.GetOrCreateAstValueFactory()->GetString(
shared_info->Name(), access_guard));
}
SharedStringAccessGuardIfNeeded access_guard(&isolate);
info_->set_function_name(info_->GetOrCreateAstValueFactory()->GetString(
shared_info->Name(), access_guard));
// Get preparsed scope data from the function literal.
if (shared_info->HasUncompiledDataWithPreparseData()) {
info.set_consumed_preparse_data(ConsumedPreparseData::For(
&isolate, handle(shared_info->uncompiled_data_with_preparse_data()
.preparse_data(&isolate),
&isolate)));
}
}
// Update the character stream's runtime call stats.
info_->character_stream()->set_runtime_call_stats(
info_->runtime_call_stats());
info.character_stream()->set_runtime_call_stats(info.runtime_call_stats());
// Parser needs to stay alive for finalizing the parsing on the main
// thread.
Parser parser(&isolate, info_.get(), script_);
Parser parser(&isolate, &info, script_);
if (flags().is_toplevel()) {
parser.InitializeEmptyScopeChain(info_.get());
parser.InitializeEmptyScopeChain(&info);
} else {
// TODO(leszeks): Consider keeping Scope zones alive between compile tasks
// and passing the Scope for the FunctionLiteral through here directly
......@@ -1547,28 +1537,27 @@ void BackgroundCompileTask::Run() {
handle(shared_info->GetOuterScopeInfo(), &isolate);
}
parser.DeserializeScopeChain(
&isolate, info_.get(), maybe_outer_scope_info,
&isolate, &info, maybe_outer_scope_info,
Scope::DeserializationMode::kIncludingVariables);
}
parser.ParseOnBackground(&isolate, info_.get(), start_position_,
end_position_, function_literal_id_);
parser.ParseOnBackground(&isolate, &info, start_position_, end_position_,
function_literal_id_);
parser.UpdateStatistics(script_, use_counts_, &total_preparse_skipped_);
// Save the language mode.
language_mode_ = info_->language_mode();
language_mode_ = info.language_mode();
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.CompileCodeBackground");
RCS_SCOPE(info_->runtime_call_stats(),
RuntimeCallCounterIdForCompileBackground(info_.get()));
RCS_SCOPE(info.runtime_call_stats(),
RuntimeCallCounterIdForCompileBackground(&info));
MaybeHandle<SharedFunctionInfo> maybe_result;
if (info_->literal() != nullptr) {
if (info.literal() != nullptr) {
Handle<SharedFunctionInfo> shared_info;
if (toplevel_script_compilation) {
shared_info =
CreateTopLevelSharedFunctionInfo(info_.get(), script_, &isolate);
shared_info = CreateTopLevelSharedFunctionInfo(&info, script_, &isolate);
} else {
// Clone into a placeholder SFI for storing the results.
shared_info = isolate.factory()->CloneSharedFunctionInfo(
......@@ -1576,16 +1565,15 @@ void BackgroundCompileTask::Run() {
}
if (IterativelyExecuteAndFinalizeUnoptimizedCompilationJobs(
&isolate, shared_info, script_, info_.get(),
compile_state_.allocator(), &is_compiled_scope_,
&finalize_unoptimized_compilation_data_,
&isolate, shared_info, script_, &info, compile_state_.allocator(),
&is_compiled_scope_, &finalize_unoptimized_compilation_data_,
&jobs_to_retry_finalization_on_main_thread_)) {
maybe_result = shared_info;
}
}
if (maybe_result.is_null()) {
PreparePendingException(&isolate, info_.get());
PreparePendingException(&isolate, &info);
}
outer_function_sfi_ = isolate.heap()->NewPersistentMaybeHandle(maybe_result);
......@@ -1593,8 +1581,7 @@ void BackgroundCompileTask::Run() {
persistent_handles_ = isolate.heap()->DetachPersistentHandles();
// Make sure the language mode didn't change.
DCHECK_EQ(language_mode_, info_->language_mode());
info_.reset();
DCHECK_EQ(language_mode_, info.language_mode());
}
MaybeHandle<SharedFunctionInfo> BackgroundCompileTask::FinalizeScript(
......
......@@ -513,7 +513,6 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
Isolate* isolate, Handle<SharedFunctionInfo> shared_info,
const UnoptimizedCompileState* compile_state,
std::unique_ptr<Utf16CharacterStream> character_stream,
ProducedPreparseData* preparse_data,
WorkerThreadRuntimeCallStats* worker_thread_runtime_stats,
TimedHistogram* timer, int max_stack_size);
......@@ -536,7 +535,7 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
Isolate* isolate_for_local_isolate_;
UnoptimizedCompileFlags flags_;
UnoptimizedCompileState compile_state_;
std::unique_ptr<ParseInfo> info_;
std::unique_ptr<Utf16CharacterStream> character_stream_;
int stack_size_;
WorkerThreadRuntimeCallStats* worker_thread_runtime_call_stats_;
TimedHistogram* timer_;
......
......@@ -87,8 +87,7 @@ LazyCompileDispatcher::~LazyCompileDispatcher() {
void LazyCompileDispatcher::Enqueue(
LocalIsolate* isolate, Handle<SharedFunctionInfo> shared_info,
const UnoptimizedCompileState* compile_state,
std::unique_ptr<Utf16CharacterStream> character_stream,
ProducedPreparseData* preparse_data) {
std::unique_ptr<Utf16CharacterStream> character_stream) {
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.LazyCompilerDispatcherEnqueue");
RCS_SCOPE(isolate, RuntimeCallCounterId::kCompileEnqueueOnDispatcher);
......@@ -96,8 +95,8 @@ void LazyCompileDispatcher::Enqueue(
std::unique_ptr<Job> job =
std::make_unique<Job>(std::make_unique<BackgroundCompileTask>(
isolate_, shared_info, compile_state, std::move(character_stream),
preparse_data, worker_thread_runtime_call_stats_,
background_compile_timer_, static_cast<int>(max_stack_size_)));
worker_thread_runtime_call_stats_, background_compile_timer_,
static_cast<int>(max_stack_size_)));
// Post a a background worker task to perform the compilation on the worker
// thread.
......
......@@ -86,8 +86,7 @@ class V8_EXPORT_PRIVATE LazyCompileDispatcher {
void Enqueue(LocalIsolate* isolate, Handle<SharedFunctionInfo> shared_info,
const UnoptimizedCompileState* compile_state,
std::unique_ptr<Utf16CharacterStream> character_stream,
ProducedPreparseData* preparse_data);
std::unique_ptr<Utf16CharacterStream> character_stream);
// Returns true if there is a pending job registered for the given function.
bool IsEnqueued(Handle<SharedFunctionInfo> function) const;
......
......@@ -3236,6 +3236,11 @@ void Isolate::Deinit() {
delete baseline_batch_compiler_;
baseline_batch_compiler_ = nullptr;
if (lazy_compile_dispatcher_) {
lazy_compile_dispatcher_->AbortAll();
lazy_compile_dispatcher_.reset();
}
// At this point there are no more background threads left in this isolate.
heap_.safepoint()->AssertMainThreadIsOnlyThread();
......@@ -3259,11 +3264,6 @@ void Isolate::Deinit() {
delete heap_profiler_;
heap_profiler_ = nullptr;
if (lazy_compile_dispatcher_) {
lazy_compile_dispatcher_->AbortAll();
lazy_compile_dispatcher_.reset();
}
string_table_.reset();
#if USE_SIMULATOR
......
......@@ -2544,8 +2544,7 @@ void BytecodeGenerator::AddToEagerLiteralsIfEager(FunctionLiteral* literal) {
Compiler::GetSharedFunctionInfo(literal, script_, local_isolate_);
info()->state()->dispatcher()->Enqueue(
local_isolate_, shared_info, info()->state(),
info()->character_stream()->Clone(),
literal->produced_preparse_data());
info()->character_stream()->Clone());
}
} else if (eager_inner_literals_ && literal->ShouldEagerCompile()) {
DCHECK(!IsInEagerLiterals(literal, *eager_inner_literals_));
......
......@@ -186,19 +186,20 @@ UnoptimizedCompileState::UnoptimizedCompileState(
dispatcher_(other.dispatcher()) {}
ParseInfo::ParseInfo(const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state)
UnoptimizedCompileState* state, uintptr_t stack_limit,
RuntimeCallStats* runtime_call_stats)
: flags_(flags),
state_(state),
zone_(std::make_unique<Zone>(state->allocator(), "parser-zone")),
extension_(nullptr),
script_scope_(nullptr),
stack_limit_(0),
stack_limit_(stack_limit),
parameters_end_pos_(kNoSourcePosition),
max_function_literal_id_(kFunctionLiteralIdInvalid),
character_stream_(nullptr),
ast_value_factory_(nullptr),
function_name_(nullptr),
runtime_call_stats_(nullptr),
runtime_call_stats_(runtime_call_stats),
source_range_map_(nullptr),
literal_(nullptr),
allow_eval_cache_(false),
......@@ -213,16 +214,12 @@ ParseInfo::ParseInfo(const UnoptimizedCompileFlags flags,
ParseInfo::ParseInfo(Isolate* isolate, const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state)
: ParseInfo(flags, state) {
SetPerThreadState(isolate->stack_guard()->real_climit(),
isolate->counters()->runtime_call_stats());
}
: ParseInfo(flags, state, isolate->stack_guard()->real_climit(),
isolate->counters()->runtime_call_stats()) {}
ParseInfo::ParseInfo(LocalIsolate* isolate, const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state)
: ParseInfo(flags, state) {
SetPerThreadState(0, nullptr);
}
UnoptimizedCompileState* state, uintptr_t stack_limit)
: ParseInfo(flags, state, stack_limit, isolate->runtime_call_stats()) {}
ParseInfo::~ParseInfo() = default;
......
......@@ -194,7 +194,7 @@ class V8_EXPORT_PRIVATE ParseInfo {
ParseInfo(Isolate* isolate, const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state);
ParseInfo(LocalIsolate* isolate, const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state);
UnoptimizedCompileState* state, uintptr_t stack_limit);
~ParseInfo();
......@@ -229,11 +229,6 @@ class V8_EXPORT_PRIVATE ParseInfo {
// 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_; }
......@@ -307,8 +302,8 @@ class V8_EXPORT_PRIVATE ParseInfo {
void CheckFlagsForFunctionFromScript(Script script);
private:
ParseInfo(const UnoptimizedCompileFlags flags,
UnoptimizedCompileState* state);
ParseInfo(const UnoptimizedCompileFlags flags, UnoptimizedCompileState* state,
uintptr_t stack_limit, RuntimeCallStats* runtime_call_stats);
void CheckFlagsForToplevelCompileFromScript(Script script,
bool is_collecting_type_profile);
......
......@@ -658,6 +658,7 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info) {
// conflicting var declarations with outer scope-info-backed scopes.
if (flags().is_eval()) {
DCHECK(parsing_on_main_thread_);
DCHECK(!overall_parse_is_parked_);
info->ast_value_factory()->Internalize(isolate);
}
CheckConflictingVarDeclarations(scope);
......@@ -2725,11 +2726,17 @@ bool Parser::SkipFunction(const AstRawString* function_name, FunctionKind kind,
int num_inner_functions;
bool uses_super_property;
if (stack_overflow()) return true;
*produced_preparse_data =
consumed_preparse_data_->GetDataForSkippableFunction(
main_zone(), function_scope->start_position(), &end_position,
num_parameters, function_length, &num_inner_functions,
&uses_super_property, &language_mode);
{
base::Optional<UnparkedScope> unparked_scope;
if (overall_parse_is_parked_) {
unparked_scope.emplace(local_isolate_);
}
*produced_preparse_data =
consumed_preparse_data_->GetDataForSkippableFunction(
main_zone(), function_scope->start_position(), &end_position,
num_parameters, function_length, &num_inner_functions,
&uses_super_property, &language_mode);
}
function_scope->outer_scope()->SetMustUsePreparseData();
function_scope->set_is_skipped_function(true);
......@@ -3296,6 +3303,7 @@ void Parser::ParseOnBackground(LocalIsolate* isolate, ParseInfo* info,
// We can park the isolate while parsing, it doesn't need to allocate or
// access the main thread.
ParkedScope parked_scope(isolate);
overall_parse_is_parked_ = true;
scanner_.Initialize();
......
......@@ -1066,6 +1066,7 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Zone preparser_zone_;
PreParser* reusable_preparser_;
Mode mode_;
bool overall_parse_is_parked_ = false;
MaybeHandle<FixedArray> maybe_wrapped_arguments_;
......
......@@ -182,13 +182,13 @@ class BaseConsumedPreparseData : public ConsumedPreparseData {
class OnHeapConsumedPreparseData final
: public BaseConsumedPreparseData<PreparseData> {
public:
OnHeapConsumedPreparseData(Isolate* isolate, Handle<PreparseData> data);
OnHeapConsumedPreparseData(LocalIsolate* isolate, Handle<PreparseData> data);
PreparseData GetScopeData() final;
ProducedPreparseData* GetChildData(Zone* zone, int child_index) final;
private:
Isolate* isolate_;
LocalIsolate* isolate_;
Handle<PreparseData> data_;
};
......
......@@ -528,8 +528,9 @@ class OnHeapProducedPreparseData final : public ProducedPreparseData {
}
Handle<PreparseData> Serialize(LocalIsolate* isolate) final {
// Not required.
UNREACHABLE();
DCHECK(!data_->is_null());
DCHECK(isolate->heap()->ContainsLocalHandle(data_.location()));
return data_;
}
ZonePreparseData* Serialize(Zone* zone) final {
......@@ -769,7 +770,7 @@ ProducedPreparseData* OnHeapConsumedPreparseData::GetChildData(Zone* zone,
}
OnHeapConsumedPreparseData::OnHeapConsumedPreparseData(
Isolate* isolate, Handle<PreparseData> data)
LocalIsolate* isolate, Handle<PreparseData> data)
: BaseConsumedPreparseData<PreparseData>(), isolate_(isolate), data_(data) {
DCHECK_NOT_NULL(isolate);
DCHECK(data->IsPreparseData());
......@@ -833,6 +834,11 @@ ProducedPreparseData* ZoneConsumedPreparseData::GetChildData(Zone* zone,
std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
Isolate* isolate, Handle<PreparseData> data) {
return ConsumedPreparseData::For(isolate->main_thread_local_isolate(), data);
}
std::unique_ptr<ConsumedPreparseData> ConsumedPreparseData::For(
LocalIsolate* isolate, Handle<PreparseData> data) {
DCHECK(!data.is_null());
return std::make_unique<OnHeapConsumedPreparseData>(isolate, data);
}
......
......@@ -281,6 +281,8 @@ class ConsumedPreparseData {
// PreparseData |data|.
V8_EXPORT_PRIVATE static std::unique_ptr<ConsumedPreparseData> For(
Isolate* isolate, Handle<PreparseData> data);
V8_EXPORT_PRIVATE static std::unique_ptr<ConsumedPreparseData> For(
LocalIsolate* isolate, Handle<PreparseData> data);
// Creates a ConsumedPreparseData representing the data of an off-heap
// ZonePreparseData |data|.
......
......@@ -80,7 +80,7 @@ class LazyCompileDispatcherTest : public TestWithNativeContext {
if (dispatcher->IsEnqueued(shared)) return;
dispatcher->Enqueue(isolate->main_thread_local_isolate(), shared,
outer_parse_info->state(),
outer_parse_info->character_stream()->Clone(), nullptr);
outer_parse_info->character_stream()->Clone());
}
};
......
......@@ -59,30 +59,9 @@ class BackgroundCompileTaskTest : public TestWithNativeContext {
AstNodeFactory ast_node_factory(ast_value_factory,
outer_parse_info->zone());
const AstRawString* function_name =
ast_value_factory->GetOneByteString("f");
DeclarationScope* script_scope =
outer_parse_info->zone()->New<DeclarationScope>(
outer_parse_info->zone(), ast_value_factory);
DeclarationScope* function_scope =
outer_parse_info->zone()->New<DeclarationScope>(
outer_parse_info->zone(), script_scope, FUNCTION_SCOPE);
function_scope->set_start_position(shared->StartPosition());
function_scope->set_end_position(shared->EndPosition());
std::vector<void*> buffer;
ScopedPtrList<Statement> statements(&buffer);
const FunctionLiteral* function_literal =
ast_node_factory.NewFunctionLiteral(
function_name, function_scope, statements, -1, -1, -1,
FunctionLiteral::kNoDuplicateParameters,
FunctionSyntaxKind::kAnonymousExpression,
FunctionLiteral::kShouldEagerCompile, shared->StartPosition(), true,
shared->function_literal_id(), nullptr);
return new BackgroundCompileTask(
isolate, shared, outer_parse_info->state(),
outer_parse_info->character_stream()->Clone(),
function_literal->produced_preparse_data(),
isolate->counters()->worker_thread_runtime_call_stats(),
isolate->counters()->compile_function_on_background(), FLAG_stack_size);
}
......
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