[compiler-dispatcher] Move Job pointer to SFI
Reduce the enqueuing cost of compiler-dispatcher jobs by getting rid of the sets and hashmaps, and instead: 1. Turning the pending job set into a queue, and 2. Making the SharedFunctionInfo's UncompiledData hold a pointer to the LazyCompilerDispatcher::Job, instead of maintaining an IdentityMap from one to the other. To avoid bloating all UncompiledData, this adds two new UncompiledData subclasses, making it four subclasses total, for with/without Preparse data and with/without a Job pointer. "should_parallel_compile" FunctionLiterals get allocated an UncompiledData with a job pointer by default, otherwise enqueueing a SFI without a job pointer triggers a reallocation of the UncompiledData to add a job pointer. Since there is no longer a set of all Jobs (aside from one for debug-only), we need to be careful to manually clear the Job pointer from the UncompiledData whenever we finish a Job (whether successfully or by aborting) and we have to make sure that we implicitly can reach all Jobs via the pending/finalizable lists, or the set of currently running jobs. Change-Id: I3aae78e6dfbdc74f5f7c1411de398433907b2705 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3314833 Reviewed-by: Igor Sheludko <ishell@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#78302}
This commit is contained in:
parent
657e5dc1d9
commit
3b9091c827
@ -14458,6 +14458,8 @@ TNode<CodeT> CodeStubAssembler::GetSharedFunctionInfoCode(
|
||||
CODET_TYPE,
|
||||
UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE,
|
||||
UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE,
|
||||
UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_WITH_JOB_TYPE,
|
||||
UNCOMPILED_DATA_WITH_PREPARSE_DATA_AND_JOB_TYPE,
|
||||
FUNCTION_TEMPLATE_INFO_TYPE,
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
WASM_CAPI_FUNCTION_DATA_TYPE,
|
||||
@ -14469,16 +14471,17 @@ TNode<CodeT> CodeStubAssembler::GetSharedFunctionInfoCode(
|
||||
Label check_is_bytecode_array(this);
|
||||
Label check_is_baseline_data(this);
|
||||
Label check_is_asm_wasm_data(this);
|
||||
Label check_is_uncompiled_data_without_preparse_data(this);
|
||||
Label check_is_uncompiled_data_with_preparse_data(this);
|
||||
Label check_is_uncompiled_data(this);
|
||||
Label check_is_function_template_info(this);
|
||||
Label check_is_interpreter_data(this);
|
||||
Label check_is_wasm_function_data(this);
|
||||
Label* case_labels[] = {
|
||||
&check_is_bytecode_array,
|
||||
&check_is_baseline_data,
|
||||
&check_is_uncompiled_data_without_preparse_data,
|
||||
&check_is_uncompiled_data_with_preparse_data,
|
||||
&check_is_uncompiled_data,
|
||||
&check_is_uncompiled_data,
|
||||
&check_is_uncompiled_data,
|
||||
&check_is_uncompiled_data,
|
||||
&check_is_function_template_info,
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
&check_is_wasm_function_data,
|
||||
@ -14506,9 +14509,7 @@ TNode<CodeT> CodeStubAssembler::GetSharedFunctionInfoCode(
|
||||
|
||||
// IsUncompiledDataWithPreparseData | IsUncompiledDataWithoutPreparseData:
|
||||
// Compile lazy
|
||||
BIND(&check_is_uncompiled_data_with_preparse_data);
|
||||
Goto(&check_is_uncompiled_data_without_preparse_data);
|
||||
BIND(&check_is_uncompiled_data_without_preparse_data);
|
||||
BIND(&check_is_uncompiled_data);
|
||||
sfi_code = HeapConstant(BUILTIN_CODET(isolate(), CompileLazy));
|
||||
Goto(if_compile_lazy ? if_compile_lazy : &done);
|
||||
|
||||
|
@ -1648,6 +1648,12 @@ bool BackgroundCompileTask::FinalizeFunction(
|
||||
Handle<SharedFunctionInfo> input_shared_info =
|
||||
input_shared_info_.ToHandleChecked();
|
||||
|
||||
// The UncompiledData on the input SharedFunctionInfo will have a pointer to
|
||||
// the LazyCompileDispatcher Job that launched this task, which will now be
|
||||
// considered complete, so clear that regardless of whether the finalize
|
||||
// succeeds or not.
|
||||
input_shared_info->ClearUncompiledDataJobPointer();
|
||||
|
||||
// We might not have been able to finalize all jobs on the background
|
||||
// thread (e.g. asm.js jobs), so finalize those deferred jobs now.
|
||||
if (FinalizeDeferredUnoptimizedCompilationJobs(
|
||||
@ -1675,6 +1681,14 @@ bool BackgroundCompileTask::FinalizeFunction(
|
||||
return true;
|
||||
}
|
||||
|
||||
void BackgroundCompileTask::AbortFunction() {
|
||||
// The UncompiledData on the input SharedFunctionInfo will have a pointer to
|
||||
// the LazyCompileDispatcher Job that launched this task, which is about to be
|
||||
// deleted, so clear that to avoid the SharedFunctionInfo from pointing to
|
||||
// deallocated memory.
|
||||
input_shared_info_.ToHandleChecked()->ClearUncompiledDataJobPointer();
|
||||
}
|
||||
|
||||
void BackgroundCompileTask::ReportStatistics(Isolate* isolate) {
|
||||
// Update use-counts.
|
||||
for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount);
|
||||
|
@ -525,12 +525,16 @@ class V8_EXPORT_PRIVATE BackgroundCompileTask {
|
||||
|
||||
bool FinalizeFunction(Isolate* isolate, Compiler::ClearExceptionFlag flag);
|
||||
|
||||
void AbortFunction();
|
||||
|
||||
UnoptimizedCompileFlags flags() const { return flags_; }
|
||||
LanguageMode language_mode() const { return language_mode_; }
|
||||
|
||||
private:
|
||||
void ReportStatistics(Isolate* isolate);
|
||||
|
||||
void ClearFunctionJobPointer();
|
||||
|
||||
// Data needed for parsing and compilation. These need to be initialized
|
||||
// before the compilation starts.
|
||||
Isolate* isolate_for_local_isolate_;
|
||||
|
@ -11,16 +11,19 @@
|
||||
#include "src/base/platform/mutex.h"
|
||||
#include "src/base/platform/time.h"
|
||||
#include "src/codegen/compiler.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/flags/flags.h"
|
||||
#include "src/handles/global-handles-inl.h"
|
||||
#include "src/heap/parked-scope.h"
|
||||
#include "src/logging/counters.h"
|
||||
#include "src/logging/runtime-call-stats-scope.h"
|
||||
#include "src/numbers/hash-seed-inl.h"
|
||||
#include "src/objects/instance-type.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/parsing/parse-info.h"
|
||||
#include "src/parsing/parser.h"
|
||||
#include "src/roots/roots.h"
|
||||
#include "src/security/external-pointer.h"
|
||||
#include "src/tasks/cancelable-task.h"
|
||||
#include "src/tasks/task-utils.h"
|
||||
#include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
|
||||
@ -72,7 +75,6 @@ LazyCompileDispatcher::LazyCompileDispatcher(Isolate* isolate,
|
||||
max_stack_size_(max_stack_size),
|
||||
trace_compiler_dispatcher_(FLAG_trace_compiler_dispatcher),
|
||||
idle_task_manager_(new CancelableTaskManager()),
|
||||
shared_to_unoptimized_job_(isolate->heap()),
|
||||
idle_task_scheduled_(false),
|
||||
num_jobs_for_background_(0),
|
||||
main_thread_blocking_on_job_(nullptr),
|
||||
@ -87,6 +89,65 @@ LazyCompileDispatcher::~LazyCompileDispatcher() {
|
||||
CHECK(!job_handle_->IsValid());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// If the SharedFunctionInfo's UncompiledData has a job slot, then write into
|
||||
// it. Otherwise, allocate a new UncompiledData with a job slot, and then write
|
||||
// into that. Since we have two optional slots (preparse data and job), this
|
||||
// gets a little messy.
|
||||
void SetUncompiledDataJobPointer(LocalIsolate* isolate,
|
||||
Handle<SharedFunctionInfo> shared_info,
|
||||
Address job_address) {
|
||||
UncompiledData uncompiled_data = shared_info->uncompiled_data();
|
||||
switch (uncompiled_data.map(isolate).instance_type()) {
|
||||
// The easy cases -- we already have a job slot, so can write into it and
|
||||
// return.
|
||||
case UNCOMPILED_DATA_WITH_PREPARSE_DATA_AND_JOB_TYPE:
|
||||
UncompiledDataWithPreparseDataAndJob::cast(uncompiled_data)
|
||||
.set_job(job_address);
|
||||
break;
|
||||
case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_WITH_JOB_TYPE:
|
||||
UncompiledDataWithoutPreparseDataWithJob::cast(uncompiled_data)
|
||||
.set_job(job_address);
|
||||
break;
|
||||
|
||||
// Otherwise, we'll have to allocate a new UncompiledData (with or without
|
||||
// preparse data as appropriate), set the job pointer on that, and update
|
||||
// the SharedFunctionInfo to use the new UncompiledData
|
||||
case UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE: {
|
||||
Handle<String> inferred_name(uncompiled_data.inferred_name(), isolate);
|
||||
Handle<PreparseData> preparse_data(
|
||||
UncompiledDataWithPreparseData::cast(uncompiled_data).preparse_data(),
|
||||
isolate);
|
||||
Handle<UncompiledDataWithPreparseDataAndJob> new_uncompiled_data =
|
||||
isolate->factory()->NewUncompiledDataWithPreparseDataAndJob(
|
||||
inferred_name, uncompiled_data.start_position(),
|
||||
uncompiled_data.end_position(), preparse_data);
|
||||
|
||||
new_uncompiled_data->set_job(job_address);
|
||||
shared_info->set_uncompiled_data(*new_uncompiled_data);
|
||||
break;
|
||||
}
|
||||
case UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE: {
|
||||
DCHECK(uncompiled_data.IsUncompiledDataWithoutPreparseData());
|
||||
Handle<String> inferred_name(uncompiled_data.inferred_name(), isolate);
|
||||
Handle<UncompiledDataWithoutPreparseDataWithJob> new_uncompiled_data =
|
||||
isolate->factory()->NewUncompiledDataWithoutPreparseDataWithJob(
|
||||
inferred_name, uncompiled_data.start_position(),
|
||||
uncompiled_data.end_position());
|
||||
|
||||
new_uncompiled_data->set_job(job_address);
|
||||
shared_info->set_uncompiled_data(*new_uncompiled_data);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void LazyCompileDispatcher::Enqueue(
|
||||
LocalIsolate* isolate, Handle<SharedFunctionInfo> shared_info,
|
||||
std::unique_ptr<Utf16CharacterStream> character_stream) {
|
||||
@ -94,11 +155,13 @@ void LazyCompileDispatcher::Enqueue(
|
||||
"V8.LazyCompilerDispatcherEnqueue");
|
||||
RCS_SCOPE(isolate, RuntimeCallCounterId::kCompileEnqueueOnDispatcher);
|
||||
|
||||
std::unique_ptr<Job> job =
|
||||
std::make_unique<Job>(std::make_unique<BackgroundCompileTask>(
|
||||
isolate_, shared_info, std::move(character_stream),
|
||||
worker_thread_runtime_call_stats_, background_compile_timer_,
|
||||
static_cast<int>(max_stack_size_)));
|
||||
Job* job = new Job(std::make_unique<BackgroundCompileTask>(
|
||||
isolate_, shared_info, std::move(character_stream),
|
||||
worker_thread_runtime_call_stats_, background_compile_timer_,
|
||||
static_cast<int>(max_stack_size_)));
|
||||
|
||||
SetUncompiledDataJobPointer(isolate, shared_info,
|
||||
reinterpret_cast<Address>(job));
|
||||
|
||||
// Post a a background worker task to perform the compilation on the worker
|
||||
// thread.
|
||||
@ -110,20 +173,28 @@ void LazyCompileDispatcher::Enqueue(
|
||||
PrintF("\n");
|
||||
}
|
||||
|
||||
pending_background_jobs_.insert(job.get());
|
||||
// Transfer ownership of the job to the IdentityMap
|
||||
shared_to_unoptimized_job_.Insert(shared_info, job.release());
|
||||
|
||||
num_jobs_for_background_ += 1;
|
||||
VerifyBackgroundTaskCount(lock);
|
||||
#ifdef DEBUG
|
||||
all_jobs_.insert(job);
|
||||
#endif
|
||||
pending_background_jobs_.push_back(job);
|
||||
NotifyAddedBackgroundJob(lock);
|
||||
}
|
||||
// This is not in NotifyAddedBackgroundJob to avoid being inside the mutex.
|
||||
job_handle_->NotifyConcurrencyIncrease();
|
||||
}
|
||||
|
||||
bool LazyCompileDispatcher::IsEnqueued(
|
||||
Handle<SharedFunctionInfo> function) const {
|
||||
base::MutexGuard lock(&mutex_);
|
||||
return shared_to_unoptimized_job_.Find(function) != nullptr;
|
||||
Job* job = nullptr;
|
||||
Object function_data = function->function_data(kAcquireLoad);
|
||||
if (function_data.IsUncompiledDataWithPreparseDataAndJob()) {
|
||||
job = reinterpret_cast<Job*>(
|
||||
UncompiledDataWithPreparseDataAndJob::cast(function_data).job());
|
||||
} else if (function_data.IsUncompiledDataWithoutPreparseDataWithJob()) {
|
||||
job = reinterpret_cast<Job*>(
|
||||
UncompiledDataWithoutPreparseDataWithJob::cast(function_data).job());
|
||||
}
|
||||
return job != nullptr;
|
||||
}
|
||||
|
||||
void LazyCompileDispatcher::WaitForJobIfRunningOnBackground(
|
||||
@ -133,13 +204,30 @@ void LazyCompileDispatcher::WaitForJobIfRunningOnBackground(
|
||||
RCS_SCOPE(isolate_, RuntimeCallCounterId::kCompileWaitForDispatcher);
|
||||
|
||||
if (!job->is_running_on_background()) {
|
||||
num_jobs_for_background_ -= pending_background_jobs_.erase(job);
|
||||
if (job->state == Job::State::kPending) {
|
||||
DCHECK_EQ(std::count(pending_background_jobs_.begin(),
|
||||
pending_background_jobs_.end(), job),
|
||||
1);
|
||||
|
||||
// TODO(leszeks): Remove from pending jobs without walking the whole
|
||||
// vector.
|
||||
pending_background_jobs_.erase(
|
||||
std::remove(pending_background_jobs_.begin(),
|
||||
pending_background_jobs_.end(), job));
|
||||
job->state = Job::State::kPendingToRunOnForeground;
|
||||
NotifyRemovedBackgroundJob(lock);
|
||||
} else {
|
||||
DCHECK_EQ(job->state, Job::State::kReadyToFinalize);
|
||||
DCHECK_EQ(
|
||||
std::count(finalizable_jobs_.begin(), finalizable_jobs_.end(), job),
|
||||
1);
|
||||
|
||||
// TODO(leszeks): Remove from finalizable jobs without walking the whole
|
||||
// vector.
|
||||
finalizable_jobs_.erase(
|
||||
std::remove(finalizable_jobs_.begin(), finalizable_jobs_.end(), job));
|
||||
job->state = Job::State::kFinalizingNow;
|
||||
}
|
||||
VerifyBackgroundTaskCount(lock);
|
||||
return;
|
||||
}
|
||||
DCHECK_NULL(main_thread_blocking_on_job_);
|
||||
@ -147,7 +235,16 @@ void LazyCompileDispatcher::WaitForJobIfRunningOnBackground(
|
||||
while (main_thread_blocking_on_job_ != nullptr) {
|
||||
main_thread_blocking_signal_.Wait(&mutex_);
|
||||
}
|
||||
DCHECK(pending_background_jobs_.find(job) == pending_background_jobs_.end());
|
||||
|
||||
DCHECK_EQ(job->state, Job::State::kReadyToFinalize);
|
||||
DCHECK_EQ(std::count(finalizable_jobs_.begin(), finalizable_jobs_.end(), job),
|
||||
1);
|
||||
|
||||
// TODO(leszeks): Remove from finalizable jobs without walking the whole
|
||||
// vector.
|
||||
finalizable_jobs_.erase(
|
||||
std::remove(finalizable_jobs_.begin(), finalizable_jobs_.end(), job));
|
||||
job->state = Job::State::kFinalizingNow;
|
||||
}
|
||||
|
||||
bool LazyCompileDispatcher::FinishNow(Handle<SharedFunctionInfo> function) {
|
||||
@ -166,20 +263,29 @@ bool LazyCompileDispatcher::FinishNow(Handle<SharedFunctionInfo> function) {
|
||||
base::MutexGuard lock(&mutex_);
|
||||
job = GetJobFor(function, lock);
|
||||
WaitForJobIfRunningOnBackground(job, lock);
|
||||
shared_to_unoptimized_job_.Delete(function, &job);
|
||||
}
|
||||
|
||||
if (job->state == Job::State::kPendingToRunOnForeground) {
|
||||
job->task->Run();
|
||||
job->state = Job::State::kReadyToFinalize;
|
||||
job->state = Job::State::kFinalizingNow;
|
||||
}
|
||||
|
||||
if (DEBUG_BOOL) {
|
||||
base::MutexGuard lock(&mutex_);
|
||||
DCHECK_EQ(std::count(pending_background_jobs_.begin(),
|
||||
pending_background_jobs_.end(), job),
|
||||
0);
|
||||
DCHECK_EQ(
|
||||
std::count(finalizable_jobs_.begin(), finalizable_jobs_.end(), job), 0);
|
||||
DCHECK_EQ(job->state, Job::State::kFinalizingNow);
|
||||
}
|
||||
|
||||
DCHECK_EQ(job->state, Job::State::kReadyToFinalize);
|
||||
bool success = Compiler::FinalizeBackgroundCompileTask(
|
||||
job->task.get(), isolate_, Compiler::KEEP_EXCEPTION);
|
||||
job->state = Job::State::kFinalized;
|
||||
|
||||
DCHECK_NE(success, isolate_->has_pending_exception());
|
||||
delete job;
|
||||
DeleteJob(job);
|
||||
|
||||
// Opportunistically finalize all other jobs for a maximum time of
|
||||
// kMaxOpportunisticFinalizeTimeMs.
|
||||
@ -201,16 +307,36 @@ void LazyCompileDispatcher::AbortJob(Handle<SharedFunctionInfo> shared_info) {
|
||||
base::LockGuard<base::Mutex> lock(&mutex_);
|
||||
|
||||
Job* job = GetJobFor(shared_info, lock);
|
||||
num_jobs_for_background_ -= pending_background_jobs_.erase(job);
|
||||
if (job->is_running_on_background()) {
|
||||
// Job is currently running on the background thread, wait until it's done
|
||||
// and remove job then.
|
||||
job->state = Job::State::kAbortRequested;
|
||||
} else {
|
||||
shared_to_unoptimized_job_.Delete(shared_info, &job);
|
||||
delete job;
|
||||
if (job->state == Job::State::kPending) {
|
||||
DCHECK_EQ(std::count(pending_background_jobs_.begin(),
|
||||
pending_background_jobs_.end(), job),
|
||||
1);
|
||||
|
||||
pending_background_jobs_.erase(
|
||||
std::remove(pending_background_jobs_.begin(),
|
||||
pending_background_jobs_.end(), job));
|
||||
job->state = Job::State::kAbortingNow;
|
||||
NotifyRemovedBackgroundJob(lock);
|
||||
} else if (job->state == Job::State::kReadyToFinalize) {
|
||||
DCHECK_EQ(
|
||||
std::count(finalizable_jobs_.begin(), finalizable_jobs_.end(), job),
|
||||
1);
|
||||
|
||||
finalizable_jobs_.erase(
|
||||
std::remove(finalizable_jobs_.begin(), finalizable_jobs_.end(), job));
|
||||
job->state = Job::State::kAbortingNow;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
job->task->AbortFunction();
|
||||
job->state = Job::State::kFinalized;
|
||||
DeleteJob(job, lock);
|
||||
}
|
||||
VerifyBackgroundTaskCount(lock);
|
||||
}
|
||||
|
||||
void LazyCompileDispatcher::AbortAll() {
|
||||
@ -219,30 +345,38 @@ void LazyCompileDispatcher::AbortAll() {
|
||||
|
||||
{
|
||||
base::MutexGuard lock(&mutex_);
|
||||
for (Job* job : pending_background_jobs_) {
|
||||
job->task->AbortFunction();
|
||||
job->state = Job::State::kFinalized;
|
||||
DeleteJob(job, lock);
|
||||
}
|
||||
pending_background_jobs_.clear();
|
||||
for (Job* job : finalizable_jobs_) {
|
||||
job->task->AbortFunction();
|
||||
job->state = Job::State::kFinalized;
|
||||
DeleteJob(job, lock);
|
||||
}
|
||||
finalizable_jobs_.clear();
|
||||
|
||||
DCHECK_EQ(all_jobs_.size(), 0);
|
||||
num_jobs_for_background_ = 0;
|
||||
VerifyBackgroundTaskCount(lock);
|
||||
}
|
||||
|
||||
idle_task_manager_->CancelAndWait();
|
||||
|
||||
{
|
||||
base::MutexGuard lock(&mutex_);
|
||||
{
|
||||
SharedToJobMap::IteratableScope iteratable_scope(
|
||||
&shared_to_unoptimized_job_);
|
||||
for (Job** job_entry : iteratable_scope) {
|
||||
Job* job = *job_entry;
|
||||
DCHECK_NE(job->state, Job::State::kRunning);
|
||||
DCHECK_NE(job->state, Job::State::kAbortRequested);
|
||||
delete job;
|
||||
}
|
||||
}
|
||||
shared_to_unoptimized_job_.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
LazyCompileDispatcher::Job* LazyCompileDispatcher::GetJobFor(
|
||||
Handle<SharedFunctionInfo> shared, const base::MutexGuard&) const {
|
||||
return *shared_to_unoptimized_job_.Find(shared);
|
||||
Object function_data = shared->function_data(kAcquireLoad);
|
||||
if (function_data.IsUncompiledDataWithPreparseDataAndJob()) {
|
||||
return reinterpret_cast<Job*>(
|
||||
UncompiledDataWithPreparseDataAndJob::cast(function_data).job());
|
||||
} else if (function_data.IsUncompiledDataWithoutPreparseDataWithJob()) {
|
||||
return reinterpret_cast<Job*>(
|
||||
UncompiledDataWithoutPreparseDataWithJob::cast(function_data).job());
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void LazyCompileDispatcher::ScheduleIdleTaskFromAnyThread(
|
||||
@ -276,13 +410,13 @@ void LazyCompileDispatcher::DoBackgroundWork(JobDelegate* delegate) {
|
||||
Job* job = nullptr;
|
||||
{
|
||||
base::MutexGuard lock(&mutex_);
|
||||
if (pending_background_jobs_.empty()) break;
|
||||
auto it = pending_background_jobs_.begin();
|
||||
job = *it;
|
||||
pending_background_jobs_.erase(it);
|
||||
|
||||
if (pending_background_jobs_.empty()) return;
|
||||
job = pending_background_jobs_.back();
|
||||
pending_background_jobs_.pop_back();
|
||||
DCHECK_EQ(job->state, Job::State::kPending);
|
||||
|
||||
job->state = Job::State::kRunning;
|
||||
VerifyBackgroundTaskCount(lock);
|
||||
}
|
||||
|
||||
if (V8_UNLIKELY(block_for_testing_.Value())) {
|
||||
@ -306,8 +440,8 @@ void LazyCompileDispatcher::DoBackgroundWork(JobDelegate* delegate) {
|
||||
DCHECK_EQ(job->state, Job::State::kAbortRequested);
|
||||
job->state = Job::State::kAborted;
|
||||
}
|
||||
num_jobs_for_background_--;
|
||||
VerifyBackgroundTaskCount(lock);
|
||||
finalizable_jobs_.push_back(job);
|
||||
NotifyRemovedBackgroundJob(lock);
|
||||
|
||||
if (main_thread_blocking_on_job_ == job) {
|
||||
main_thread_blocking_on_job_ = nullptr;
|
||||
@ -322,50 +456,42 @@ void LazyCompileDispatcher::DoBackgroundWork(JobDelegate* delegate) {
|
||||
// deleted.
|
||||
}
|
||||
|
||||
std::tuple<SharedFunctionInfo, LazyCompileDispatcher::Job*>
|
||||
LazyCompileDispatcher::GetSingleFinalizableJob(const base::MutexGuard&) {
|
||||
SharedToJobMap::IteratableScope iteratable_scope(&shared_to_unoptimized_job_);
|
||||
LazyCompileDispatcher::Job* LazyCompileDispatcher::PopSingleFinalizeJob() {
|
||||
base::MutexGuard lock(&mutex_);
|
||||
|
||||
auto it = iteratable_scope.begin();
|
||||
auto end = iteratable_scope.end();
|
||||
for (; it != end; ++it) {
|
||||
Job* job = *it.entry();
|
||||
if (job->state == Job::State::kReadyToFinalize ||
|
||||
job->state == Job::State::kAborted) {
|
||||
return {SharedFunctionInfo::cast(it.key()), job};
|
||||
}
|
||||
if (finalizable_jobs_.empty()) return nullptr;
|
||||
|
||||
Job* job = finalizable_jobs_.back();
|
||||
finalizable_jobs_.pop_back();
|
||||
DCHECK(job->state == Job::State::kReadyToFinalize ||
|
||||
job->state == Job::State::kAborted);
|
||||
if (job->state == Job::State::kReadyToFinalize) {
|
||||
job->state = Job::State::kFinalizingNow;
|
||||
} else {
|
||||
DCHECK_EQ(job->state, Job::State::kAborted);
|
||||
job->state = Job::State::kAbortingNow;
|
||||
}
|
||||
// Since we hold the lock here, we can be sure no jobs have become ready
|
||||
// for finalization while we looped through the list.
|
||||
return {SharedFunctionInfo(), nullptr};
|
||||
return job;
|
||||
}
|
||||
|
||||
bool LazyCompileDispatcher::FinalizeSingleJob() {
|
||||
SharedFunctionInfo function;
|
||||
Job* job;
|
||||
{
|
||||
base::MutexGuard lock(&mutex_);
|
||||
std::tie(function, job) = GetSingleFinalizableJob(lock);
|
||||
if (job == nullptr) return false;
|
||||
|
||||
// We're finalizing this job now, so remove it from the map.
|
||||
shared_to_unoptimized_job_.Delete(function, &job);
|
||||
}
|
||||
Job* job = PopSingleFinalizeJob();
|
||||
if (job == nullptr) return false;
|
||||
|
||||
if (trace_compiler_dispatcher_) {
|
||||
PrintF("LazyCompileDispatcher: idle finalizing job for ");
|
||||
function.ShortPrint();
|
||||
PrintF("\n");
|
||||
PrintF("LazyCompileDispatcher: idle finalizing job\n");
|
||||
}
|
||||
|
||||
if (job->state == Job::State::kReadyToFinalize) {
|
||||
if (job->state == Job::State::kFinalizingNow) {
|
||||
HandleScope scope(isolate_);
|
||||
Compiler::FinalizeBackgroundCompileTask(job->task.get(), isolate_,
|
||||
Compiler::CLEAR_EXCEPTION);
|
||||
} else {
|
||||
DCHECK_EQ(job->state, Job::State::kAborted);
|
||||
DCHECK_EQ(job->state, Job::State::kAbortingNow);
|
||||
job->task->AbortFunction();
|
||||
}
|
||||
delete job;
|
||||
job->state = Job::State::kFinalized;
|
||||
DeleteJob(job);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -395,26 +521,56 @@ void LazyCompileDispatcher::DoIdleWork(double deadline_in_seconds) {
|
||||
}
|
||||
}
|
||||
|
||||
void LazyCompileDispatcher::DeleteJob(Job* job) {
|
||||
DCHECK(job->state == Job::State::kFinalized);
|
||||
#ifdef DEBUG
|
||||
{
|
||||
base::MutexGuard lock(&mutex_);
|
||||
all_jobs_.erase(job);
|
||||
}
|
||||
#endif
|
||||
delete job;
|
||||
}
|
||||
|
||||
void LazyCompileDispatcher::DeleteJob(Job* job, const base::MutexGuard&) {
|
||||
DCHECK(job->state == Job::State::kFinalized);
|
||||
#ifdef DEBUG
|
||||
all_jobs_.erase(job);
|
||||
#endif
|
||||
delete job;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void LazyCompileDispatcher::VerifyBackgroundTaskCount(const base::MutexGuard&) {
|
||||
int running_jobs = 0;
|
||||
int pending_jobs = 0;
|
||||
size_t pending_jobs = 0;
|
||||
size_t running_jobs = 0;
|
||||
size_t finalizable_jobs = 0;
|
||||
|
||||
SharedToJobMap::IteratableScope iteratable_scope(&shared_to_unoptimized_job_);
|
||||
auto it = iteratable_scope.begin();
|
||||
auto end = iteratable_scope.end();
|
||||
for (; it != end; ++it) {
|
||||
Job* job = *it.entry();
|
||||
if (job->state == Job::State::kRunning ||
|
||||
job->state == Job::State::kAbortRequested) {
|
||||
running_jobs++;
|
||||
} else if (job->state == Job::State::kPending) {
|
||||
pending_jobs++;
|
||||
for (Job* job : all_jobs_) {
|
||||
switch (job->state) {
|
||||
case Job::State::kPending:
|
||||
pending_jobs++;
|
||||
break;
|
||||
case Job::State::kRunning:
|
||||
case Job::State::kAbortRequested:
|
||||
running_jobs++;
|
||||
break;
|
||||
case Job::State::kReadyToFinalize:
|
||||
case Job::State::kAborted:
|
||||
finalizable_jobs++;
|
||||
break;
|
||||
case Job::State::kPendingToRunOnForeground:
|
||||
case Job::State::kFinalizingNow:
|
||||
case Job::State::kAbortingNow:
|
||||
case Job::State::kFinalized:
|
||||
// Ignore.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_EQ(pending_jobs, pending_background_jobs_.size());
|
||||
CHECK_EQ(num_jobs_for_background_.load(), running_jobs + pending_jobs);
|
||||
CHECK_EQ(pending_background_jobs_.size(), pending_jobs);
|
||||
CHECK_EQ(finalizable_jobs_.size(), finalizable_jobs);
|
||||
CHECK_EQ(num_jobs_for_background_.load(), pending_jobs + running_jobs);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -115,13 +115,29 @@ class V8_EXPORT_PRIVATE LazyCompileDispatcher {
|
||||
|
||||
struct Job {
|
||||
enum class State {
|
||||
// Background thread states (Enqueue + DoBackgroundWork)
|
||||
// ---
|
||||
|
||||
// In the pending task queue.
|
||||
kPending,
|
||||
// Currently running on a background thread.
|
||||
kRunning,
|
||||
kAbortRequested, // ... but we want to drop the result.
|
||||
// In the finalizable task queue.
|
||||
kReadyToFinalize,
|
||||
kFinalized,
|
||||
kAbortRequested,
|
||||
kAborted,
|
||||
kPendingToRunOnForeground
|
||||
|
||||
// Main thread states (FinishNow and FinalizeSingleJob)
|
||||
// ---
|
||||
|
||||
// Popped off the pending task queue.
|
||||
kPendingToRunOnForeground,
|
||||
// Popped off the finalizable task queue.
|
||||
kFinalizingNow,
|
||||
kAbortingNow, // ... and we want to abort
|
||||
|
||||
// Finished finalizing, ready for deletion.
|
||||
kFinalized,
|
||||
};
|
||||
|
||||
explicit Job(std::unique_ptr<BackgroundCompileTask> task);
|
||||
@ -140,13 +156,26 @@ class V8_EXPORT_PRIVATE LazyCompileDispatcher {
|
||||
void WaitForJobIfRunningOnBackground(Job* job, const base::MutexGuard&);
|
||||
Job* GetJobFor(Handle<SharedFunctionInfo> shared,
|
||||
const base::MutexGuard&) const;
|
||||
std::tuple<SharedFunctionInfo, Job*> GetSingleFinalizableJob(
|
||||
const base::MutexGuard&);
|
||||
Job* PopSingleFinalizeJob();
|
||||
void ScheduleIdleTaskFromAnyThread(const base::MutexGuard&);
|
||||
bool FinalizeSingleJob();
|
||||
void DoBackgroundWork(JobDelegate* delegate);
|
||||
void DoIdleWork(double deadline_in_seconds);
|
||||
|
||||
// DeleteJob without the mutex held.
|
||||
void DeleteJob(Job* job);
|
||||
// DeleteJob with the mutex already held.
|
||||
void DeleteJob(Job* job, const base::MutexGuard&);
|
||||
|
||||
void NotifyAddedBackgroundJob(const base::MutexGuard& lock) {
|
||||
++num_jobs_for_background_;
|
||||
VerifyBackgroundTaskCount(lock);
|
||||
}
|
||||
void NotifyRemovedBackgroundJob(const base::MutexGuard& lock) {
|
||||
--num_jobs_for_background_;
|
||||
VerifyBackgroundTaskCount(lock);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void VerifyBackgroundTaskCount(const base::MutexGuard&);
|
||||
#else
|
||||
@ -171,20 +200,25 @@ class V8_EXPORT_PRIVATE LazyCompileDispatcher {
|
||||
// the mutex |mutex_| while accessing them.
|
||||
mutable base::Mutex mutex_;
|
||||
|
||||
// Mapping from SharedFunctionInfo to the corresponding unoptimized
|
||||
// compilation job.
|
||||
SharedToJobMap shared_to_unoptimized_job_;
|
||||
|
||||
// True if an idle task is scheduled to be run.
|
||||
bool idle_task_scheduled_;
|
||||
|
||||
// The set of jobs that can be run on a background thread.
|
||||
std::unordered_set<Job*> pending_background_jobs_;
|
||||
std::vector<Job*> pending_background_jobs_;
|
||||
|
||||
// The set of jobs that can be finalized on the main thread.
|
||||
std::vector<Job*> finalizable_jobs_;
|
||||
|
||||
// The total number of jobs ready to execute on background, both those pending
|
||||
// and those currently running.
|
||||
std::atomic<size_t> num_jobs_for_background_;
|
||||
|
||||
#ifdef DEBUG
|
||||
// The set of all allocated jobs, used for verification of the various queues
|
||||
// and counts.
|
||||
std::unordered_set<Job*> all_jobs_;
|
||||
#endif
|
||||
|
||||
// If not nullptr, then the main thread waits for the task processing
|
||||
// this job, and blocks on the ConditionVariable main_thread_blocking_signal_.
|
||||
Job* main_thread_blocking_on_job_;
|
||||
|
@ -357,6 +357,29 @@ FactoryBase<Impl>::NewUncompiledDataWithPreparseData(
|
||||
AllocationType::kOld);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
Handle<UncompiledDataWithoutPreparseDataWithJob>
|
||||
FactoryBase<Impl>::NewUncompiledDataWithoutPreparseDataWithJob(
|
||||
Handle<String> inferred_name, int32_t start_position,
|
||||
int32_t end_position) {
|
||||
return TorqueGeneratedFactory<
|
||||
Impl>::NewUncompiledDataWithoutPreparseDataWithJob(inferred_name,
|
||||
start_position,
|
||||
end_position,
|
||||
kNullAddress,
|
||||
AllocationType::kOld);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
Handle<UncompiledDataWithPreparseDataAndJob>
|
||||
FactoryBase<Impl>::NewUncompiledDataWithPreparseDataAndJob(
|
||||
Handle<String> inferred_name, int32_t start_position, int32_t end_position,
|
||||
Handle<PreparseData> preparse_data) {
|
||||
return TorqueGeneratedFactory<Impl>::NewUncompiledDataWithPreparseDataAndJob(
|
||||
inferred_name, start_position, end_position, preparse_data, kNullAddress,
|
||||
AllocationType::kOld);
|
||||
}
|
||||
|
||||
template <typename Impl>
|
||||
Handle<SharedFunctionInfo> FactoryBase<Impl>::NewSharedFunctionInfo(
|
||||
MaybeHandle<String> maybe_name, MaybeHandle<HeapObject> maybe_function_data,
|
||||
|
@ -178,6 +178,17 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase
|
||||
Handle<String> inferred_name, int32_t start_position,
|
||||
int32_t end_position, Handle<PreparseData>);
|
||||
|
||||
Handle<UncompiledDataWithoutPreparseDataWithJob>
|
||||
NewUncompiledDataWithoutPreparseDataWithJob(Handle<String> inferred_name,
|
||||
int32_t start_position,
|
||||
int32_t end_position);
|
||||
|
||||
Handle<UncompiledDataWithPreparseDataAndJob>
|
||||
NewUncompiledDataWithPreparseDataAndJob(Handle<String> inferred_name,
|
||||
int32_t start_position,
|
||||
int32_t end_position,
|
||||
Handle<PreparseData>);
|
||||
|
||||
// Allocates a FeedbackMedata object and zeroes the data section.
|
||||
Handle<FeedbackMetadata> NewFeedbackMetadata(
|
||||
int slot_count, int create_closure_slot_count,
|
||||
|
@ -230,6 +230,8 @@ class ZoneForwardList;
|
||||
V(UncompiledData) \
|
||||
V(UncompiledDataWithPreparseData) \
|
||||
V(UncompiledDataWithoutPreparseData) \
|
||||
V(UncompiledDataWithPreparseDataAndJob) \
|
||||
V(UncompiledDataWithoutPreparseDataWithJob) \
|
||||
V(Undetectable) \
|
||||
V(UniqueName) \
|
||||
IF_WASM(V, WasmApiFunctionRef) \
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "src/base/macros.h"
|
||||
#include "src/base/platform/mutex.h"
|
||||
#include "src/codegen/optimized-compilation-info.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/handles/handles-inl.h"
|
||||
#include "src/heap/heap-write-barrier-inl.h"
|
||||
@ -92,6 +93,8 @@ void PreparseData::set_child(int index, PreparseData value,
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(UncompiledData)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithoutPreparseData)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithPreparseData)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithoutPreparseDataWithJob)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(UncompiledDataWithPreparseDataAndJob)
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(InterpreterData)
|
||||
TQ_OBJECT_CONSTRUCTORS_IMPL(SharedFunctionInfo)
|
||||
@ -791,6 +794,17 @@ bool SharedFunctionInfo::HasUncompiledDataWithoutPreparseData() const {
|
||||
return function_data(kAcquireLoad).IsUncompiledDataWithoutPreparseData();
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::ClearUncompiledDataJobPointer() {
|
||||
UncompiledData uncompiled_data = this->uncompiled_data();
|
||||
if (uncompiled_data.IsUncompiledDataWithPreparseDataAndJob()) {
|
||||
UncompiledDataWithPreparseDataAndJob::cast(uncompiled_data)
|
||||
.set_job(kNullAddress);
|
||||
} else if (uncompiled_data.IsUncompiledDataWithoutPreparseDataWithJob()) {
|
||||
UncompiledDataWithoutPreparseDataWithJob::cast(uncompiled_data)
|
||||
.set_job(kNullAddress);
|
||||
}
|
||||
}
|
||||
|
||||
void SharedFunctionInfo::ClearPreparseData() {
|
||||
DCHECK(HasUncompiledDataWithPreparseData());
|
||||
UncompiledDataWithPreparseData data = uncompiled_data_with_preparse_data();
|
||||
|
@ -549,13 +549,25 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
|
||||
if (scope_data != nullptr) {
|
||||
Handle<PreparseData> preparse_data = scope_data->Serialize(isolate);
|
||||
|
||||
data = isolate->factory()->NewUncompiledDataWithPreparseData(
|
||||
lit->GetInferredName(isolate), lit->start_position(),
|
||||
lit->end_position(), preparse_data);
|
||||
if (lit->should_parallel_compile()) {
|
||||
data = isolate->factory()->NewUncompiledDataWithPreparseDataAndJob(
|
||||
lit->GetInferredName(isolate), lit->start_position(),
|
||||
lit->end_position(), preparse_data);
|
||||
} else {
|
||||
data = isolate->factory()->NewUncompiledDataWithPreparseData(
|
||||
lit->GetInferredName(isolate), lit->start_position(),
|
||||
lit->end_position(), preparse_data);
|
||||
}
|
||||
} else {
|
||||
data = isolate->factory()->NewUncompiledDataWithoutPreparseData(
|
||||
lit->GetInferredName(isolate), lit->start_position(),
|
||||
lit->end_position());
|
||||
if (lit->should_parallel_compile()) {
|
||||
data = isolate->factory()->NewUncompiledDataWithoutPreparseDataWithJob(
|
||||
lit->GetInferredName(isolate), lit->start_position(),
|
||||
lit->end_position());
|
||||
} else {
|
||||
data = isolate->factory()->NewUncompiledDataWithoutPreparseData(
|
||||
lit->GetInferredName(isolate), lit->start_position(),
|
||||
lit->end_position());
|
||||
}
|
||||
}
|
||||
|
||||
shared_info->set_uncompiled_data(*data);
|
||||
|
@ -145,6 +145,31 @@ class UncompiledDataWithPreparseData
|
||||
TQ_OBJECT_CONSTRUCTORS(UncompiledDataWithPreparseData)
|
||||
};
|
||||
|
||||
// Class representing data for an uncompiled function that does not have any
|
||||
// data from the pre-parser, either because it's a leaf function or because the
|
||||
// pre-parser bailed out, but has a job pointer.
|
||||
class UncompiledDataWithoutPreparseDataWithJob
|
||||
: public TorqueGeneratedUncompiledDataWithoutPreparseDataWithJob<
|
||||
UncompiledDataWithoutPreparseDataWithJob,
|
||||
UncompiledDataWithoutPreparseData> {
|
||||
public:
|
||||
class BodyDescriptor;
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS(UncompiledDataWithoutPreparseDataWithJob)
|
||||
};
|
||||
|
||||
// Class representing data for an uncompiled function that has pre-parsed scope
|
||||
// data and a job pointer.
|
||||
class UncompiledDataWithPreparseDataAndJob
|
||||
: public TorqueGeneratedUncompiledDataWithPreparseDataAndJob<
|
||||
UncompiledDataWithPreparseDataAndJob,
|
||||
UncompiledDataWithPreparseData> {
|
||||
public:
|
||||
class BodyDescriptor;
|
||||
|
||||
TQ_OBJECT_CONSTRUCTORS(UncompiledDataWithPreparseDataAndJob)
|
||||
};
|
||||
|
||||
class InterpreterData
|
||||
: public TorqueGeneratedInterpreterData<InterpreterData, Struct> {
|
||||
public:
|
||||
@ -351,6 +376,7 @@ class SharedFunctionInfo
|
||||
inline void set_uncompiled_data_with_preparse_data(
|
||||
UncompiledDataWithPreparseData data);
|
||||
inline bool HasUncompiledDataWithoutPreparseData() const;
|
||||
inline void ClearUncompiledDataJobPointer();
|
||||
|
||||
// Clear out pre-parsed scope data from UncompiledDataWithPreparseData,
|
||||
// turning it into UncompiledDataWithoutPreparseData.
|
||||
|
@ -135,6 +135,24 @@ extern class UncompiledDataWithPreparseData extends UncompiledData {
|
||||
preparse_data: PreparseData;
|
||||
}
|
||||
|
||||
@generateBodyDescriptor
|
||||
@generateUniqueMap
|
||||
@generateFactoryFunction
|
||||
extern class UncompiledDataWithoutPreparseDataWithJob extends
|
||||
UncompiledDataWithoutPreparseData {
|
||||
// TODO(v8:10391): Define the field as ExternalPointer or move jobs into cage.
|
||||
job: RawPtr;
|
||||
}
|
||||
|
||||
@generateBodyDescriptor
|
||||
@generateUniqueMap
|
||||
@generateFactoryFunction
|
||||
extern class UncompiledDataWithPreparseDataAndJob extends
|
||||
UncompiledDataWithPreparseData {
|
||||
// TODO(v8:10391): Define the field as ExternalPointer or move jobs into cage.
|
||||
job: RawPtr;
|
||||
}
|
||||
|
||||
@export
|
||||
class OnHeapBasicBlockProfilerData extends HeapObject {
|
||||
block_ids: ByteArray; // Stored as 4-byte ints
|
||||
|
@ -201,6 +201,25 @@ void CodeSerializer::SerializeObjectImpl(Handle<HeapObject> obj) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj->IsUncompiledDataWithoutPreparseDataWithJob()) {
|
||||
Handle<UncompiledDataWithoutPreparseDataWithJob> data =
|
||||
Handle<UncompiledDataWithoutPreparseDataWithJob>::cast(obj);
|
||||
Address job = data->job();
|
||||
data->set_job(kNullAddress);
|
||||
SerializeGeneric(data);
|
||||
data->set_job(job);
|
||||
return;
|
||||
}
|
||||
if (obj->IsUncompiledDataWithPreparseDataAndJob()) {
|
||||
Handle<UncompiledDataWithPreparseDataAndJob> data =
|
||||
Handle<UncompiledDataWithPreparseDataAndJob>::cast(obj);
|
||||
Address job = data->job();
|
||||
data->set_job(kNullAddress);
|
||||
SerializeGeneric(data);
|
||||
data->set_job(job);
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE(mmarchini): If we try to serialize an InterpreterData our process
|
||||
// will crash since it stores a code object. Instead, we serialize the
|
||||
// bytecode array stored within the InterpreterData, which is the important
|
||||
|
@ -25,6 +25,12 @@
|
||||
#include "test/unittests/test-utils.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_ASSERT_EQ ASSERT_EQ
|
||||
#else
|
||||
#define DEBUG_ASSERT_EQ(...)
|
||||
#endif
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
@ -397,11 +403,17 @@ TEST_F(LazyCompileDispatcherTest, IdleTaskNoIdleTime) {
|
||||
|
||||
EnqueueUnoptimizedCompileJob(&dispatcher, i_isolate(), shared);
|
||||
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 0u);
|
||||
|
||||
// Run compile steps.
|
||||
platform.RunJobTasksAndBlock(V8::GetCurrentPlatform());
|
||||
|
||||
// Job should be ready to finalize.
|
||||
ASSERT_EQ(dispatcher.shared_to_unoptimized_job_.size(), 1);
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 0u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 1u);
|
||||
ASSERT_EQ(
|
||||
dispatcher.GetJobFor(shared, base::MutexGuard(&dispatcher.mutex_))->state,
|
||||
LazyCompileDispatcher::Job::State::kReadyToFinalize);
|
||||
@ -415,7 +427,8 @@ TEST_F(LazyCompileDispatcherTest, IdleTaskNoIdleTime) {
|
||||
ASSERT_TRUE(platform.IdleTaskPending());
|
||||
|
||||
// Job should be ready to finalize.
|
||||
ASSERT_EQ(dispatcher.shared_to_unoptimized_job_.size(), 1);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 0u);
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 1u);
|
||||
ASSERT_EQ(
|
||||
dispatcher.GetJobFor(shared, base::MutexGuard(&dispatcher.mutex_))->state,
|
||||
LazyCompileDispatcher::Job::State::kReadyToFinalize);
|
||||
@ -444,11 +457,17 @@ TEST_F(LazyCompileDispatcherTest, IdleTaskSmallIdleTime) {
|
||||
EnqueueUnoptimizedCompileJob(&dispatcher, i_isolate(), shared_1);
|
||||
EnqueueUnoptimizedCompileJob(&dispatcher, i_isolate(), shared_2);
|
||||
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 2u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 2u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 0u);
|
||||
|
||||
// Run compile steps.
|
||||
platform.RunJobTasksAndBlock(V8::GetCurrentPlatform());
|
||||
|
||||
// Both jobs should be ready to finalize.
|
||||
ASSERT_EQ(dispatcher.shared_to_unoptimized_job_.size(), 2);
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 2u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 0u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 2u);
|
||||
ASSERT_EQ(
|
||||
dispatcher.GetJobFor(shared_1, base::MutexGuard(&dispatcher.mutex_))
|
||||
->state,
|
||||
@ -464,7 +483,9 @@ TEST_F(LazyCompileDispatcherTest, IdleTaskSmallIdleTime) {
|
||||
platform.RunIdleTask(2.0, 1.0);
|
||||
|
||||
// Only one of the jobs should be finalized.
|
||||
ASSERT_EQ(dispatcher.shared_to_unoptimized_job_.size(), 1);
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 0u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 1u);
|
||||
if (dispatcher.IsEnqueued(shared_1)) {
|
||||
ASSERT_EQ(
|
||||
dispatcher.GetJobFor(shared_1, base::MutexGuard(&dispatcher.mutex_))
|
||||
@ -532,7 +553,9 @@ TEST_F(LazyCompileDispatcherTest, FinishNowWithWorkerTask) {
|
||||
|
||||
ASSERT_TRUE(dispatcher.IsEnqueued(shared));
|
||||
ASSERT_FALSE(shared->is_compiled());
|
||||
ASSERT_EQ(dispatcher.shared_to_unoptimized_job_.size(), 1);
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 0u);
|
||||
ASSERT_NE(
|
||||
dispatcher.GetJobFor(shared, base::MutexGuard(&dispatcher.mutex_))->state,
|
||||
LazyCompileDispatcher::Job::State::kReadyToFinalize);
|
||||
@ -544,6 +567,7 @@ TEST_F(LazyCompileDispatcherTest, FinishNowWithWorkerTask) {
|
||||
ASSERT_TRUE(dispatcher.FinishNow(shared));
|
||||
// Finishing removes the SFI from the queue.
|
||||
ASSERT_FALSE(dispatcher.IsEnqueued(shared));
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 0u);
|
||||
ASSERT_TRUE(shared->is_compiled());
|
||||
if (platform.IdleTaskPending()) platform.ClearIdleTask();
|
||||
ASSERT_FALSE(platform.JobTaskPending());
|
||||
@ -620,7 +644,9 @@ TEST_F(LazyCompileDispatcherTest, AbortJobNotStarted) {
|
||||
EnqueueUnoptimizedCompileJob(&dispatcher, i_isolate(), shared);
|
||||
|
||||
ASSERT_FALSE(shared->is_compiled());
|
||||
ASSERT_EQ(dispatcher.shared_to_unoptimized_job_.size(), 1);
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 0u);
|
||||
ASSERT_NE(
|
||||
dispatcher.GetJobFor(shared, base::MutexGuard(&dispatcher.mutex_))->state,
|
||||
LazyCompileDispatcher::Job::State::kReadyToFinalize);
|
||||
@ -645,7 +671,9 @@ TEST_F(LazyCompileDispatcherTest, AbortJobAlreadyStarted) {
|
||||
EnqueueUnoptimizedCompileJob(&dispatcher, i_isolate(), shared);
|
||||
|
||||
ASSERT_FALSE(shared->is_compiled());
|
||||
ASSERT_EQ(dispatcher.shared_to_unoptimized_job_.size(), 1);
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 0u);
|
||||
ASSERT_NE(
|
||||
dispatcher.GetJobFor(shared, base::MutexGuard(&dispatcher.mutex_))->state,
|
||||
LazyCompileDispatcher::Job::State::kReadyToFinalize);
|
||||
@ -674,7 +702,9 @@ TEST_F(LazyCompileDispatcherTest, AbortJobAlreadyStarted) {
|
||||
|
||||
// Job should have finished running and then been aborted.
|
||||
ASSERT_FALSE(shared->is_compiled());
|
||||
ASSERT_EQ(dispatcher.shared_to_unoptimized_job_.size(), 1);
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 1u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 0u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 1u);
|
||||
ASSERT_EQ(
|
||||
dispatcher.GetJobFor(shared, base::MutexGuard(&dispatcher.mutex_))->state,
|
||||
LazyCompileDispatcher::Job::State::kAborted);
|
||||
@ -760,7 +790,9 @@ TEST_F(LazyCompileDispatcherTest, CompileMultipleOnBackgroundThread) {
|
||||
|
||||
EnqueueUnoptimizedCompileJob(&dispatcher, i_isolate(), shared_2);
|
||||
|
||||
ASSERT_EQ(dispatcher.shared_to_unoptimized_job_.size(), 2);
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 2u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 2u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 0u);
|
||||
ASSERT_NE(
|
||||
dispatcher.GetJobFor(shared_1, base::MutexGuard(&dispatcher.mutex_))
|
||||
->state,
|
||||
@ -781,7 +813,9 @@ TEST_F(LazyCompileDispatcherTest, CompileMultipleOnBackgroundThread) {
|
||||
|
||||
ASSERT_TRUE(platform.IdleTaskPending());
|
||||
ASSERT_FALSE(platform.JobTaskPending());
|
||||
ASSERT_EQ(dispatcher.shared_to_unoptimized_job_.size(), 2);
|
||||
DEBUG_ASSERT_EQ(dispatcher.all_jobs_.size(), 2u);
|
||||
ASSERT_EQ(dispatcher.pending_background_jobs_.size(), 0u);
|
||||
ASSERT_EQ(dispatcher.finalizable_jobs_.size(), 2u);
|
||||
ASSERT_EQ(
|
||||
dispatcher.GetJobFor(shared_1, base::MutexGuard(&dispatcher.mutex_))
|
||||
->state,
|
||||
|
@ -43,7 +43,7 @@ Handle<SharedFunctionInfo> CreateSharedFunctionInfo(
|
||||
shared->set_function_literal_id(function_literal_id);
|
||||
// Ensure that the function can be compiled lazily.
|
||||
shared->set_uncompiled_data(
|
||||
*isolate->factory()->NewUncompiledDataWithoutPreparseData(
|
||||
*isolate->factory()->NewUncompiledDataWithoutPreparseDataWithJob(
|
||||
ReadOnlyRoots(isolate).empty_string_handle(), 0, source->length()));
|
||||
// Make sure we have an outer scope info, even though it's empty
|
||||
shared->set_raw_outer_scope_info_or_feedback_metadata(
|
||||
|
@ -113,59 +113,61 @@ INSTANCE_TYPES = {
|
||||
209: "TURBOFAN_OTHER_NUMBER_CONSTANT_TYPE_TYPE",
|
||||
210: "TURBOFAN_RANGE_TYPE_TYPE",
|
||||
211: "TURBOFAN_UNION_TYPE_TYPE",
|
||||
212: "WASM_FUNCTION_DATA_TYPE",
|
||||
213: "WASM_CAPI_FUNCTION_DATA_TYPE",
|
||||
214: "WASM_EXPORTED_FUNCTION_DATA_TYPE",
|
||||
215: "WASM_JS_FUNCTION_DATA_TYPE",
|
||||
216: "EXPORTED_SUB_CLASS_BASE_TYPE",
|
||||
217: "EXPORTED_SUB_CLASS_TYPE",
|
||||
218: "EXPORTED_SUB_CLASS2_TYPE",
|
||||
219: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||
220: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||
221: "SMALL_ORDERED_NAME_DICTIONARY_TYPE",
|
||||
222: "ABSTRACT_INTERNAL_CLASS_SUBCLASS1_TYPE",
|
||||
223: "ABSTRACT_INTERNAL_CLASS_SUBCLASS2_TYPE",
|
||||
224: "DESCRIPTOR_ARRAY_TYPE",
|
||||
225: "STRONG_DESCRIPTOR_ARRAY_TYPE",
|
||||
226: "SOURCE_TEXT_MODULE_TYPE",
|
||||
227: "SYNTHETIC_MODULE_TYPE",
|
||||
228: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE",
|
||||
229: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE",
|
||||
230: "WEAK_FIXED_ARRAY_TYPE",
|
||||
231: "TRANSITION_ARRAY_TYPE",
|
||||
232: "CELL_TYPE",
|
||||
233: "CODE_TYPE",
|
||||
234: "CODE_DATA_CONTAINER_TYPE",
|
||||
235: "COVERAGE_INFO_TYPE",
|
||||
236: "EMBEDDER_DATA_ARRAY_TYPE",
|
||||
237: "FEEDBACK_METADATA_TYPE",
|
||||
238: "FEEDBACK_VECTOR_TYPE",
|
||||
239: "FILLER_TYPE",
|
||||
240: "FREE_SPACE_TYPE",
|
||||
241: "INTERNAL_CLASS_TYPE",
|
||||
242: "INTERNAL_CLASS_WITH_STRUCT_ELEMENTS_TYPE",
|
||||
243: "MAP_TYPE",
|
||||
244: "MEGA_DOM_HANDLER_TYPE",
|
||||
245: "ON_HEAP_BASIC_BLOCK_PROFILER_DATA_TYPE",
|
||||
246: "PREPARSE_DATA_TYPE",
|
||||
247: "PROPERTY_ARRAY_TYPE",
|
||||
248: "PROPERTY_CELL_TYPE",
|
||||
249: "SCOPE_INFO_TYPE",
|
||||
250: "SHARED_FUNCTION_INFO_TYPE",
|
||||
251: "SMI_BOX_TYPE",
|
||||
252: "SMI_PAIR_TYPE",
|
||||
253: "SORT_STATE_TYPE",
|
||||
254: "SWISS_NAME_DICTIONARY_TYPE",
|
||||
255: "WASM_API_FUNCTION_REF_TYPE",
|
||||
256: "WEAK_ARRAY_LIST_TYPE",
|
||||
257: "WEAK_CELL_TYPE",
|
||||
258: "WASM_ARRAY_TYPE",
|
||||
259: "WASM_STRUCT_TYPE",
|
||||
260: "JS_PROXY_TYPE",
|
||||
212: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE",
|
||||
213: "UNCOMPILED_DATA_WITH_PREPARSE_DATA_AND_JOB_TYPE",
|
||||
214: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE",
|
||||
215: "UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_WITH_JOB_TYPE",
|
||||
216: "WASM_FUNCTION_DATA_TYPE",
|
||||
217: "WASM_CAPI_FUNCTION_DATA_TYPE",
|
||||
218: "WASM_EXPORTED_FUNCTION_DATA_TYPE",
|
||||
219: "WASM_JS_FUNCTION_DATA_TYPE",
|
||||
220: "EXPORTED_SUB_CLASS_BASE_TYPE",
|
||||
221: "EXPORTED_SUB_CLASS_TYPE",
|
||||
222: "EXPORTED_SUB_CLASS2_TYPE",
|
||||
223: "SMALL_ORDERED_HASH_MAP_TYPE",
|
||||
224: "SMALL_ORDERED_HASH_SET_TYPE",
|
||||
225: "SMALL_ORDERED_NAME_DICTIONARY_TYPE",
|
||||
226: "ABSTRACT_INTERNAL_CLASS_SUBCLASS1_TYPE",
|
||||
227: "ABSTRACT_INTERNAL_CLASS_SUBCLASS2_TYPE",
|
||||
228: "DESCRIPTOR_ARRAY_TYPE",
|
||||
229: "STRONG_DESCRIPTOR_ARRAY_TYPE",
|
||||
230: "SOURCE_TEXT_MODULE_TYPE",
|
||||
231: "SYNTHETIC_MODULE_TYPE",
|
||||
232: "WEAK_FIXED_ARRAY_TYPE",
|
||||
233: "TRANSITION_ARRAY_TYPE",
|
||||
234: "CELL_TYPE",
|
||||
235: "CODE_TYPE",
|
||||
236: "CODE_DATA_CONTAINER_TYPE",
|
||||
237: "COVERAGE_INFO_TYPE",
|
||||
238: "EMBEDDER_DATA_ARRAY_TYPE",
|
||||
239: "FEEDBACK_METADATA_TYPE",
|
||||
240: "FEEDBACK_VECTOR_TYPE",
|
||||
241: "FILLER_TYPE",
|
||||
242: "FREE_SPACE_TYPE",
|
||||
243: "INTERNAL_CLASS_TYPE",
|
||||
244: "INTERNAL_CLASS_WITH_STRUCT_ELEMENTS_TYPE",
|
||||
245: "MAP_TYPE",
|
||||
246: "MEGA_DOM_HANDLER_TYPE",
|
||||
247: "ON_HEAP_BASIC_BLOCK_PROFILER_DATA_TYPE",
|
||||
248: "PREPARSE_DATA_TYPE",
|
||||
249: "PROPERTY_ARRAY_TYPE",
|
||||
250: "PROPERTY_CELL_TYPE",
|
||||
251: "SCOPE_INFO_TYPE",
|
||||
252: "SHARED_FUNCTION_INFO_TYPE",
|
||||
253: "SMI_BOX_TYPE",
|
||||
254: "SMI_PAIR_TYPE",
|
||||
255: "SORT_STATE_TYPE",
|
||||
256: "SWISS_NAME_DICTIONARY_TYPE",
|
||||
257: "WASM_API_FUNCTION_REF_TYPE",
|
||||
258: "WEAK_ARRAY_LIST_TYPE",
|
||||
259: "WEAK_CELL_TYPE",
|
||||
260: "WASM_ARRAY_TYPE",
|
||||
261: "WASM_STRUCT_TYPE",
|
||||
262: "JS_PROXY_TYPE",
|
||||
1057: "JS_OBJECT_TYPE",
|
||||
261: "JS_GLOBAL_OBJECT_TYPE",
|
||||
262: "JS_GLOBAL_PROXY_TYPE",
|
||||
263: "JS_MODULE_NAMESPACE_TYPE",
|
||||
263: "JS_GLOBAL_OBJECT_TYPE",
|
||||
264: "JS_GLOBAL_PROXY_TYPE",
|
||||
265: "JS_MODULE_NAMESPACE_TYPE",
|
||||
1040: "JS_SPECIAL_API_OBJECT_TYPE",
|
||||
1041: "JS_PRIMITIVE_WRAPPER_TYPE",
|
||||
1058: "JS_API_OBJECT_TYPE",
|
||||
@ -260,16 +262,16 @@ INSTANCE_TYPES = {
|
||||
|
||||
# List of known V8 maps.
|
||||
KNOWN_MAPS = {
|
||||
("read_only_space", 0x02119): (243, "MetaMap"),
|
||||
("read_only_space", 0x02119): (245, "MetaMap"),
|
||||
("read_only_space", 0x02141): (131, "NullMap"),
|
||||
("read_only_space", 0x02169): (225, "StrongDescriptorArrayMap"),
|
||||
("read_only_space", 0x02191): (256, "WeakArrayListMap"),
|
||||
("read_only_space", 0x02169): (229, "StrongDescriptorArrayMap"),
|
||||
("read_only_space", 0x02191): (258, "WeakArrayListMap"),
|
||||
("read_only_space", 0x021d5): (156, "EnumCacheMap"),
|
||||
("read_only_space", 0x02209): (176, "FixedArrayMap"),
|
||||
("read_only_space", 0x02255): (8, "OneByteInternalizedStringMap"),
|
||||
("read_only_space", 0x022a1): (240, "FreeSpaceMap"),
|
||||
("read_only_space", 0x022c9): (239, "OnePointerFillerMap"),
|
||||
("read_only_space", 0x022f1): (239, "TwoPointerFillerMap"),
|
||||
("read_only_space", 0x022a1): (242, "FreeSpaceMap"),
|
||||
("read_only_space", 0x022c9): (241, "OnePointerFillerMap"),
|
||||
("read_only_space", 0x022f1): (241, "TwoPointerFillerMap"),
|
||||
("read_only_space", 0x02319): (131, "UninitializedMap"),
|
||||
("read_only_space", 0x02391): (131, "UndefinedMap"),
|
||||
("read_only_space", 0x023d5): (130, "HeapNumberMap"),
|
||||
@ -280,15 +282,15 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x0255d): (177, "HashTableMap"),
|
||||
("read_only_space", 0x02585): (128, "SymbolMap"),
|
||||
("read_only_space", 0x025ad): (40, "OneByteStringMap"),
|
||||
("read_only_space", 0x025d5): (249, "ScopeInfoMap"),
|
||||
("read_only_space", 0x025fd): (250, "SharedFunctionInfoMap"),
|
||||
("read_only_space", 0x02625): (233, "CodeMap"),
|
||||
("read_only_space", 0x0264d): (232, "CellMap"),
|
||||
("read_only_space", 0x02675): (248, "GlobalPropertyCellMap"),
|
||||
("read_only_space", 0x025d5): (251, "ScopeInfoMap"),
|
||||
("read_only_space", 0x025fd): (252, "SharedFunctionInfoMap"),
|
||||
("read_only_space", 0x02625): (235, "CodeMap"),
|
||||
("read_only_space", 0x0264d): (234, "CellMap"),
|
||||
("read_only_space", 0x02675): (250, "GlobalPropertyCellMap"),
|
||||
("read_only_space", 0x0269d): (204, "ForeignMap"),
|
||||
("read_only_space", 0x026c5): (231, "TransitionArrayMap"),
|
||||
("read_only_space", 0x026c5): (233, "TransitionArrayMap"),
|
||||
("read_only_space", 0x026ed): (45, "ThinOneByteStringMap"),
|
||||
("read_only_space", 0x02715): (238, "FeedbackVectorMap"),
|
||||
("read_only_space", 0x02715): (240, "FeedbackVectorMap"),
|
||||
("read_only_space", 0x0274d): (131, "ArgumentsMarkerMap"),
|
||||
("read_only_space", 0x027ad): (131, "ExceptionMap"),
|
||||
("read_only_space", 0x02809): (131, "TerminationExceptionMap"),
|
||||
@ -296,17 +298,17 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x028d1): (131, "StaleRegisterMap"),
|
||||
("read_only_space", 0x02931): (188, "ScriptContextTableMap"),
|
||||
("read_only_space", 0x02959): (186, "ClosureFeedbackCellArrayMap"),
|
||||
("read_only_space", 0x02981): (237, "FeedbackMetadataArrayMap"),
|
||||
("read_only_space", 0x02981): (239, "FeedbackMetadataArrayMap"),
|
||||
("read_only_space", 0x029a9): (176, "ArrayListMap"),
|
||||
("read_only_space", 0x029d1): (129, "BigIntMap"),
|
||||
("read_only_space", 0x029f9): (187, "ObjectBoilerplateDescriptionMap"),
|
||||
("read_only_space", 0x02a21): (190, "BytecodeArrayMap"),
|
||||
("read_only_space", 0x02a49): (234, "CodeDataContainerMap"),
|
||||
("read_only_space", 0x02a71): (235, "CoverageInfoMap"),
|
||||
("read_only_space", 0x02a49): (236, "CodeDataContainerMap"),
|
||||
("read_only_space", 0x02a71): (237, "CoverageInfoMap"),
|
||||
("read_only_space", 0x02a99): (191, "FixedDoubleArrayMap"),
|
||||
("read_only_space", 0x02ac1): (179, "GlobalDictionaryMap"),
|
||||
("read_only_space", 0x02ae9): (157, "ManyClosuresCellMap"),
|
||||
("read_only_space", 0x02b11): (244, "MegaDomHandlerMap"),
|
||||
("read_only_space", 0x02b11): (246, "MegaDomHandlerMap"),
|
||||
("read_only_space", 0x02b39): (176, "ModuleInfoMap"),
|
||||
("read_only_space", 0x02b61): (180, "NameDictionaryMap"),
|
||||
("read_only_space", 0x02b89): (157, "NoClosuresCellMap"),
|
||||
@ -315,28 +317,28 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x02c01): (182, "OrderedHashMapMap"),
|
||||
("read_only_space", 0x02c29): (183, "OrderedHashSetMap"),
|
||||
("read_only_space", 0x02c51): (184, "OrderedNameDictionaryMap"),
|
||||
("read_only_space", 0x02c79): (246, "PreparseDataMap"),
|
||||
("read_only_space", 0x02ca1): (247, "PropertyArrayMap"),
|
||||
("read_only_space", 0x02c79): (248, "PreparseDataMap"),
|
||||
("read_only_space", 0x02ca1): (249, "PropertyArrayMap"),
|
||||
("read_only_space", 0x02cc9): (153, "SideEffectCallHandlerInfoMap"),
|
||||
("read_only_space", 0x02cf1): (153, "SideEffectFreeCallHandlerInfoMap"),
|
||||
("read_only_space", 0x02d19): (153, "NextCallSideEffectFreeCallHandlerInfoMap"),
|
||||
("read_only_space", 0x02d41): (185, "SimpleNumberDictionaryMap"),
|
||||
("read_only_space", 0x02d69): (219, "SmallOrderedHashMapMap"),
|
||||
("read_only_space", 0x02d91): (220, "SmallOrderedHashSetMap"),
|
||||
("read_only_space", 0x02db9): (221, "SmallOrderedNameDictionaryMap"),
|
||||
("read_only_space", 0x02de1): (226, "SourceTextModuleMap"),
|
||||
("read_only_space", 0x02e09): (254, "SwissNameDictionaryMap"),
|
||||
("read_only_space", 0x02e31): (227, "SyntheticModuleMap"),
|
||||
("read_only_space", 0x02e59): (255, "WasmApiFunctionRefMap"),
|
||||
("read_only_space", 0x02e81): (213, "WasmCapiFunctionDataMap"),
|
||||
("read_only_space", 0x02ea9): (214, "WasmExportedFunctionDataMap"),
|
||||
("read_only_space", 0x02d69): (223, "SmallOrderedHashMapMap"),
|
||||
("read_only_space", 0x02d91): (224, "SmallOrderedHashSetMap"),
|
||||
("read_only_space", 0x02db9): (225, "SmallOrderedNameDictionaryMap"),
|
||||
("read_only_space", 0x02de1): (230, "SourceTextModuleMap"),
|
||||
("read_only_space", 0x02e09): (256, "SwissNameDictionaryMap"),
|
||||
("read_only_space", 0x02e31): (231, "SyntheticModuleMap"),
|
||||
("read_only_space", 0x02e59): (257, "WasmApiFunctionRefMap"),
|
||||
("read_only_space", 0x02e81): (217, "WasmCapiFunctionDataMap"),
|
||||
("read_only_space", 0x02ea9): (218, "WasmExportedFunctionDataMap"),
|
||||
("read_only_space", 0x02ed1): (205, "WasmInternalFunctionMap"),
|
||||
("read_only_space", 0x02ef9): (215, "WasmJSFunctionDataMap"),
|
||||
("read_only_space", 0x02ef9): (219, "WasmJSFunctionDataMap"),
|
||||
("read_only_space", 0x02f21): (206, "WasmTypeInfoMap"),
|
||||
("read_only_space", 0x02f49): (230, "WeakFixedArrayMap"),
|
||||
("read_only_space", 0x02f49): (232, "WeakFixedArrayMap"),
|
||||
("read_only_space", 0x02f71): (178, "EphemeronHashTableMap"),
|
||||
("read_only_space", 0x02f99): (236, "EmbedderDataArrayMap"),
|
||||
("read_only_space", 0x02fc1): (257, "WeakCellMap"),
|
||||
("read_only_space", 0x02f99): (238, "EmbedderDataArrayMap"),
|
||||
("read_only_space", 0x02fc1): (259, "WeakCellMap"),
|
||||
("read_only_space", 0x02fe9): (32, "StringMap"),
|
||||
("read_only_space", 0x03011): (41, "ConsOneByteStringMap"),
|
||||
("read_only_space", 0x03039): (33, "ConsStringMap"),
|
||||
@ -399,35 +401,37 @@ KNOWN_MAPS = {
|
||||
("read_only_space", 0x06261): (174, "WasmExceptionTagMap"),
|
||||
("read_only_space", 0x06289): (175, "WasmIndirectFunctionTableMap"),
|
||||
("read_only_space", 0x062b1): (193, "SloppyArgumentsElementsMap"),
|
||||
("read_only_space", 0x062d9): (224, "DescriptorArrayMap"),
|
||||
("read_only_space", 0x06301): (229, "UncompiledDataWithoutPreparseDataMap"),
|
||||
("read_only_space", 0x06329): (228, "UncompiledDataWithPreparseDataMap"),
|
||||
("read_only_space", 0x06351): (245, "OnHeapBasicBlockProfilerDataMap"),
|
||||
("read_only_space", 0x06379): (207, "TurbofanBitsetTypeMap"),
|
||||
("read_only_space", 0x063a1): (211, "TurbofanUnionTypeMap"),
|
||||
("read_only_space", 0x063c9): (210, "TurbofanRangeTypeMap"),
|
||||
("read_only_space", 0x063f1): (208, "TurbofanHeapConstantTypeMap"),
|
||||
("read_only_space", 0x06419): (209, "TurbofanOtherNumberConstantTypeMap"),
|
||||
("read_only_space", 0x06441): (241, "InternalClassMap"),
|
||||
("read_only_space", 0x06469): (252, "SmiPairMap"),
|
||||
("read_only_space", 0x06491): (251, "SmiBoxMap"),
|
||||
("read_only_space", 0x064b9): (216, "ExportedSubClassBaseMap"),
|
||||
("read_only_space", 0x064e1): (217, "ExportedSubClassMap"),
|
||||
("read_only_space", 0x06509): (222, "AbstractInternalClassSubclass1Map"),
|
||||
("read_only_space", 0x06531): (223, "AbstractInternalClassSubclass2Map"),
|
||||
("read_only_space", 0x06559): (192, "InternalClassWithSmiElementsMap"),
|
||||
("read_only_space", 0x06581): (242, "InternalClassWithStructElementsMap"),
|
||||
("read_only_space", 0x065a9): (218, "ExportedSubClass2Map"),
|
||||
("read_only_space", 0x065d1): (253, "SortStateMap"),
|
||||
("read_only_space", 0x065f9): (146, "AllocationSiteWithWeakNextMap"),
|
||||
("read_only_space", 0x06621): (146, "AllocationSiteWithoutWeakNextMap"),
|
||||
("read_only_space", 0x06649): (137, "LoadHandler1Map"),
|
||||
("read_only_space", 0x06671): (137, "LoadHandler2Map"),
|
||||
("read_only_space", 0x06699): (137, "LoadHandler3Map"),
|
||||
("read_only_space", 0x066c1): (138, "StoreHandler0Map"),
|
||||
("read_only_space", 0x066e9): (138, "StoreHandler1Map"),
|
||||
("read_only_space", 0x06711): (138, "StoreHandler2Map"),
|
||||
("read_only_space", 0x06739): (138, "StoreHandler3Map"),
|
||||
("read_only_space", 0x062d9): (228, "DescriptorArrayMap"),
|
||||
("read_only_space", 0x06301): (214, "UncompiledDataWithoutPreparseDataMap"),
|
||||
("read_only_space", 0x06329): (212, "UncompiledDataWithPreparseDataMap"),
|
||||
("read_only_space", 0x06351): (215, "UncompiledDataWithoutPreparseDataWithJobMap"),
|
||||
("read_only_space", 0x06379): (213, "UncompiledDataWithPreparseDataAndJobMap"),
|
||||
("read_only_space", 0x063a1): (247, "OnHeapBasicBlockProfilerDataMap"),
|
||||
("read_only_space", 0x063c9): (207, "TurbofanBitsetTypeMap"),
|
||||
("read_only_space", 0x063f1): (211, "TurbofanUnionTypeMap"),
|
||||
("read_only_space", 0x06419): (210, "TurbofanRangeTypeMap"),
|
||||
("read_only_space", 0x06441): (208, "TurbofanHeapConstantTypeMap"),
|
||||
("read_only_space", 0x06469): (209, "TurbofanOtherNumberConstantTypeMap"),
|
||||
("read_only_space", 0x06491): (243, "InternalClassMap"),
|
||||
("read_only_space", 0x064b9): (254, "SmiPairMap"),
|
||||
("read_only_space", 0x064e1): (253, "SmiBoxMap"),
|
||||
("read_only_space", 0x06509): (220, "ExportedSubClassBaseMap"),
|
||||
("read_only_space", 0x06531): (221, "ExportedSubClassMap"),
|
||||
("read_only_space", 0x06559): (226, "AbstractInternalClassSubclass1Map"),
|
||||
("read_only_space", 0x06581): (227, "AbstractInternalClassSubclass2Map"),
|
||||
("read_only_space", 0x065a9): (192, "InternalClassWithSmiElementsMap"),
|
||||
("read_only_space", 0x065d1): (244, "InternalClassWithStructElementsMap"),
|
||||
("read_only_space", 0x065f9): (222, "ExportedSubClass2Map"),
|
||||
("read_only_space", 0x06621): (255, "SortStateMap"),
|
||||
("read_only_space", 0x06649): (146, "AllocationSiteWithWeakNextMap"),
|
||||
("read_only_space", 0x06671): (146, "AllocationSiteWithoutWeakNextMap"),
|
||||
("read_only_space", 0x06699): (137, "LoadHandler1Map"),
|
||||
("read_only_space", 0x066c1): (137, "LoadHandler2Map"),
|
||||
("read_only_space", 0x066e9): (137, "LoadHandler3Map"),
|
||||
("read_only_space", 0x06711): (138, "StoreHandler0Map"),
|
||||
("read_only_space", 0x06739): (138, "StoreHandler1Map"),
|
||||
("read_only_space", 0x06761): (138, "StoreHandler2Map"),
|
||||
("read_only_space", 0x06789): (138, "StoreHandler3Map"),
|
||||
("map_space", 0x02119): (1057, "ExternalMap"),
|
||||
("map_space", 0x02141): (2114, "JSMessageObjectMap"),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user