LCOV - code coverage report
Current view: top level - src - isolate.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1450 1709 84.8 %
Date: 2019-03-21 Functions: 198 236 83.9 %

          Line data    Source code
       1             : // Copyright 2012 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/isolate.h"
       6             : 
       7             : #include <stdlib.h>
       8             : 
       9             : #include <atomic>
      10             : #include <fstream>  // NOLINT(readability/streams)
      11             : #include <memory>
      12             : #include <sstream>
      13             : #include <unordered_map>
      14             : 
      15             : #include "src/api-inl.h"
      16             : #include "src/assembler-inl.h"
      17             : #include "src/ast/ast-value-factory.h"
      18             : #include "src/ast/scopes.h"
      19             : #include "src/base/adapters.h"
      20             : #include "src/base/hashmap.h"
      21             : #include "src/base/platform/platform.h"
      22             : #include "src/base/sys-info.h"
      23             : #include "src/base/utils/random-number-generator.h"
      24             : #include "src/bootstrapper.h"
      25             : #include "src/builtins/builtins-promise.h"
      26             : #include "src/builtins/constants-table-builder.h"
      27             : #include "src/cancelable-task.h"
      28             : #include "src/compilation-cache.h"
      29             : #include "src/compilation-statistics.h"
      30             : #include "src/compiler-dispatcher/compiler-dispatcher.h"
      31             : #include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
      32             : #include "src/date.h"
      33             : #include "src/debug/debug-frames.h"
      34             : #include "src/debug/debug.h"
      35             : #include "src/deoptimizer.h"
      36             : #include "src/elements.h"
      37             : #include "src/frames-inl.h"
      38             : #include "src/hash-seed-inl.h"
      39             : #include "src/heap/heap-inl.h"
      40             : #include "src/heap/read-only-heap.h"
      41             : #include "src/ic/stub-cache.h"
      42             : #include "src/interpreter/interpreter.h"
      43             : #include "src/isolate-inl.h"
      44             : #include "src/libsampler/sampler.h"
      45             : #include "src/log.h"
      46             : #include "src/messages.h"
      47             : #include "src/microtask-queue.h"
      48             : #include "src/objects/frame-array-inl.h"
      49             : #include "src/objects/hash-table-inl.h"
      50             : #include "src/objects/js-array-inl.h"
      51             : #include "src/objects/js-generator-inl.h"
      52             : #include "src/objects/module-inl.h"
      53             : #include "src/objects/promise-inl.h"
      54             : #include "src/objects/slots.h"
      55             : #include "src/objects/smi.h"
      56             : #include "src/objects/stack-frame-info-inl.h"
      57             : #include "src/ostreams.h"
      58             : #include "src/profiler/heap-profiler.h"
      59             : #include "src/profiler/tracing-cpu-profiler.h"
      60             : #include "src/prototype.h"
      61             : #include "src/ptr-compr.h"
      62             : #include "src/regexp/regexp-stack.h"
      63             : #include "src/runtime-profiler.h"
      64             : #include "src/setup-isolate.h"
      65             : #include "src/simulator.h"
      66             : #include "src/snapshot/embedded-data.h"
      67             : #include "src/snapshot/embedded-file-writer.h"
      68             : #include "src/snapshot/read-only-deserializer.h"
      69             : #include "src/snapshot/startup-deserializer.h"
      70             : #include "src/string-builder-inl.h"
      71             : #include "src/string-stream.h"
      72             : #include "src/tracing/tracing-category-observer.h"
      73             : #include "src/trap-handler/trap-handler.h"
      74             : #include "src/unicode-cache.h"
      75             : #include "src/v8.h"
      76             : #include "src/v8threads.h"
      77             : #include "src/version.h"
      78             : #include "src/visitors.h"
      79             : #include "src/vm-state-inl.h"
      80             : #include "src/wasm/wasm-code-manager.h"
      81             : #include "src/wasm/wasm-engine.h"
      82             : #include "src/wasm/wasm-objects.h"
      83             : #include "src/zone/accounting-allocator.h"
      84             : #ifdef V8_INTL_SUPPORT
      85             : #include "unicode/uobject.h"
      86             : #endif  // V8_INTL_SUPPORT
      87             : 
      88             : extern "C" const uint8_t* v8_Default_embedded_blob_;
      89             : extern "C" uint32_t v8_Default_embedded_blob_size_;
      90             : 
      91             : namespace v8 {
      92             : namespace internal {
      93             : 
      94             : #ifdef DEBUG
      95             : #define TRACE_ISOLATE(tag)                                                  \
      96             :   do {                                                                      \
      97             :     if (FLAG_trace_isolates) {                                              \
      98             :       PrintF("Isolate %p (id %d)" #tag "\n", reinterpret_cast<void*>(this), \
      99             :              id());                                                         \
     100             :     }                                                                       \
     101             :   } while (false)
     102             : #else
     103             : #define TRACE_ISOLATE(tag)
     104             : #endif
     105             : 
     106       61534 : const uint8_t* DefaultEmbeddedBlob() { return v8_Default_embedded_blob_; }
     107       61534 : uint32_t DefaultEmbeddedBlobSize() { return v8_Default_embedded_blob_size_; }
     108             : 
     109             : #ifdef V8_MULTI_SNAPSHOTS
     110             : extern "C" const uint8_t* v8_Trusted_embedded_blob_;
     111             : extern "C" uint32_t v8_Trusted_embedded_blob_size_;
     112             : 
     113             : const uint8_t* TrustedEmbeddedBlob() { return v8_Trusted_embedded_blob_; }
     114             : uint32_t TrustedEmbeddedBlobSize() { return v8_Trusted_embedded_blob_size_; }
     115             : #endif
     116             : 
     117             : namespace {
     118             : // These variables provide access to the current embedded blob without requiring
     119             : // an isolate instance. This is needed e.g. by Code::InstructionStart, which may
     120             : // not have access to an isolate but still needs to access the embedded blob.
     121             : // The variables are initialized by each isolate in Init(). Writes and reads are
     122             : // relaxed since we can guarantee that the current thread has initialized these
     123             : // variables before accessing them. Different threads may race, but this is fine
     124             : // since they all attempt to set the same values of the blob pointer and size.
     125             : 
     126             : std::atomic<const uint8_t*> current_embedded_blob_(nullptr);
     127             : std::atomic<uint32_t> current_embedded_blob_size_(0);
     128             : 
     129             : // The various workflows around embedded snapshots are fairly complex. We need
     130             : // to support plain old snapshot builds, nosnap builds, and the requirements of
     131             : // subtly different serialization tests. There's two related knobs to twiddle:
     132             : //
     133             : // - The default embedded blob may be overridden by setting the sticky embedded
     134             : // blob. This is set automatically whenever we create a new embedded blob.
     135             : //
     136             : // - Lifecycle management can be either manual or set to refcounting.
     137             : //
     138             : // A few situations to demonstrate their use:
     139             : //
     140             : // - A plain old snapshot build neither overrides the default blob nor
     141             : // refcounts.
     142             : //
     143             : // - mksnapshot sets the sticky blob and manually frees the embedded
     144             : // blob once done.
     145             : //
     146             : // - Most serializer tests do the same.
     147             : //
     148             : // - Nosnapshot builds set the sticky blob and enable refcounting.
     149             : 
     150             : // This mutex protects access to the following variables:
     151             : // - sticky_embedded_blob_
     152             : // - sticky_embedded_blob_size_
     153             : // - enable_embedded_blob_refcounting_
     154             : // - current_embedded_blob_refs_
     155             : base::LazyMutex current_embedded_blob_refcount_mutex_ = LAZY_MUTEX_INITIALIZER;
     156             : 
     157             : const uint8_t* sticky_embedded_blob_ = nullptr;
     158             : uint32_t sticky_embedded_blob_size_ = 0;
     159             : 
     160             : bool enable_embedded_blob_refcounting_ = true;
     161             : int current_embedded_blob_refs_ = 0;
     162             : 
     163      124571 : const uint8_t* StickyEmbeddedBlob() { return sticky_embedded_blob_; }
     164          55 : uint32_t StickyEmbeddedBlobSize() { return sticky_embedded_blob_size_; }
     165             : 
     166             : void SetStickyEmbeddedBlob(const uint8_t* blob, uint32_t blob_size) {
     167          56 :   sticky_embedded_blob_ = blob;
     168          56 :   sticky_embedded_blob_size_ = blob_size;
     169             : }
     170             : 
     171             : }  // namespace
     172             : 
     173        1356 : void DisableEmbeddedBlobRefcounting() {
     174             :   base::MutexGuard guard(current_embedded_blob_refcount_mutex_.Pointer());
     175        1356 :   enable_embedded_blob_refcounting_ = false;
     176        1356 : }
     177             : 
     178        1351 : void FreeCurrentEmbeddedBlob() {
     179        1351 :   CHECK(!enable_embedded_blob_refcounting_);
     180             :   base::MutexGuard guard(current_embedded_blob_refcount_mutex_.Pointer());
     181             : 
     182        1351 :   if (StickyEmbeddedBlob() == nullptr) return;
     183             : 
     184          56 :   CHECK_EQ(StickyEmbeddedBlob(), Isolate::CurrentEmbeddedBlob());
     185             : 
     186             :   InstructionStream::FreeOffHeapInstructionStream(
     187             :       const_cast<uint8_t*>(Isolate::CurrentEmbeddedBlob()),
     188          56 :       Isolate::CurrentEmbeddedBlobSize());
     189             : 
     190             :   current_embedded_blob_.store(nullptr, std::memory_order_relaxed);
     191             :   current_embedded_blob_size_.store(0, std::memory_order_relaxed);
     192          56 :   sticky_embedded_blob_ = nullptr;
     193          56 :   sticky_embedded_blob_size_ = 0;
     194             : }
     195             : 
     196             : // static
     197           0 : bool Isolate::CurrentEmbeddedBlobIsBinaryEmbedded() {
     198             :   // In some situations, we must be able to rely on the embedded blob being
     199             :   // immortal immovable. This is the case if the blob is binary-embedded.
     200             :   // See blob lifecycle controls above for descriptions of when the current
     201             :   // embedded blob may change (e.g. in tests or mksnapshot). If the blob is
     202             :   // binary-embedded, it is immortal immovable.
     203             :   const uint8_t* blob =
     204             :       current_embedded_blob_.load(std::memory_order::memory_order_relaxed);
     205           0 :   if (blob == nullptr) return false;
     206             : #ifdef V8_MULTI_SNAPSHOTS
     207             :   if (blob == TrustedEmbeddedBlob()) return true;
     208             : #endif
     209           0 :   return blob == DefaultEmbeddedBlob();
     210             : }
     211             : 
     212       61589 : void Isolate::SetEmbeddedBlob(const uint8_t* blob, uint32_t blob_size) {
     213       61589 :   CHECK_NOT_NULL(blob);
     214             : 
     215       61589 :   embedded_blob_ = blob;
     216       61589 :   embedded_blob_size_ = blob_size;
     217             :   current_embedded_blob_.store(blob, std::memory_order_relaxed);
     218             :   current_embedded_blob_size_.store(blob_size, std::memory_order_relaxed);
     219             : 
     220             : #ifdef DEBUG
     221             :   // Verify that the contents of the embedded blob are unchanged from
     222             :   // serialization-time, just to ensure the compiler isn't messing with us.
     223             :   EmbeddedData d = EmbeddedData::FromBlob();
     224             :   if (d.EmbeddedBlobHash() != d.CreateEmbeddedBlobHash()) {
     225             :     FATAL(
     226             :         "Embedded blob checksum verification failed. This indicates that the "
     227             :         "embedded blob has been modified since compilation time. A common "
     228             :         "cause is a debugging breakpoint set within builtin code.");
     229             :   }
     230             : #endif  // DEBUG
     231       61589 : }
     232             : 
     233           0 : void Isolate::ClearEmbeddedBlob() {
     234           0 :   CHECK(enable_embedded_blob_refcounting_);
     235           0 :   CHECK_EQ(embedded_blob_, CurrentEmbeddedBlob());
     236           0 :   CHECK_EQ(embedded_blob_, StickyEmbeddedBlob());
     237             : 
     238           0 :   embedded_blob_ = nullptr;
     239           0 :   embedded_blob_size_ = 0;
     240             :   current_embedded_blob_.store(nullptr, std::memory_order_relaxed);
     241             :   current_embedded_blob_size_.store(0, std::memory_order_relaxed);
     242           0 :   sticky_embedded_blob_ = nullptr;
     243           0 :   sticky_embedded_blob_size_ = 0;
     244           0 : }
     245             : 
     246   197576147 : const uint8_t* Isolate::embedded_blob() const { return embedded_blob_; }
     247    92658618 : uint32_t Isolate::embedded_blob_size() const { return embedded_blob_size_; }
     248             : 
     249             : // static
     250   408265126 : const uint8_t* Isolate::CurrentEmbeddedBlob() {
     251   408265126 :   return current_embedded_blob_.load(std::memory_order::memory_order_relaxed);
     252             : }
     253             : 
     254             : // static
     255   255800505 : uint32_t Isolate::CurrentEmbeddedBlobSize() {
     256             :   return current_embedded_blob_size_.load(
     257   255800505 :       std::memory_order::memory_order_relaxed);
     258             : }
     259             : 
     260          56 : size_t Isolate::HashIsolateForEmbeddedBlob() {
     261             :   DCHECK(builtins_.is_initialized());
     262             :   DCHECK(FLAG_embedded_builtins);
     263             :   DCHECK(Builtins::AllBuiltinsAreIsolateIndependent());
     264             : 
     265             :   DisallowHeapAllocation no_gc;
     266             : 
     267             :   static constexpr size_t kSeed = 0;
     268             :   size_t hash = kSeed;
     269             : 
     270             :   // Hash data sections of builtin code objects.
     271      169736 :   for (int i = 0; i < Builtins::builtin_count; i++) {
     272       84840 :     Code code = heap_.builtin(i);
     273             : 
     274             :     DCHECK(Internals::HasHeapObjectTag(code.ptr()));
     275             :     uint8_t* const code_ptr =
     276       84840 :         reinterpret_cast<uint8_t*>(code.ptr() - kHeapObjectTag);
     277             : 
     278             :     // These static asserts ensure we don't miss relevant fields. We don't hash
     279             :     // instruction size and flags since they change when creating the off-heap
     280             :     // trampolines. Other data fields must remain the same.
     281             :     STATIC_ASSERT(Code::kInstructionSizeOffset == Code::kDataStart);
     282             :     STATIC_ASSERT(Code::kFlagsOffset == Code::kInstructionSizeOffsetEnd + 1);
     283             :     STATIC_ASSERT(Code::kSafepointTableOffsetOffset ==
     284             :                   Code::kFlagsOffsetEnd + 1);
     285             :     static constexpr int kStartOffset = Code::kSafepointTableOffsetOffset;
     286             : 
     287     2799720 :     for (int j = kStartOffset; j < Code::kUnalignedHeaderSize; j++) {
     288     1357440 :       hash = base::hash_combine(hash, size_t{code_ptr[j]});
     289             :     }
     290             :   }
     291             : 
     292             :   // The builtins constants table is also tightly tied to embedded builtins.
     293          56 :   hash = base::hash_combine(
     294         112 :       hash, static_cast<size_t>(heap_.builtins_constants_table()->length()));
     295             : 
     296          56 :   return hash;
     297             : }
     298             : 
     299             : 
     300             : base::Thread::LocalStorageKey Isolate::isolate_key_;
     301             : base::Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
     302             : #if DEBUG
     303             : std::atomic<bool> Isolate::isolate_key_created_{false};
     304             : #endif
     305             : 
     306             : namespace {
     307             : // A global counter for all generated Isolates, might overflow.
     308             : std::atomic<int> isolate_counter{0};
     309             : }  // namespace
     310             : 
     311             : Isolate::PerIsolateThreadData*
     312      325554 :     Isolate::FindOrAllocatePerThreadDataForThisThread() {
     313             :   ThreadId thread_id = ThreadId::Current();
     314             :   PerIsolateThreadData* per_thread = nullptr;
     315             :   {
     316      325549 :     base::MutexGuard lock_guard(&thread_data_table_mutex_);
     317             :     per_thread = thread_data_table_.Lookup(thread_id);
     318      325562 :     if (per_thread == nullptr) {
     319       67069 :       per_thread = new PerIsolateThreadData(this, thread_id);
     320       67069 :       thread_data_table_.Insert(per_thread);
     321             :     }
     322             :     DCHECK(thread_data_table_.Lookup(thread_id) == per_thread);
     323             :   }
     324      325567 :   return per_thread;
     325             : }
     326             : 
     327             : 
     328        1500 : void Isolate::DiscardPerThreadDataForThisThread() {
     329        1500 :   ThreadId thread_id = ThreadId::TryGetCurrent();
     330        1500 :   if (thread_id.IsValid()) {
     331             :     DCHECK_NE(thread_manager_->mutex_owner_.load(std::memory_order_relaxed),
     332             :               thread_id);
     333        1000 :     base::MutexGuard lock_guard(&thread_data_table_mutex_);
     334             :     PerIsolateThreadData* per_thread = thread_data_table_.Lookup(thread_id);
     335        1000 :     if (per_thread) {
     336             :       DCHECK(!per_thread->thread_state_);
     337             :       thread_data_table_.Remove(per_thread);
     338             :     }
     339             :   }
     340        1500 : }
     341             : 
     342             : 
     343       40303 : Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() {
     344       40303 :   ThreadId thread_id = ThreadId::Current();
     345       40303 :   return FindPerThreadDataForThread(thread_id);
     346             : }
     347             : 
     348             : 
     349       40303 : Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThread(
     350             :     ThreadId thread_id) {
     351             :   PerIsolateThreadData* per_thread = nullptr;
     352             :   {
     353       40303 :     base::MutexGuard lock_guard(&thread_data_table_mutex_);
     354             :     per_thread = thread_data_table_.Lookup(thread_id);
     355             :   }
     356       40303 :   return per_thread;
     357             : }
     358             : 
     359             : 
     360       60098 : void Isolate::InitializeOncePerProcess() {
     361       60098 :   isolate_key_ = base::Thread::CreateThreadLocalKey();
     362             : #if DEBUG
     363             :   bool expected = false;
     364             :   DCHECK_EQ(true, isolate_key_created_.compare_exchange_strong(
     365             :                       expected, true, std::memory_order_relaxed));
     366             : #endif
     367       60098 :   per_isolate_thread_data_key_ = base::Thread::CreateThreadLocalKey();
     368       60098 : }
     369             : 
     370      789828 : Address Isolate::get_address_from_id(IsolateAddressId id) {
     371      789828 :   return isolate_addresses_[id];
     372             : }
     373             : 
     374        5546 : char* Isolate::Iterate(RootVisitor* v, char* thread_storage) {
     375             :   ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage);
     376        5546 :   Iterate(v, thread);
     377        5546 :   return thread_storage + sizeof(ThreadLocalTop);
     378             : }
     379             : 
     380             : 
     381       84083 : void Isolate::IterateThread(ThreadVisitor* v, char* t) {
     382             :   ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t);
     383       84083 :   v->VisitThread(this, thread);
     384       84083 : }
     385             : 
     386      282434 : void Isolate::Iterate(RootVisitor* v, ThreadLocalTop* thread) {
     387             :   // Visit the roots from the top for a given thread.
     388      282434 :   v->VisitRootPointer(Root::kTop, nullptr,
     389      564868 :                       FullObjectSlot(&thread->pending_exception_));
     390      282434 :   v->VisitRootPointer(Root::kTop, nullptr,
     391      564868 :                       FullObjectSlot(&thread->pending_message_obj_));
     392      564868 :   v->VisitRootPointer(Root::kTop, nullptr, FullObjectSlot(&thread->context_));
     393      282434 :   v->VisitRootPointer(Root::kTop, nullptr,
     394      564868 :                       FullObjectSlot(&thread->scheduled_exception_));
     395             : 
     396      450002 :   for (v8::TryCatch* block = thread->try_catch_handler_; block != nullptr;
     397             :        block = block->next_) {
     398             :     // TODO(3770): Make TryCatch::exception_ an Address (and message_obj_ too).
     399      335136 :     v->VisitRootPointer(
     400             :         Root::kTop, nullptr,
     401      335136 :         FullObjectSlot(reinterpret_cast<Address>(&(block->exception_))));
     402      335136 :     v->VisitRootPointer(
     403             :         Root::kTop, nullptr,
     404      335136 :         FullObjectSlot(reinterpret_cast<Address>(&(block->message_obj_))));
     405             :   }
     406             : 
     407             :   // Iterate over pointers on native execution stack.
     408     3464368 :   for (StackFrameIterator it(this, thread); !it.done(); it.Advance()) {
     409     3181934 :     it.frame()->Iterate(v);
     410             :   }
     411      282434 : }
     412             : 
     413      276888 : void Isolate::Iterate(RootVisitor* v) {
     414             :   ThreadLocalTop* current_t = thread_local_top();
     415      276888 :   Iterate(v, current_t);
     416      276888 : }
     417             : 
     418      276888 : void Isolate::IterateDeferredHandles(RootVisitor* visitor) {
     419      280001 :   for (DeferredHandles* deferred = deferred_handles_head_; deferred != nullptr;
     420             :        deferred = deferred->next_) {
     421        3113 :     deferred->Iterate(visitor);
     422             :   }
     423      276888 : }
     424             : 
     425             : 
     426             : #ifdef DEBUG
     427             : bool Isolate::IsDeferredHandle(Address* handle) {
     428             :   // Comparing unrelated pointers (not from the same array) is undefined
     429             :   // behavior, so cast to Address before making arbitrary comparisons.
     430             :   Address handle_as_address = reinterpret_cast<Address>(handle);
     431             :   // Each DeferredHandles instance keeps the handles to one job in the
     432             :   // concurrent recompilation queue, containing a list of blocks.  Each block
     433             :   // contains kHandleBlockSize handles except for the first block, which may
     434             :   // not be fully filled.
     435             :   // We iterate through all the blocks to see whether the argument handle
     436             :   // belongs to one of the blocks.  If so, it is deferred.
     437             :   for (DeferredHandles* deferred = deferred_handles_head_; deferred != nullptr;
     438             :        deferred = deferred->next_) {
     439             :     std::vector<Address*>* blocks = &deferred->blocks_;
     440             :     for (size_t i = 0; i < blocks->size(); i++) {
     441             :       Address* block_limit = (i == 0) ? deferred->first_block_limit_
     442             :                                       : blocks->at(i) + kHandleBlockSize;
     443             :       if (reinterpret_cast<Address>(blocks->at(i)) <= handle_as_address &&
     444             :           handle_as_address < reinterpret_cast<Address>(block_limit)) {
     445             :         return true;
     446             :       }
     447             :     }
     448             :   }
     449             :   return false;
     450             : }
     451             : #endif  // DEBUG
     452             : 
     453             : 
     454    20992758 : void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) {
     455    20992758 :   thread_local_top()->try_catch_handler_ = that;
     456    20992758 : }
     457             : 
     458             : 
     459    20992762 : void Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) {
     460             :   DCHECK(thread_local_top()->try_catch_handler_ == that);
     461    20992762 :   thread_local_top()->try_catch_handler_ = that->next_;
     462    20992762 : }
     463             : 
     464             : 
     465           0 : Handle<String> Isolate::StackTraceString() {
     466           0 :   if (stack_trace_nesting_level_ == 0) {
     467           0 :     stack_trace_nesting_level_++;
     468             :     HeapStringAllocator allocator;
     469           0 :     StringStream::ClearMentionedObjectCache(this);
     470             :     StringStream accumulator(&allocator);
     471           0 :     incomplete_message_ = &accumulator;
     472           0 :     PrintStack(&accumulator);
     473           0 :     Handle<String> stack_trace = accumulator.ToString(this);
     474           0 :     incomplete_message_ = nullptr;
     475           0 :     stack_trace_nesting_level_ = 0;
     476           0 :     return stack_trace;
     477           0 :   } else if (stack_trace_nesting_level_ == 1) {
     478           0 :     stack_trace_nesting_level_++;
     479             :     base::OS::PrintError(
     480           0 :       "\n\nAttempt to print stack while printing stack (double fault)\n");
     481             :     base::OS::PrintError(
     482           0 :       "If you are lucky you may find a partial stack dump on stdout.\n\n");
     483           0 :     incomplete_message_->OutputToStdOut();
     484             :     return factory()->empty_string();
     485             :   } else {
     486           0 :     base::OS::Abort();
     487             :     // Unreachable
     488             :     return factory()->empty_string();
     489             :   }
     490             : }
     491             : 
     492           0 : void Isolate::PushStackTraceAndDie(void* ptr1, void* ptr2, void* ptr3,
     493             :                                    void* ptr4) {
     494           0 :   StackTraceFailureMessage message(this, ptr1, ptr2, ptr3, ptr4);
     495           0 :   message.Print();
     496           0 :   base::OS::Abort();
     497             : }
     498             : 
     499           0 : void StackTraceFailureMessage::Print() volatile {
     500             :   // Print the details of this failure message object, including its own address
     501             :   // to force stack allocation.
     502           0 :   base::OS::PrintError(
     503             :       "Stacktrace:\n   ptr1=%p\n    ptr2=%p\n    ptr3=%p\n    ptr4=%p\n    "
     504             :       "failure_message_object=%p\n%s",
     505           0 :       ptr1_, ptr2_, ptr3_, ptr4_, this, &js_stack_trace_[0]);
     506           0 : }
     507             : 
     508           0 : StackTraceFailureMessage::StackTraceFailureMessage(Isolate* isolate, void* ptr1,
     509             :                                                    void* ptr2, void* ptr3,
     510           0 :                                                    void* ptr4) {
     511           0 :   isolate_ = isolate;
     512           0 :   ptr1_ = ptr1;
     513           0 :   ptr2_ = ptr2;
     514           0 :   ptr3_ = ptr3;
     515           0 :   ptr4_ = ptr4;
     516             :   // Write a stracktrace into the {js_stack_trace_} buffer.
     517             :   const size_t buffer_length = arraysize(js_stack_trace_);
     518           0 :   memset(&js_stack_trace_, 0, buffer_length);
     519             :   FixedStringAllocator fixed(&js_stack_trace_[0], buffer_length - 1);
     520             :   StringStream accumulator(&fixed, StringStream::kPrintObjectConcise);
     521           0 :   isolate->PrintStack(&accumulator, Isolate::kPrintStackVerbose);
     522             :   // Keeping a reference to the last code objects to increase likelyhood that
     523             :   // they get included in the minidump.
     524             :   const size_t code_objects_length = arraysize(code_objects_);
     525             :   size_t i = 0;
     526           0 :   StackFrameIterator it(isolate);
     527           0 :   for (; !it.done() && i < code_objects_length; it.Advance()) {
     528           0 :     if (it.frame()->type() == StackFrame::INTERNAL) continue;
     529           0 :     code_objects_[i++] =
     530           0 :         reinterpret_cast<void*>(it.frame()->unchecked_code().ptr());
     531             :   }
     532           0 : }
     533             : 
     534             : namespace {
     535             : 
     536             : class StackFrameCacheHelper : public AllStatic {
     537             :  public:
     538       61728 :   static MaybeHandle<StackTraceFrame> LookupCachedFrame(
     539             :       Isolate* isolate, Handle<AbstractCode> code, int code_offset) {
     540       61728 :     if (FLAG_optimize_for_size) return MaybeHandle<StackTraceFrame>();
     541             : 
     542      123456 :     const auto maybe_cache = handle(code->stack_frame_cache(), isolate);
     543       61728 :     if (!maybe_cache->IsSimpleNumberDictionary())
     544        8199 :       return MaybeHandle<StackTraceFrame>();
     545             : 
     546             :     const auto cache = Handle<SimpleNumberDictionary>::cast(maybe_cache);
     547      107058 :     const int entry = cache->FindEntry(isolate, code_offset);
     548       53529 :     if (entry != NumberDictionary::kNotFound) {
     549      102302 :       return handle(StackTraceFrame::cast(cache->ValueAt(entry)), isolate);
     550             :     }
     551        2378 :     return MaybeHandle<StackTraceFrame>();
     552             :   }
     553             : 
     554       10577 :   static void CacheFrameAndUpdateCache(Isolate* isolate,
     555             :                                        Handle<AbstractCode> code,
     556             :                                        int code_offset,
     557             :                                        Handle<StackTraceFrame> frame) {
     558       10577 :     if (FLAG_optimize_for_size) return;
     559             : 
     560       21154 :     const auto maybe_cache = handle(code->stack_frame_cache(), isolate);
     561             :     const auto cache = maybe_cache->IsSimpleNumberDictionary()
     562             :                            ? Handle<SimpleNumberDictionary>::cast(maybe_cache)
     563       10577 :                            : SimpleNumberDictionary::New(isolate, 1);
     564             :     Handle<SimpleNumberDictionary> new_cache =
     565       10577 :         SimpleNumberDictionary::Set(isolate, cache, code_offset, frame);
     566       20805 :     if (*new_cache != *cache || !maybe_cache->IsSimpleNumberDictionary()) {
     567        8548 :       AbstractCode::SetStackFrameCache(code, new_cache);
     568             :     }
     569             :   }
     570             : };
     571             : 
     572             : }  // anonymous namespace
     573             : 
     574             : class FrameArrayBuilder {
     575             :  public:
     576             :   enum FrameFilterMode { ALL, CURRENT_SECURITY_CONTEXT };
     577             : 
     578     1311087 :   FrameArrayBuilder(Isolate* isolate, FrameSkipMode mode, int limit,
     579             :                     Handle<Object> caller, FrameFilterMode filter_mode)
     580             :       : isolate_(isolate),
     581             :         mode_(mode),
     582             :         limit_(limit),
     583             :         caller_(caller),
     584     1311087 :         check_security_context_(filter_mode == CURRENT_SECURITY_CONTEXT) {
     585     1311087 :     switch (mode_) {
     586             :       case SKIP_FIRST:
     587             :         skip_next_frame_ = true;
     588             :         break;
     589             :       case SKIP_UNTIL_SEEN:
     590             :         DCHECK(caller_->IsJSFunction());
     591             :         skip_next_frame_ = true;
     592             :         break;
     593             :       case SKIP_NONE:
     594     1288244 :         skip_next_frame_ = false;
     595     1288244 :         break;
     596             :     }
     597             : 
     598     1311087 :     elements_ = isolate->factory()->NewFrameArray(Min(limit, 10));
     599     1311087 :   }
     600             : 
     601        1355 :   void AppendAsyncFrame(Handle<JSGeneratorObject> generator_object) {
     602        1355 :     if (full()) return;
     603        1355 :     Handle<JSFunction> function(generator_object->function(), isolate_);
     604        1355 :     if (!IsVisibleInStackTrace(function)) return;
     605             :     int flags = FrameArray::kIsAsync;
     606        1355 :     if (IsStrictFrame(function)) flags |= FrameArray::kIsStrict;
     607             : 
     608        1355 :     Handle<Object> receiver(generator_object->receiver(), isolate_);
     609             :     Handle<AbstractCode> code(
     610        4065 :         AbstractCode::cast(function->shared()->GetBytecodeArray()), isolate_);
     611             :     int offset = Smi::ToInt(generator_object->input_or_debug_pos());
     612             :     // The stored bytecode offset is relative to a different base than what
     613             :     // is used in the source position table, hence the subtraction.
     614        1355 :     offset -= BytecodeArray::kHeaderSize - kHeapObjectTag;
     615             : 
     616        1355 :     Handle<FixedArray> parameters = isolate_->factory()->empty_fixed_array();
     617        1355 :     if (V8_UNLIKELY(FLAG_detailed_error_stack_trace)) {
     618           0 :       int param_count = function->shared()->internal_formal_parameter_count();
     619           0 :       parameters = isolate_->factory()->NewFixedArray(param_count);
     620           0 :       for (int i = 0; i < param_count; i++) {
     621           0 :         parameters->set(i,
     622           0 :                         generator_object->parameters_and_registers()->get(i));
     623             :       }
     624             :     }
     625             : 
     626             :     elements_ = FrameArray::AppendJSFrame(elements_, receiver, function, code,
     627        1355 :                                           offset, flags, parameters);
     628             :   }
     629             : 
     630         108 :   void AppendPromiseAllFrame(Handle<Context> context, int offset) {
     631         108 :     if (full()) return;
     632             :     int flags = FrameArray::kIsAsync | FrameArray::kIsPromiseAll;
     633             : 
     634         324 :     Handle<Context> native_context(context->native_context(), isolate_);
     635         324 :     Handle<JSFunction> function(native_context->promise_all(), isolate_);
     636         108 :     if (!IsVisibleInStackTrace(function)) return;
     637             : 
     638         324 :     Handle<Object> receiver(native_context->promise_function(), isolate_);
     639         108 :     Handle<AbstractCode> code(AbstractCode::cast(function->code()), isolate_);
     640             : 
     641             :     // TODO(mmarchini) save Promises list from Promise.all()
     642         216 :     Handle<FixedArray> parameters = isolate_->factory()->empty_fixed_array();
     643             : 
     644             :     elements_ = FrameArray::AppendJSFrame(elements_, receiver, function, code,
     645         108 :                                           offset, flags, parameters);
     646             :   }
     647             : 
     648     4979744 :   void AppendJavaScriptFrame(
     649             :       FrameSummary::JavaScriptFrameSummary const& summary) {
     650             :     // Filter out internal frames that we do not want to show.
     651     4987752 :     if (!IsVisibleInStackTrace(summary.function())) return;
     652             : 
     653     4971736 :     Handle<AbstractCode> abstract_code = summary.abstract_code();
     654             :     const int offset = summary.code_offset();
     655             : 
     656             :     const bool is_constructor = summary.is_constructor();
     657             : 
     658             :     int flags = 0;
     659     4971736 :     Handle<JSFunction> function = summary.function();
     660     4971736 :     if (IsStrictFrame(function)) flags |= FrameArray::kIsStrict;
     661     4971736 :     if (is_constructor) flags |= FrameArray::kIsConstructor;
     662             : 
     663     9943472 :     Handle<FixedArray> parameters = isolate_->factory()->empty_fixed_array();
     664     4971736 :     if (V8_UNLIKELY(FLAG_detailed_error_stack_trace))
     665          45 :       parameters = summary.parameters();
     666             : 
     667             :     elements_ = FrameArray::AppendJSFrame(
     668             :         elements_, TheHoleToUndefined(isolate_, summary.receiver()), function,
     669     4971736 :         abstract_code, offset, flags, parameters);
     670             :   }
     671             : 
     672      155191 :   void AppendWasmCompiledFrame(
     673             :       FrameSummary::WasmCompiledFrameSummary const& summary) {
     674      155191 :     if (summary.code()->kind() != wasm::WasmCode::kFunction) return;
     675             :     Handle<WasmInstanceObject> instance = summary.wasm_instance();
     676             :     int flags = 0;
     677      310382 :     if (instance->module_object()->is_asm_js()) {
     678             :       flags |= FrameArray::kIsAsmJsWasmFrame;
     679         400 :       if (summary.at_to_number_conversion()) {
     680             :         flags |= FrameArray::kAsmJsAtNumberConversion;
     681             :       }
     682             :     } else {
     683             :       flags |= FrameArray::kIsWasmFrame;
     684             :     }
     685             : 
     686             :     elements_ = FrameArray::AppendWasmFrame(
     687      155191 :         elements_, instance, summary.function_index(), summary.code(),
     688      155191 :         summary.code_offset(), flags);
     689             :   }
     690             : 
     691        1644 :   void AppendWasmInterpretedFrame(
     692             :       FrameSummary::WasmInterpretedFrameSummary const& summary) {
     693        1644 :     Handle<WasmInstanceObject> instance = summary.wasm_instance();
     694             :     int flags = FrameArray::kIsWasmInterpretedFrame;
     695             :     DCHECK(!instance->module_object()->is_asm_js());
     696             :     elements_ = FrameArray::AppendWasmFrame(elements_, instance,
     697             :                                             summary.function_index(), {},
     698        1644 :                                             summary.byte_offset(), flags);
     699        1644 :   }
     700             : 
     701       61056 :   void AppendBuiltinExitFrame(BuiltinExitFrame* exit_frame) {
     702      122112 :     Handle<JSFunction> function = handle(exit_frame->function(), isolate_);
     703             : 
     704             :     // Filter out internal frames that we do not want to show.
     705       91302 :     if (!IsVisibleInStackTrace(function)) return;
     706             : 
     707       30810 :     Handle<Object> receiver(exit_frame->receiver(), isolate_);
     708       30810 :     Handle<Code> code(exit_frame->LookupCode(), isolate_);
     709             :     const int offset =
     710       92430 :         static_cast<int>(exit_frame->pc() - code->InstructionStart());
     711             : 
     712             :     int flags = 0;
     713       30810 :     if (IsStrictFrame(function)) flags |= FrameArray::kIsStrict;
     714       30810 :     if (exit_frame->IsConstructor()) flags |= FrameArray::kIsConstructor;
     715             : 
     716       30810 :     Handle<FixedArray> parameters = isolate_->factory()->empty_fixed_array();
     717       30810 :     if (V8_UNLIKELY(FLAG_detailed_error_stack_trace)) {
     718           5 :       int param_count = exit_frame->ComputeParametersCount();
     719           5 :       parameters = isolate_->factory()->NewFixedArray(param_count);
     720          25 :       for (int i = 0; i < param_count; i++) {
     721          20 :         parameters->set(i, exit_frame->GetParameter(i));
     722             :       }
     723             :     }
     724             : 
     725             :     elements_ = FrameArray::AppendJSFrame(elements_, receiver, function,
     726             :                                           Handle<AbstractCode>::cast(code),
     727       30810 :                                           offset, flags, parameters);
     728             :   }
     729             : 
     730    14677979 :   bool full() { return elements_->FrameCount() >= limit_; }
     731             : 
     732             :   Handle<FrameArray> GetElements() {
     733     2492490 :     elements_->ShrinkToFit(isolate_);
     734     1246245 :     return elements_;
     735             :   }
     736             : 
     737             :   // Creates a StackTraceFrame object for each frame in the FrameArray.
     738       64842 :   Handle<FixedArray> GetElementsAsStackTraceFrameArray() {
     739      129684 :     elements_->ShrinkToFit(isolate_);
     740             :     const int frame_count = elements_->FrameCount();
     741             :     Handle<FixedArray> stack_trace =
     742       64842 :         isolate_->factory()->NewFixedArray(frame_count);
     743             : 
     744      189186 :     for (int i = 0; i < frame_count; ++i) {
     745             :       // Caching stack frames only happens for non-Wasm frames.
     746       62172 :       if (!elements_->IsAnyWasmFrame(i)) {
     747             :         MaybeHandle<StackTraceFrame> maybe_frame =
     748             :             StackFrameCacheHelper::LookupCachedFrame(
     749             :                 isolate_, handle(elements_->Code(i), isolate_),
     750      246912 :                 Smi::ToInt(elements_->Offset(i)));
     751       61728 :         if (!maybe_frame.is_null()) {
     752             :           Handle<StackTraceFrame> frame = maybe_frame.ToHandleChecked();
     753      102302 :           stack_trace->set(i, *frame);
     754             :           continue;
     755             :         }
     756             :       }
     757             : 
     758             :       Handle<StackTraceFrame> frame =
     759       11021 :           isolate_->factory()->NewStackTraceFrame(elements_, i);
     760       22042 :       stack_trace->set(i, *frame);
     761             : 
     762       11021 :       if (!elements_->IsAnyWasmFrame(i)) {
     763       42308 :         StackFrameCacheHelper::CacheFrameAndUpdateCache(
     764             :             isolate_, handle(elements_->Code(i), isolate_),
     765       31731 :             Smi::ToInt(elements_->Offset(i)), frame);
     766             :       }
     767             :     }
     768       64842 :     return stack_trace;
     769             :   }
     770             : 
     771             :  private:
     772             :   // Poison stack frames below the first strict mode frame.
     773             :   // The stack trace API should not expose receivers and function
     774             :   // objects on frames deeper than the top-most one with a strict mode
     775             :   // function.
     776     5003901 :   bool IsStrictFrame(Handle<JSFunction> function) {
     777     5003901 :     if (!encountered_strict_function_) {
     778             :       encountered_strict_function_ =
     779     3700845 :           is_strict(function->shared()->language_mode());
     780             :     }
     781     5003901 :     return encountered_strict_function_;
     782             :   }
     783             : 
     784             :   // Determines whether the given stack frame should be displayed in a stack
     785             :   // trace.
     786     5042263 :   bool IsVisibleInStackTrace(Handle<JSFunction> function) {
     787    10048636 :     return ShouldIncludeFrame(function) && IsNotHidden(function) &&
     788    10048636 :            IsInSameSecurityContext(function);
     789             :   }
     790             : 
     791             :   // This mechanism excludes a number of uninteresting frames from the stack
     792             :   // trace. This can be be the first frame (which will be a builtin-exit frame
     793             :   // for the error constructor builtin) or every frame until encountering a
     794             :   // user-specified function.
     795     5042263 :   bool ShouldIncludeFrame(Handle<JSFunction> function) {
     796     5042263 :     switch (mode_) {
     797             :       case SKIP_NONE:
     798             :         return true;
     799             :       case SKIP_FIRST:
     800        2714 :         if (!skip_next_frame_) return true;
     801         590 :         skip_next_frame_ = false;
     802         590 :         return false;
     803             :       case SKIP_UNTIL_SEEN:
     804      166644 :         if (skip_next_frame_ && (*function == *caller_)) {
     805       21992 :           skip_next_frame_ = false;
     806       21992 :           return false;
     807             :         }
     808      119204 :         return !skip_next_frame_;
     809             :     }
     810           0 :     UNREACHABLE();
     811             :   }
     812             : 
     813     5016225 :   bool IsNotHidden(Handle<JSFunction> function) {
     814             :     // Functions defined not in user scripts are not visible unless directly
     815             :     // exposed, in which case the native flag is set.
     816             :     // The --builtins-in-stack-traces command line flag allows including
     817             :     // internal call sites in the stack trace for debugging purposes.
     818    15048531 :     if (!FLAG_builtins_in_stack_traces &&
     819    10032306 :         !function->shared()->IsUserJavaScript()) {
     820             :       return function->shared()->native();
     821             :     }
     822             :     return true;
     823             :   }
     824             : 
     825     5006373 :   bool IsInSameSecurityContext(Handle<JSFunction> function) {
     826     5006373 :     if (!check_security_context_) return true;
     827     9891022 :     return isolate_->context()->HasSameSecurityTokenAs(function->context());
     828             :   }
     829             : 
     830             :   // TODO(jgruber): Fix all cases in which frames give us a hole value (e.g. the
     831             :   // receiver in RegExp constructor frames.
     832             :   Handle<Object> TheHoleToUndefined(Isolate* isolate, Handle<Object> in) {
     833             :     return (in->IsTheHole(isolate))
     834             :                ? Handle<Object>::cast(isolate->factory()->undefined_value())
     835     4971736 :                : in;
     836             :   }
     837             : 
     838             :   Isolate* isolate_;
     839             :   const FrameSkipMode mode_;
     840             :   int limit_;
     841             :   const Handle<Object> caller_;
     842             :   bool skip_next_frame_ = true;
     843             :   bool encountered_strict_function_ = false;
     844             :   const bool check_security_context_;
     845             :   Handle<FrameArray> elements_;
     846             : };
     847             : 
     848     1253730 : bool GetStackTraceLimit(Isolate* isolate, int* result) {
     849     1253730 :   Handle<JSObject> error = isolate->error_function();
     850             : 
     851             :   Handle<String> key = isolate->factory()->stackTraceLimit_string();
     852     1253730 :   Handle<Object> stack_trace_limit = JSReceiver::GetDataProperty(error, key);
     853     1253730 :   if (!stack_trace_limit->IsNumber()) return false;
     854             : 
     855             :   // Ensure that limit is not negative.
     856     1246245 :   *result = Max(FastD2IChecked(stack_trace_limit->Number()), 0);
     857             : 
     858     1246245 :   if (*result != FLAG_stack_trace_limit) {
     859          54 :     isolate->CountUsage(v8::Isolate::kErrorStackTraceLimit);
     860             :   }
     861             : 
     862             :   return true;
     863             : }
     864             : 
     865      280463 : bool NoExtension(const v8::FunctionCallbackInfo<v8::Value>&) { return false; }
     866             : 
     867      673057 : bool IsBuiltinFunction(Isolate* isolate, HeapObject object,
     868             :                        Builtins::Name builtin_index) {
     869      673057 :   if (!object->IsJSFunction()) return false;
     870             :   JSFunction const function = JSFunction::cast(object);
     871      901618 :   return function->code() == isolate->builtins()->builtin(builtin_index);
     872             : }
     873             : 
     874        2938 : void CaptureAsyncStackTrace(Isolate* isolate, Handle<JSPromise> promise,
     875             :                             FrameArrayBuilder* builder) {
     876      170382 :   while (!builder->full()) {
     877             :     // Check that the {promise} is not settled.
     878      170373 :     if (promise->status() != Promise::kPending) return;
     879             : 
     880             :     // Check that we have exactly one PromiseReaction on the {promise}.
     881      170335 :     if (!promise->reactions()->IsPromiseReaction()) return;
     882             :     Handle<PromiseReaction> reaction(
     883             :         PromiseReaction::cast(promise->reactions()), isolate);
     884      167444 :     if (!reaction->next()->IsSmi()) return;
     885             : 
     886             :     // Check if the {reaction} has one of the known async function or
     887             :     // async generator continuations as its fulfill handler.
     888      334888 :     if (IsBuiltinFunction(isolate, reaction->fulfill_handler(),
     889      166161 :                           Builtins::kAsyncFunctionAwaitResolveClosure) ||
     890      166161 :         IsBuiltinFunction(isolate, reaction->fulfill_handler(),
     891      333569 :                           Builtins::kAsyncGeneratorAwaitResolveClosure) ||
     892      166125 :         IsBuiltinFunction(isolate, reaction->fulfill_handler(),
     893             :                           Builtins::kAsyncGeneratorYieldResolveClosure)) {
     894             :       // Now peak into the handlers' AwaitContext to get to
     895             :       // the JSGeneratorObject for the async function.
     896             :       Handle<Context> context(
     897             :           JSFunction::cast(reaction->fulfill_handler())->context(), isolate);
     898             :       Handle<JSGeneratorObject> generator_object(
     899        2710 :           JSGeneratorObject::cast(context->extension()), isolate);
     900        1355 :       CHECK(generator_object->is_suspended());
     901             : 
     902             :       // Append async frame corresponding to the {generator_object}.
     903        1355 :       builder->AppendAsyncFrame(generator_object);
     904             : 
     905             :       // Try to continue from here.
     906        1355 :       if (generator_object->IsJSAsyncFunctionObject()) {
     907             :         Handle<JSAsyncFunctionObject> async_function_object =
     908             :             Handle<JSAsyncFunctionObject>::cast(generator_object);
     909             :         promise = handle(async_function_object->promise(), isolate);
     910             :       } else {
     911             :         Handle<JSAsyncGeneratorObject> async_generator_object =
     912             :             Handle<JSAsyncGeneratorObject>::cast(generator_object);
     913          72 :         if (async_generator_object->queue()->IsUndefined(isolate)) return;
     914             :         Handle<AsyncGeneratorRequest> async_generator_request(
     915             :             AsyncGeneratorRequest::cast(async_generator_object->queue()),
     916             :             isolate);
     917             :         promise = handle(JSPromise::cast(async_generator_request->promise()),
     918             :                          isolate);
     919             :       }
     920      166089 :     } else if (IsBuiltinFunction(isolate, reaction->fulfill_handler(),
     921             :                                  Builtins::kPromiseAllResolveElementClosure)) {
     922             :       Handle<JSFunction> function(JSFunction::cast(reaction->fulfill_handler()),
     923             :                                   isolate);
     924             :       Handle<Context> context(function->context(), isolate);
     925             : 
     926             :       // We store the offset of the promise into the {function}'s
     927             :       // hash field for promise resolve element callbacks.
     928         216 :       int const offset = Smi::ToInt(Smi::cast(function->GetIdentityHash())) - 1;
     929         108 :       builder->AppendPromiseAllFrame(context, offset);
     930             : 
     931             :       // Now peak into the Promise.all() resolve element context to
     932             :       // find the promise capability that's being resolved when all
     933             :       // the concurrent promises resolve.
     934             :       int const index =
     935             :           PromiseBuiltins::kPromiseAllResolveElementCapabilitySlot;
     936             :       Handle<PromiseCapability> capability(
     937             :           PromiseCapability::cast(context->get(index)), isolate);
     938         108 :       if (!capability->promise()->IsJSPromise()) return;
     939             :       promise = handle(JSPromise::cast(capability->promise()), isolate);
     940             :     } else {
     941             :       // We have some generic promise chain here, so try to
     942             :       // continue with the chained promise on the reaction
     943             :       // (only works for native promise chains).
     944             :       Handle<HeapObject> promise_or_capability(
     945             :           reaction->promise_or_capability(), isolate);
     946      165981 :       if (promise_or_capability->IsJSPromise()) {
     947             :         promise = Handle<JSPromise>::cast(promise_or_capability);
     948           0 :       } else if (promise_or_capability->IsPromiseCapability()) {
     949             :         Handle<PromiseCapability> capability =
     950             :             Handle<PromiseCapability>::cast(promise_or_capability);
     951           0 :         if (!capability->promise()->IsJSPromise()) return;
     952             :         promise = handle(JSPromise::cast(capability->promise()), isolate);
     953             :       } else {
     954             :         // Otherwise the {promise_or_capability} must be undefined here.
     955           0 :         CHECK(promise_or_capability->IsUndefined(isolate));
     956             :         return;
     957             :       }
     958             :     }
     959             :   }
     960             : }
     961             : 
     962             : namespace {
     963             : 
     964             : struct CaptureStackTraceOptions {
     965             :   int limit;
     966             :   // 'filter_mode' and 'skip_mode' are somewhat orthogonal. 'filter_mode'
     967             :   // specifies whether to capture all frames, or just frames in the same
     968             :   // security context. While 'skip_mode' allows skipping the first frame.
     969             :   FrameSkipMode skip_mode;
     970             :   FrameArrayBuilder::FrameFilterMode filter_mode;
     971             : 
     972             :   bool capture_builtin_exit_frames;
     973             :   bool capture_only_frames_subject_to_debugging;
     974             :   bool async_stack_trace;
     975             : 
     976             :   enum CaptureResult { RAW_FRAME_ARRAY, STACK_TRACE_FRAME_ARRAY };
     977             :   CaptureResult capture_result;
     978             : };
     979             : 
     980     1311087 : Handle<Object> CaptureStackTrace(Isolate* isolate, Handle<Object> caller,
     981             :                                  CaptureStackTraceOptions options) {
     982     2622174 :   DisallowJavascriptExecution no_js(isolate);
     983             : 
     984             :   FrameArrayBuilder builder(isolate, options.skip_mode, options.limit, caller,
     985     1311087 :                             options.filter_mode);
     986             : 
     987             :   // Build the regular stack trace, and remember the last relevant
     988             :   // frame ID and inlined index (for the async stack trace handling
     989             :   // below, which starts from this last frame).
     990    10678327 :   for (StackFrameIterator it(isolate); !it.done() && !builder.full();
     991     9117257 :        it.Advance()) {
     992             :     StackFrame* const frame = it.frame();
     993     9117257 :     switch (frame->type()) {
     994             :       case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION:
     995             :       case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH:
     996             :       case StackFrame::OPTIMIZED:
     997             :       case StackFrame::INTERPRETED:
     998             :       case StackFrame::BUILTIN:
     999             :       case StackFrame::WASM_COMPILED:
    1000             :       case StackFrame::WASM_INTERPRETER_ENTRY: {
    1001             :         // A standard frame may include many summarized frames (due to
    1002             :         // inlining).
    1003     4984703 :         std::vector<FrameSummary> frames;
    1004     4984703 :         StandardFrame::cast(frame)->Summarize(&frames);
    1005    15262351 :         for (size_t i = frames.size(); i-- != 0 && !builder.full();) {
    1006             :           const auto& summary = frames[i];
    1007     5203101 :           if (options.capture_only_frames_subject_to_debugging &&
    1008       64347 :               !summary.is_subject_to_debugging()) {
    1009             :             continue;
    1010             :           }
    1011             : 
    1012     5136579 :           if (summary.IsJavaScript()) {
    1013             :             //=========================================================
    1014             :             // Handle a JavaScript frame.
    1015             :             //=========================================================
    1016             :             auto const& java_script = summary.AsJavaScript();
    1017     4979744 :             builder.AppendJavaScriptFrame(java_script);
    1018      156835 :           } else if (summary.IsWasmCompiled()) {
    1019             :             //=========================================================
    1020             :             // Handle a WASM compiled frame.
    1021             :             //=========================================================
    1022             :             auto const& wasm_compiled = summary.AsWasmCompiled();
    1023      155191 :             builder.AppendWasmCompiledFrame(wasm_compiled);
    1024        1644 :           } else if (summary.IsWasmInterpreted()) {
    1025             :             //=========================================================
    1026             :             // Handle a WASM interpreted frame.
    1027             :             //=========================================================
    1028             :             auto const& wasm_interpreted = summary.AsWasmInterpreted();
    1029        1644 :             builder.AppendWasmInterpretedFrame(wasm_interpreted);
    1030             :           }
    1031             :         }
    1032             :         break;
    1033             :       }
    1034             : 
    1035             :       case StackFrame::BUILTIN_EXIT:
    1036       68907 :         if (!options.capture_builtin_exit_frames) continue;
    1037             : 
    1038             :         // BuiltinExitFrames are not standard frames, so they do not have
    1039             :         // Summarize(). However, they may have one JS frame worth showing.
    1040       61056 :         builder.AppendBuiltinExitFrame(BuiltinExitFrame::cast(frame));
    1041             :         break;
    1042             : 
    1043             :       default:
    1044             :         break;
    1045             :     }
    1046             :   }
    1047             : 
    1048             :   // If --async-stack-traces are enabled and the "current microtask" is a
    1049             :   // PromiseReactionJobTask, we try to enrich the stack trace with async
    1050             :   // frames.
    1051     1311087 :   if (options.async_stack_trace) {
    1052             :     Handle<Object> current_microtask = isolate->factory()->current_microtask();
    1053     1245867 :     if (current_microtask->IsPromiseReactionJobTask()) {
    1054             :       Handle<PromiseReactionJobTask> promise_reaction_job_task =
    1055             :           Handle<PromiseReactionJobTask>::cast(current_microtask);
    1056             :       // Check if the {reaction} has one of the known async function or
    1057             :       // async generator continuations as its fulfill handler.
    1058        6130 :       if (IsBuiltinFunction(isolate, promise_reaction_job_task->handler(),
    1059        2154 :                             Builtins::kAsyncFunctionAwaitResolveClosure) ||
    1060        2154 :           IsBuiltinFunction(isolate, promise_reaction_job_task->handler(),
    1061        5084 :                             Builtins::kAsyncGeneratorAwaitResolveClosure) ||
    1062        2019 :           IsBuiltinFunction(isolate, promise_reaction_job_task->handler(),
    1063             :                             Builtins::kAsyncGeneratorYieldResolveClosure)) {
    1064             :         // Now peak into the handlers' AwaitContext to get to
    1065             :         // the JSGeneratorObject for the async function.
    1066             :         Handle<Context> context(
    1067             :             JSFunction::cast(promise_reaction_job_task->handler())->context(),
    1068             :             isolate);
    1069             :         Handle<JSGeneratorObject> generator_object(
    1070        2092 :             JSGeneratorObject::cast(context->extension()), isolate);
    1071        1046 :         if (generator_object->is_executing()) {
    1072        1027 :           if (generator_object->IsJSAsyncFunctionObject()) {
    1073             :             Handle<JSAsyncFunctionObject> async_function_object =
    1074             :                 Handle<JSAsyncFunctionObject>::cast(generator_object);
    1075             :             Handle<JSPromise> promise(async_function_object->promise(),
    1076             :                                       isolate);
    1077         892 :             CaptureAsyncStackTrace(isolate, promise, &builder);
    1078             :           } else {
    1079             :             Handle<JSAsyncGeneratorObject> async_generator_object =
    1080             :                 Handle<JSAsyncGeneratorObject>::cast(generator_object);
    1081             :             Handle<AsyncGeneratorRequest> async_generator_request(
    1082             :                 AsyncGeneratorRequest::cast(async_generator_object->queue()),
    1083             :                 isolate);
    1084             :             Handle<JSPromise> promise(
    1085             :                 JSPromise::cast(async_generator_request->promise()), isolate);
    1086         135 :             CaptureAsyncStackTrace(isolate, promise, &builder);
    1087             :           }
    1088             :         }
    1089             :       } else {
    1090             :         // The {promise_reaction_job_task} doesn't belong to an await (or
    1091             :         // yield inside an async generator), but we might still be able to
    1092             :         // find an async frame if we follow along the chain of promises on
    1093             :         // the {promise_reaction_job_task}.
    1094             :         Handle<HeapObject> promise_or_capability(
    1095             :             promise_reaction_job_task->promise_or_capability(), isolate);
    1096        2019 :         if (promise_or_capability->IsJSPromise()) {
    1097             :           Handle<JSPromise> promise =
    1098        1911 :               Handle<JSPromise>::cast(promise_or_capability);
    1099        1911 :           CaptureAsyncStackTrace(isolate, promise, &builder);
    1100             :         }
    1101             :       }
    1102             :     }
    1103             :   }
    1104             : 
    1105             :   // TODO(yangguo): Queue this structured stack trace for preprocessing on GC.
    1106     1311087 :   if (options.capture_result == CaptureStackTraceOptions::RAW_FRAME_ARRAY) {
    1107     1246245 :     return isolate->factory()->NewJSArrayWithElements(builder.GetElements());
    1108             :   }
    1109       64842 :   return builder.GetElementsAsStackTraceFrameArray();
    1110             : }
    1111             : 
    1112             : }  // namespace
    1113             : 
    1114     1253730 : Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
    1115             :                                                 FrameSkipMode mode,
    1116             :                                                 Handle<Object> caller) {
    1117             :   int limit;
    1118     1261215 :   if (!GetStackTraceLimit(this, &limit)) return factory()->undefined_value();
    1119             : 
    1120             :   CaptureStackTraceOptions options;
    1121     1246245 :   options.limit = limit;
    1122             :   options.skip_mode = mode;
    1123             :   options.capture_builtin_exit_frames = true;
    1124     1246245 :   options.async_stack_trace = FLAG_async_stack_traces;
    1125             :   options.filter_mode = FrameArrayBuilder::CURRENT_SECURITY_CONTEXT;
    1126             :   options.capture_only_frames_subject_to_debugging = false;
    1127             :   options.capture_result = CaptureStackTraceOptions::RAW_FRAME_ARRAY;
    1128             : 
    1129     1246245 :   return CaptureStackTrace(this, caller, options);
    1130             : }
    1131             : 
    1132     1205315 : MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace(
    1133             :     Handle<JSReceiver> error_object) {
    1134     1205315 :   if (capture_stack_trace_for_uncaught_exceptions_) {
    1135             :     // Capture stack trace for a detailed exception message.
    1136             :     Handle<Name> key = factory()->detailed_stack_trace_symbol();
    1137             :     Handle<FixedArray> stack_trace = CaptureCurrentStackTrace(
    1138             :         stack_trace_for_uncaught_exceptions_frame_limit_,
    1139         264 :         stack_trace_for_uncaught_exceptions_options_);
    1140         528 :     RETURN_ON_EXCEPTION(
    1141             :         this,
    1142             :         Object::SetProperty(this, error_object, key, stack_trace,
    1143             :                             StoreOrigin::kMaybeKeyed,
    1144             :                             Just(ShouldThrow::kThrowOnError)),
    1145             :         JSReceiver);
    1146             :   }
    1147     1205315 :   return error_object;
    1148             : }
    1149             : 
    1150     1253730 : MaybeHandle<JSReceiver> Isolate::CaptureAndSetSimpleStackTrace(
    1151             :     Handle<JSReceiver> error_object, FrameSkipMode mode,
    1152             :     Handle<Object> caller) {
    1153             :   // Capture stack trace for simple stack trace string formatting.
    1154             :   Handle<Name> key = factory()->stack_trace_symbol();
    1155             :   Handle<Object> stack_trace =
    1156     1253730 :       CaptureSimpleStackTrace(error_object, mode, caller);
    1157     2507460 :   RETURN_ON_EXCEPTION(this,
    1158             :                       Object::SetProperty(this, error_object, key, stack_trace,
    1159             :                                           StoreOrigin::kMaybeKeyed,
    1160             :                                           Just(ShouldThrow::kThrowOnError)),
    1161             :                       JSReceiver);
    1162     1253730 :   return error_object;
    1163             : }
    1164             : 
    1165         363 : Handle<FixedArray> Isolate::GetDetailedStackTrace(
    1166             :     Handle<JSObject> error_object) {
    1167             :   Handle<Name> key_detailed = factory()->detailed_stack_trace_symbol();
    1168             :   Handle<Object> stack_trace =
    1169         363 :       JSReceiver::GetDataProperty(error_object, key_detailed);
    1170         363 :   if (stack_trace->IsFixedArray()) return Handle<FixedArray>::cast(stack_trace);
    1171          16 :   return Handle<FixedArray>();
    1172             : }
    1173             : 
    1174        4156 : Address Isolate::GetAbstractPC(int* line, int* column) {
    1175        4156 :   JavaScriptFrameIterator it(this);
    1176             : 
    1177        4156 :   if (it.done()) {
    1178           0 :     *line = -1;
    1179           0 :     *column = -1;
    1180           0 :     return kNullAddress;
    1181             :   }
    1182             :   JavaScriptFrame* frame = it.frame();
    1183             :   DCHECK(!frame->is_builtin());
    1184        4156 :   int position = frame->position();
    1185             : 
    1186        8312 :   Object maybe_script = frame->function()->shared()->script();
    1187        4156 :   if (maybe_script->IsScript()) {
    1188             :     Handle<Script> script(Script::cast(maybe_script), this);
    1189             :     Script::PositionInfo info;
    1190        4156 :     Script::GetPositionInfo(script, position, &info, Script::WITH_OFFSET);
    1191        4156 :     *line = info.line + 1;
    1192        4156 :     *column = info.column + 1;
    1193             :   } else {
    1194           0 :     *line = position;
    1195           0 :     *column = -1;
    1196             :   }
    1197             : 
    1198        8312 :   if (frame->is_interpreted()) {
    1199             :     InterpretedFrame* iframe = static_cast<InterpretedFrame*>(frame);
    1200             :     Address bytecode_start =
    1201        6696 :         iframe->GetBytecodeArray()->GetFirstBytecodeAddress();
    1202        3348 :     return bytecode_start + iframe->GetBytecodeOffset();
    1203             :   }
    1204             : 
    1205         808 :   return frame->pc();
    1206             : }
    1207             : 
    1208       64842 : Handle<FixedArray> Isolate::CaptureCurrentStackTrace(
    1209             :     int frame_limit, StackTrace::StackTraceOptions stack_trace_options) {
    1210             :   CaptureStackTraceOptions options;
    1211             :   options.limit = Max(frame_limit, 0);  // Ensure no negative values.
    1212             :   options.skip_mode = SKIP_NONE;
    1213             :   options.capture_builtin_exit_frames = false;
    1214             :   options.async_stack_trace = false;
    1215             :   options.filter_mode =
    1216       64842 :       (stack_trace_options & StackTrace::kExposeFramesAcrossSecurityOrigins)
    1217             :           ? FrameArrayBuilder::ALL
    1218       64842 :           : FrameArrayBuilder::CURRENT_SECURITY_CONTEXT;
    1219             :   options.capture_only_frames_subject_to_debugging = true;
    1220             :   options.capture_result = CaptureStackTraceOptions::STACK_TRACE_FRAME_ARRAY;
    1221             : 
    1222             :   return Handle<FixedArray>::cast(
    1223       64842 :       CaptureStackTrace(this, factory()->undefined_value(), options));
    1224             : }
    1225             : 
    1226          17 : void Isolate::PrintStack(FILE* out, PrintStackMode mode) {
    1227          17 :   if (stack_trace_nesting_level_ == 0) {
    1228          17 :     stack_trace_nesting_level_++;
    1229          17 :     StringStream::ClearMentionedObjectCache(this);
    1230             :     HeapStringAllocator allocator;
    1231             :     StringStream accumulator(&allocator);
    1232          17 :     incomplete_message_ = &accumulator;
    1233          17 :     PrintStack(&accumulator, mode);
    1234          17 :     accumulator.OutputToFile(out);
    1235          17 :     InitializeLoggingAndCounters();
    1236          17 :     accumulator.Log(this);
    1237          17 :     incomplete_message_ = nullptr;
    1238          17 :     stack_trace_nesting_level_ = 0;
    1239           0 :   } else if (stack_trace_nesting_level_ == 1) {
    1240           0 :     stack_trace_nesting_level_++;
    1241             :     base::OS::PrintError(
    1242           0 :       "\n\nAttempt to print stack while printing stack (double fault)\n");
    1243             :     base::OS::PrintError(
    1244           0 :       "If you are lucky you may find a partial stack dump on stdout.\n\n");
    1245           0 :     incomplete_message_->OutputToFile(out);
    1246             :   }
    1247          17 : }
    1248             : 
    1249             : 
    1250          25 : static void PrintFrames(Isolate* isolate,
    1251             :                         StringStream* accumulator,
    1252             :                         StackFrame::PrintMode mode) {
    1253          25 :   StackFrameIterator it(isolate);
    1254         477 :   for (int i = 0; !it.done(); it.Advance()) {
    1255         226 :     it.frame()->Print(accumulator, mode, i++);
    1256             :   }
    1257          25 : }
    1258             : 
    1259          32 : void Isolate::PrintStack(StringStream* accumulator, PrintStackMode mode) {
    1260             :   HandleScope scope(this);
    1261             :   DCHECK(accumulator->IsMentionedObjectCacheClear(this));
    1262             : 
    1263             :   // Avoid printing anything if there are no frames.
    1264          32 :   if (c_entry_fp(thread_local_top()) == 0) return;
    1265             : 
    1266             :   accumulator->Add(
    1267          17 :       "\n==== JS stack trace =========================================\n\n");
    1268          17 :   PrintFrames(this, accumulator, StackFrame::OVERVIEW);
    1269          17 :   if (mode == kPrintStackVerbose) {
    1270             :     accumulator->Add(
    1271           8 :         "\n==== Details ================================================\n\n");
    1272           8 :     PrintFrames(this, accumulator, StackFrame::DETAILS);
    1273           8 :     accumulator->PrintMentionedObjectCache(this);
    1274             :   }
    1275          17 :   accumulator->Add("=====================\n\n");
    1276             : }
    1277             : 
    1278             : 
    1279          26 : void Isolate::SetFailedAccessCheckCallback(
    1280             :     v8::FailedAccessCheckCallback callback) {
    1281          26 :   thread_local_top()->failed_access_check_callback_ = callback;
    1282          26 : }
    1283             : 
    1284             : 
    1285        1318 : void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver) {
    1286        1318 :   if (!thread_local_top()->failed_access_check_callback_) {
    1287        3483 :     return ScheduleThrow(*factory()->NewTypeError(MessageTemplate::kNoAccess));
    1288             :   }
    1289             : 
    1290             :   DCHECK(receiver->IsAccessCheckNeeded());
    1291             :   DCHECK(!context().is_null());
    1292             : 
    1293             :   // Get the data object from access check info.
    1294             :   HandleScope scope(this);
    1295             :   Handle<Object> data;
    1296             :   { DisallowHeapAllocation no_gc;
    1297         157 :     AccessCheckInfo access_check_info = AccessCheckInfo::Get(this, receiver);
    1298         157 :     if (access_check_info.is_null()) {
    1299             :       AllowHeapAllocation doesnt_matter_anymore;
    1300             :       return ScheduleThrow(
    1301           0 :           *factory()->NewTypeError(MessageTemplate::kNoAccess));
    1302             :     }
    1303             :     data = handle(access_check_info->data(), this);
    1304             :   }
    1305             : 
    1306             :   // Leaving JavaScript.
    1307         314 :   VMState<EXTERNAL> state(this);
    1308         157 :   thread_local_top()->failed_access_check_callback_(
    1309         157 :       v8::Utils::ToLocal(receiver), v8::ACCESS_HAS, v8::Utils::ToLocal(data));
    1310             : }
    1311             : 
    1312             : 
    1313     6039822 : bool Isolate::MayAccess(Handle<Context> accessing_context,
    1314             :                         Handle<JSObject> receiver) {
    1315             :   DCHECK(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
    1316             : 
    1317             :   // Check for compatibility between the security tokens in the
    1318             :   // current lexical context and the accessed object.
    1319             : 
    1320             :   // During bootstrapping, callback functions are not enabled yet.
    1321     6039822 :   if (bootstrapper()->IsActive()) return true;
    1322             :   {
    1323             :     DisallowHeapAllocation no_gc;
    1324             : 
    1325     6039584 :     if (receiver->IsJSGlobalProxy()) {
    1326             :       Object receiver_context =
    1327             :           JSGlobalProxy::cast(*receiver)->native_context();
    1328    12074223 :       if (!receiver_context->IsContext()) return false;
    1329             : 
    1330             :       // Get the native context of current top context.
    1331             :       // avoid using Isolate::native_context() because it uses Handle.
    1332             :       Context native_context =
    1333    12075230 :           accessing_context->global_object()->native_context();
    1334     6037615 :       if (receiver_context == native_context) return true;
    1335             : 
    1336        3048 :       if (Context::cast(receiver_context)->security_token() ==
    1337             :           native_context->security_token())
    1338             :         return true;
    1339             :     }
    1340             :   }
    1341             : 
    1342             :   HandleScope scope(this);
    1343             :   Handle<Object> data;
    1344             :   v8::AccessCheckCallback callback = nullptr;
    1345             :   { DisallowHeapAllocation no_gc;
    1346        3097 :     AccessCheckInfo access_check_info = AccessCheckInfo::Get(this, receiver);
    1347        3097 :     if (access_check_info.is_null()) return false;
    1348             :     Object fun_obj = access_check_info->callback();
    1349             :     callback = v8::ToCData<v8::AccessCheckCallback>(fun_obj);
    1350             :     data = handle(access_check_info->data(), this);
    1351             :   }
    1352             : 
    1353        2400 :   LOG(this, ApiSecurityCheck());
    1354             : 
    1355             :   {
    1356             :     // Leaving JavaScript.
    1357        4800 :     VMState<EXTERNAL> state(this);
    1358             :     return callback(v8::Utils::ToLocal(accessing_context),
    1359        2400 :                     v8::Utils::ToLocal(receiver), v8::Utils::ToLocal(data));
    1360             :   }
    1361             : }
    1362             : 
    1363       48415 : Object Isolate::StackOverflow() {
    1364       48415 :   if (FLAG_abort_on_stack_or_string_length_overflow) {
    1365           0 :     FATAL("Aborting on stack overflow");
    1366             :   }
    1367             : 
    1368       96830 :   DisallowJavascriptExecution no_js(this);
    1369             :   HandleScope scope(this);
    1370             : 
    1371       48415 :   Handle<JSFunction> fun = range_error_function();
    1372             :   Handle<Object> msg = factory()->NewStringFromAsciiChecked(
    1373       48415 :       MessageFormatter::TemplateString(MessageTemplate::kStackOverflow));
    1374             :   Handle<Object> no_caller;
    1375             :   Handle<Object> exception;
    1376       96830 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    1377             :       this, exception,
    1378             :       ErrorUtils::Construct(this, fun, fun, msg, SKIP_NONE, no_caller, true));
    1379             : 
    1380       48415 :   Throw(*exception, nullptr);
    1381             : 
    1382             : #ifdef VERIFY_HEAP
    1383             :   if (FLAG_verify_heap && FLAG_stress_compaction) {
    1384             :     heap()->CollectAllGarbage(Heap::kNoGCFlags,
    1385             :                               GarbageCollectionReason::kTesting);
    1386             :   }
    1387             : #endif  // VERIFY_HEAP
    1388             : 
    1389       48415 :   return ReadOnlyRoots(heap()).exception();
    1390             : }
    1391             : 
    1392        4305 : Object Isolate::TerminateExecution() {
    1393        4305 :   return Throw(ReadOnlyRoots(this).termination_exception(), nullptr);
    1394             : }
    1395             : 
    1396        3114 : void Isolate::CancelTerminateExecution() {
    1397        3114 :   if (try_catch_handler()) {
    1398        1298 :     try_catch_handler()->has_terminated_ = false;
    1399             :   }
    1400        6143 :   if (has_pending_exception() &&
    1401             :       pending_exception() == ReadOnlyRoots(this).termination_exception()) {
    1402        3029 :     thread_local_top()->external_caught_exception_ = false;
    1403             :     clear_pending_exception();
    1404             :   }
    1405        3177 :   if (has_scheduled_exception() &&
    1406             :       scheduled_exception() == ReadOnlyRoots(this).termination_exception()) {
    1407          63 :     thread_local_top()->external_caught_exception_ = false;
    1408             :     clear_scheduled_exception();
    1409             :   }
    1410        3114 : }
    1411             : 
    1412             : 
    1413       60205 : void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
    1414             :   ExecutionAccess access(this);
    1415       60205 :   api_interrupts_queue_.push(InterruptEntry(callback, data));
    1416             :   stack_guard()->RequestApiInterrupt();
    1417       60205 : }
    1418             : 
    1419             : 
    1420        2165 : void Isolate::InvokeApiInterruptCallbacks() {
    1421             :   RuntimeCallTimerScope runtimeTimer(
    1422        2165 :       this, RuntimeCallCounterId::kInvokeApiInterruptCallbacks);
    1423             :   // Note: callback below should be called outside of execution access lock.
    1424             :   while (true) {
    1425             :     InterruptEntry entry;
    1426             :     {
    1427             :       ExecutionAccess access(this);
    1428       64525 :       if (api_interrupts_queue_.empty()) return;
    1429             :       entry = api_interrupts_queue_.front();
    1430             :       api_interrupts_queue_.pop();
    1431             :     }
    1432      120390 :     VMState<EXTERNAL> state(this);
    1433             :     HandleScope handle_scope(this);
    1434       60195 :     entry.first(reinterpret_cast<v8::Isolate*>(this), entry.second);
    1435             :   }
    1436             : }
    1437             : 
    1438             : 
    1439          30 : void ReportBootstrappingException(Handle<Object> exception,
    1440             :                                   MessageLocation* location) {
    1441          30 :   base::OS::PrintError("Exception thrown during bootstrapping\n");
    1442          30 :   if (location == nullptr || location->script().is_null()) return;
    1443             :   // We are bootstrapping and caught an error where the location is set
    1444             :   // and we have a script for the location.
    1445             :   // In this case we could have an extension (or an internal error
    1446             :   // somewhere) and we print out the line number at which the error occurred
    1447             :   // to the console for easier debugging.
    1448             :   int line_number =
    1449          30 :       location->script()->GetLineNumber(location->start_pos()) + 1;
    1450          60 :   if (exception->IsString() && location->script()->name()->IsString()) {
    1451             :     base::OS::PrintError(
    1452             :         "Extension or internal compilation error: %s in %s at line %d.\n",
    1453          60 :         String::cast(*exception)->ToCString().get(),
    1454          60 :         String::cast(location->script()->name())->ToCString().get(),
    1455          30 :         line_number);
    1456           0 :   } else if (location->script()->name()->IsString()) {
    1457             :     base::OS::PrintError(
    1458             :         "Extension or internal compilation error in %s at line %d.\n",
    1459           0 :         String::cast(location->script()->name())->ToCString().get(),
    1460           0 :         line_number);
    1461           0 :   } else if (exception->IsString()) {
    1462             :     base::OS::PrintError("Extension or internal compilation error: %s.\n",
    1463           0 :                          String::cast(*exception)->ToCString().get());
    1464             :   } else {
    1465           0 :     base::OS::PrintError("Extension or internal compilation error.\n");
    1466             :   }
    1467             : #ifdef OBJECT_PRINT
    1468             :   // Since comments and empty lines have been stripped from the source of
    1469             :   // builtins, print the actual source here so that line numbers match.
    1470             :   if (location->script()->source()->IsString()) {
    1471             :     Handle<String> src(String::cast(location->script()->source()),
    1472             :                        location->script()->GetIsolate());
    1473             :     PrintF("Failing script:");
    1474             :     int len = src->length();
    1475             :     if (len == 0) {
    1476             :       PrintF(" <not available>\n");
    1477             :     } else {
    1478             :       PrintF("\n");
    1479             :       int line_number = 1;
    1480             :       PrintF("%5d: ", line_number);
    1481             :       for (int i = 0; i < len; i++) {
    1482             :         uint16_t character = src->Get(i);
    1483             :         PrintF("%c", character);
    1484             :         if (character == '\n' && i < len - 2) {
    1485             :           PrintF("%5d: ", ++line_number);
    1486             :         }
    1487             :       }
    1488             :       PrintF("\n");
    1489             :     }
    1490             :   }
    1491             : #endif
    1492             : }
    1493             : 
    1494     1409794 : Object Isolate::Throw(Object raw_exception, MessageLocation* location) {
    1495             :   DCHECK(!has_pending_exception());
    1496             : 
    1497             :   HandleScope scope(this);
    1498             :   Handle<Object> exception(raw_exception, this);
    1499             : 
    1500     1409794 :   if (FLAG_print_all_exceptions) {
    1501             :     printf("=========================================================\n");
    1502             :     printf("Exception thrown:\n");
    1503           0 :     if (location) {
    1504             :       Handle<Script> script = location->script();
    1505           0 :       Handle<Object> name(script->GetNameOrSourceURL(), this);
    1506             :       printf("at ");
    1507           0 :       if (name->IsString() && String::cast(*name)->length() > 0)
    1508           0 :         String::cast(*name)->PrintOn(stdout);
    1509             :       else
    1510             :         printf("<anonymous>");
    1511             : // Script::GetLineNumber and Script::GetColumnNumber can allocate on the heap to
    1512             : // initialize the line_ends array, so be careful when calling them.
    1513             : #ifdef DEBUG
    1514             :       if (AllowHeapAllocation::IsAllowed()) {
    1515             : #else
    1516             :       if ((false)) {
    1517             : #endif
    1518             :         printf(", %d:%d - %d:%d\n",
    1519             :                Script::GetLineNumber(script, location->start_pos()) + 1,
    1520             :                Script::GetColumnNumber(script, location->start_pos()),
    1521             :                Script::GetLineNumber(script, location->end_pos()) + 1,
    1522             :                Script::GetColumnNumber(script, location->end_pos()));
    1523             :         // Make sure to update the raw exception pointer in case it moved.
    1524             :         raw_exception = *exception;
    1525             :       } else {
    1526           0 :         printf(", line %d\n", script->GetLineNumber(location->start_pos()) + 1);
    1527             :       }
    1528             :     }
    1529             :     raw_exception->Print();
    1530             :     printf("Stack Trace:\n");
    1531           0 :     PrintStack(stdout);
    1532             :     printf("=========================================================\n");
    1533             :   }
    1534             : 
    1535             :   // Determine whether a message needs to be created for the given exception
    1536             :   // depending on the following criteria:
    1537             :   // 1) External v8::TryCatch missing: Always create a message because any
    1538             :   //    JavaScript handler for a finally-block might re-throw to top-level.
    1539             :   // 2) External v8::TryCatch exists: Only create a message if the handler
    1540             :   //    captures messages or is verbose (which reports despite the catch).
    1541             :   // 3) ReThrow from v8::TryCatch: The message from a previous throw still
    1542             :   //    exists and we preserve it instead of creating a new message.
    1543     1126454 :   bool requires_message = try_catch_handler() == nullptr ||
    1544     1467908 :                           try_catch_handler()->is_verbose_ ||
    1545       58114 :                           try_catch_handler()->capture_message_;
    1546     1409794 :   bool rethrowing_message = thread_local_top()->rethrowing_message_;
    1547             : 
    1548     1409794 :   thread_local_top()->rethrowing_message_ = false;
    1549             : 
    1550             :   // Notify debugger of exception.
    1551     1409794 :   if (is_catchable_by_javascript(raw_exception)) {
    1552     1405489 :     debug()->OnThrow(exception);
    1553             :   }
    1554             : 
    1555             :   // Generate the message if required.
    1556     1409794 :   if (requires_message && !rethrowing_message) {
    1557     1358674 :     MessageLocation computed_location;
    1558             :     // If no location was specified we try to use a computed one instead.
    1559     1358674 :     if (location == nullptr && ComputeLocation(&computed_location)) {
    1560             :       location = &computed_location;
    1561             :     }
    1562             : 
    1563     1358674 :     if (bootstrapper()->IsActive()) {
    1564             :       // It's not safe to try to make message objects or collect stack traces
    1565             :       // while the bootstrapper is active since the infrastructure may not have
    1566             :       // been properly initialized.
    1567          30 :       ReportBootstrappingException(exception, location);
    1568             :     } else {
    1569     1358644 :       Handle<Object> message_obj = CreateMessage(exception, location);
    1570     1358644 :       thread_local_top()->pending_message_obj_ = *message_obj;
    1571             : 
    1572             :       // For any exception not caught by JavaScript, even when an external
    1573             :       // handler is present:
    1574             :       // If the abort-on-uncaught-exception flag is specified, and if the
    1575             :       // embedder didn't specify a custom uncaught exception callback,
    1576             :       // or if the custom callback determined that V8 should abort, then
    1577             :       // abort.
    1578     1358644 :       if (FLAG_abort_on_uncaught_exception) {
    1579           5 :         CatchType prediction = PredictExceptionCatcher();
    1580          15 :         if ((prediction == NOT_CAUGHT || prediction == CAUGHT_BY_EXTERNAL) &&
    1581          10 :             (!abort_on_uncaught_exception_callback_ ||
    1582           5 :              abort_on_uncaught_exception_callback_(
    1583             :                  reinterpret_cast<v8::Isolate*>(this)))) {
    1584             :           // Prevent endless recursion.
    1585           0 :           FLAG_abort_on_uncaught_exception = false;
    1586             :           // This flag is intended for use by JavaScript developers, so
    1587             :           // print a user-friendly stack trace (not an internal one).
    1588             :           PrintF(stderr, "%s\n\nFROM\n",
    1589           0 :                  MessageHandler::GetLocalizedMessage(this, message_obj).get());
    1590           0 :           PrintCurrentStackTrace(stderr);
    1591           0 :           base::OS::Abort();
    1592             :         }
    1593             :       }
    1594             :     }
    1595             :   }
    1596             : 
    1597             :   // Set the exception being thrown.
    1598             :   set_pending_exception(*exception);
    1599     2819588 :   return ReadOnlyRoots(heap()).exception();
    1600             : }
    1601             : 
    1602       83904 : Object Isolate::ReThrow(Object exception) {
    1603             :   DCHECK(!has_pending_exception());
    1604             : 
    1605             :   // Set the exception being re-thrown.
    1606             :   set_pending_exception(exception);
    1607       83904 :   return ReadOnlyRoots(heap()).exception();
    1608             : }
    1609             : 
    1610     1311088 : Object Isolate::UnwindAndFindHandler() {
    1611     1311088 :   Object exception = pending_exception();
    1612             : 
    1613             :   auto FoundHandler = [&](Context context, Address instruction_start,
    1614             :                           intptr_t handler_offset,
    1615             :                           Address constant_pool_address, Address handler_sp,
    1616             :                           Address handler_fp) {
    1617             :     // Store information to be consumed by the CEntry.
    1618     1311088 :     thread_local_top()->pending_handler_context_ = context;
    1619             :     thread_local_top()->pending_handler_entrypoint_ =
    1620     1311088 :         instruction_start + handler_offset;
    1621     1311088 :     thread_local_top()->pending_handler_constant_pool_ = constant_pool_address;
    1622     1311088 :     thread_local_top()->pending_handler_fp_ = handler_fp;
    1623     1311088 :     thread_local_top()->pending_handler_sp_ = handler_sp;
    1624             : 
    1625             :     // Return and clear pending exception.
    1626             :     clear_pending_exception();
    1627     1311088 :     return exception;
    1628             :   };
    1629             : 
    1630             :   // Special handling of termination exceptions, uncatchable by JavaScript and
    1631             :   // Wasm code, we unwind the handlers until the top ENTRY handler is found.
    1632             :   bool catchable_by_js = is_catchable_by_javascript(exception);
    1633             : 
    1634             :   // Compute handler and stack unwinding information by performing a full walk
    1635             :   // over the stack and dispatching according to the frame type.
    1636    22840103 :   for (StackFrameIterator iter(this);; iter.Advance()) {
    1637             :     // Handler must exist.
    1638             :     DCHECK(!iter.done());
    1639             : 
    1640             :     StackFrame* frame = iter.frame();
    1641             : 
    1642    22840103 :     switch (frame->type()) {
    1643             :       case StackFrame::ENTRY:
    1644             :       case StackFrame::CONSTRUCT_ENTRY: {
    1645             :         // For JSEntry frames we always have a handler.
    1646             :         StackHandler* handler = frame->top_handler();
    1647             : 
    1648             :         // Restore the next handler.
    1649      118860 :         thread_local_top()->handler_ = handler->next_address();
    1650             : 
    1651             :         // Gather information from the handler.
    1652      118860 :         Code code = frame->LookupCode();
    1653      118860 :         HandlerTable table(code);
    1654             :         return FoundHandler(Context(), code->InstructionStart(),
    1655      118860 :                             table.LookupReturn(0), code->constant_pool(),
    1656             :                             handler->address() + StackHandlerConstants::kSize,
    1657      118860 :                             0);
    1658             :       }
    1659             : 
    1660             :       case StackFrame::WASM_COMPILED: {
    1661     2464811 :         if (trap_handler::IsThreadInWasm()) {
    1662             :           trap_handler::ClearThreadInWasm();
    1663             :         }
    1664             : 
    1665             :         // For WebAssembly frames we perform a lookup in the handler table.
    1666     2464811 :         if (!catchable_by_js) break;
    1667             :         WasmCompiledFrame* wasm_frame = static_cast<WasmCompiledFrame*>(frame);
    1668     2464803 :         int stack_slots = 0;  // Will contain stack slot count of frame.
    1669     2464803 :         int offset = wasm_frame->LookupExceptionHandlerInTable(&stack_slots);
    1670     2464803 :         if (offset < 0) break;
    1671             :         // Compute the stack pointer from the frame pointer. This ensures that
    1672             :         // argument slots on the stack are dropped as returning would.
    1673             :         Address return_sp = frame->fp() +
    1674         656 :                             StandardFrameConstants::kFixedFrameSizeAboveFp -
    1675        1312 :                             stack_slots * kSystemPointerSize;
    1676             : 
    1677             :         // This is going to be handled by Wasm, so we need to set the TLS flag
    1678             :         // again. It was cleared above assuming the frame would be unwound.
    1679             :         trap_handler::SetThreadInWasm();
    1680             : 
    1681             :         // Gather information from the frame.
    1682             :         wasm::WasmCode* wasm_code =
    1683         656 :             wasm_engine()->code_manager()->LookupCode(frame->pc());
    1684             :         return FoundHandler(Context(), wasm_code->instruction_start(), offset,
    1685         656 :                             wasm_code->constant_pool(), return_sp, frame->fp());
    1686             :       }
    1687             : 
    1688             :       case StackFrame::OPTIMIZED: {
    1689             :         // For optimized frames we perform a lookup in the handler table.
    1690     3333011 :         if (!catchable_by_js) break;
    1691             :         OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame);
    1692     3332630 :         int stack_slots = 0;  // Will contain stack slot count of frame.
    1693             :         int offset =
    1694     3332630 :             js_frame->LookupExceptionHandlerInTable(&stack_slots, nullptr);
    1695     3332630 :         if (offset < 0) break;
    1696             :         // Compute the stack pointer from the frame pointer. This ensures
    1697             :         // that argument slots on the stack are dropped as returning would.
    1698             :         Address return_sp = frame->fp() +
    1699      326961 :                             StandardFrameConstants::kFixedFrameSizeAboveFp -
    1700      653922 :                             stack_slots * kSystemPointerSize;
    1701             : 
    1702             :         // Gather information from the frame.
    1703      326961 :         Code code = frame->LookupCode();
    1704             : 
    1705             :         // TODO(bmeurer): Turbofanned BUILTIN frames appear as OPTIMIZED,
    1706             :         // but do not have a code kind of OPTIMIZED_FUNCTION.
    1707      581482 :         if (code->kind() == Code::OPTIMIZED_FUNCTION &&
    1708      254521 :             code->marked_for_deoptimization()) {
    1709             :           // If the target code is lazy deoptimized, we jump to the original
    1710             :           // return address, but we make a note that we are throwing, so
    1711             :           // that the deoptimizer can do the right thing.
    1712       10736 :           offset = static_cast<int>(frame->pc() - code->entry());
    1713             :           set_deoptimizer_lazy_throw(true);
    1714             :         }
    1715             : 
    1716             :         return FoundHandler(Context(), code->InstructionStart(), offset,
    1717      326961 :                             code->constant_pool(), return_sp, frame->fp());
    1718             :       }
    1719             : 
    1720             :       case StackFrame::STUB: {
    1721             :         // Some stubs are able to handle exceptions.
    1722     1043877 :         if (!catchable_by_js) break;
    1723             :         StubFrame* stub_frame = static_cast<StubFrame*>(frame);
    1724             :         wasm::WasmCode* wasm_code =
    1725     1042521 :             wasm_engine()->code_manager()->LookupCode(frame->pc());
    1726     1042521 :         if (wasm_code != nullptr) {
    1727             :           // It is safe to skip Wasm runtime stubs as none of them contain local
    1728             :           // exception handlers.
    1729           0 :           CHECK_EQ(wasm::WasmCode::kRuntimeStub, wasm_code->kind());
    1730           0 :           CHECK_EQ(0, wasm_code->handler_table_offset());
    1731             :           break;
    1732             :         }
    1733     1042521 :         Code code = stub_frame->LookupCode();
    1734     2523277 :         if (!code->IsCode() || code->kind() != Code::BUILTIN ||
    1735     1526360 :             !code->has_handler_table() || !code->is_turbofanned()) {
    1736             :           break;
    1737             :         }
    1738             : 
    1739       45604 :         int stack_slots = 0;  // Will contain stack slot count of frame.
    1740       45604 :         int offset = stub_frame->LookupExceptionHandlerInTable(&stack_slots);
    1741       45604 :         if (offset < 0) break;
    1742             : 
    1743             :         // Compute the stack pointer from the frame pointer. This ensures
    1744             :         // that argument slots on the stack are dropped as returning would.
    1745             :         Address return_sp = frame->fp() +
    1746       45604 :                             StandardFrameConstants::kFixedFrameSizeAboveFp -
    1747       91208 :                             stack_slots * kSystemPointerSize;
    1748             : 
    1749             :         return FoundHandler(Context(), code->InstructionStart(), offset,
    1750       45604 :                             code->constant_pool(), return_sp, frame->fp());
    1751             :       }
    1752             : 
    1753             :       case StackFrame::INTERPRETED: {
    1754             :         // For interpreted frame we perform a range lookup in the handler table.
    1755    13456928 :         if (!catchable_by_js) break;
    1756             :         InterpretedFrame* js_frame = static_cast<InterpretedFrame*>(frame);
    1757             :         int register_slots = InterpreterFrameConstants::RegisterStackSlotCount(
    1758    26906732 :             js_frame->GetBytecodeArray()->register_count());
    1759    13453366 :         int context_reg = 0;  // Will contain register index holding context.
    1760             :         int offset =
    1761    13453366 :             js_frame->LookupExceptionHandlerInTable(&context_reg, nullptr);
    1762    13453366 :         if (offset < 0) break;
    1763             :         // Compute the stack pointer from the frame pointer. This ensures that
    1764             :         // argument slots on the stack are dropped as returning would.
    1765             :         // Note: This is only needed for interpreted frames that have been
    1766             :         //       materialized by the deoptimizer. If there is a handler frame
    1767             :         //       in between then {frame->sp()} would already be correct.
    1768             :         Address return_sp = frame->fp() -
    1769      818999 :                             InterpreterFrameConstants::kFixedFrameSizeFromFp -
    1770     1637998 :                             register_slots * kSystemPointerSize;
    1771             : 
    1772             :         // Patch the bytecode offset in the interpreted frame to reflect the
    1773             :         // position of the exception handler. The special builtin below will
    1774             :         // take care of continuing to dispatch at that position. Also restore
    1775             :         // the correct context for the handler from the interpreter register.
    1776             :         Context context =
    1777      818999 :             Context::cast(js_frame->ReadInterpreterRegister(context_reg));
    1778      818999 :         js_frame->PatchBytecodeOffset(static_cast<int>(offset));
    1779             : 
    1780             :         Code code =
    1781      818999 :             builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
    1782             :         return FoundHandler(context, code->InstructionStart(), 0,
    1783     1637998 :                             code->constant_pool(), return_sp, frame->fp());
    1784             :       }
    1785             : 
    1786             :       case StackFrame::BUILTIN:
    1787             :         // For builtin frames we are guaranteed not to find a handler.
    1788           0 :         if (catchable_by_js) {
    1789           0 :           CHECK_EQ(-1,
    1790             :                    JavaScriptFrame::cast(frame)->LookupExceptionHandlerInTable(
    1791             :                        nullptr, nullptr));
    1792             :         }
    1793             :         break;
    1794             : 
    1795             :       case StackFrame::WASM_INTERPRETER_ENTRY: {
    1796        1761 :         if (trap_handler::IsThreadInWasm()) {
    1797             :           trap_handler::ClearThreadInWasm();
    1798             :         }
    1799             :       } break;
    1800             : 
    1801             :       case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH: {
    1802             :         // Builtin continuation frames with catch can handle exceptions.
    1803           8 :         if (!catchable_by_js) break;
    1804             :         JavaScriptBuiltinContinuationWithCatchFrame* js_frame =
    1805             :             JavaScriptBuiltinContinuationWithCatchFrame::cast(frame);
    1806           8 :         js_frame->SetException(exception);
    1807             : 
    1808             :         // Reconstruct the stack pointer from the frame pointer.
    1809           8 :         Address return_sp = js_frame->fp() - js_frame->GetSPToFPDelta();
    1810           8 :         Code code = js_frame->LookupCode();
    1811             :         return FoundHandler(Context(), code->InstructionStart(), 0,
    1812           8 :                             code->constant_pool(), return_sp, frame->fp());
    1813             :       } break;
    1814             : 
    1815             :       default:
    1816             :         // All other types can not handle exception.
    1817             :         break;
    1818             :     }
    1819             : 
    1820    21529015 :     if (frame->is_optimized()) {
    1821             :       // Remove per-frame stored materialized objects.
    1822     3006050 :       bool removed = materialized_object_store_->Remove(frame->fp());
    1823             :       USE(removed);
    1824             :       // If there were any materialized objects, the code should be
    1825             :       // marked for deopt.
    1826             :       DCHECK_IMPLIES(removed, frame->LookupCode()->marked_for_deoptimization());
    1827             :     }
    1828             :   }
    1829             : 
    1830             :   UNREACHABLE();
    1831             : }
    1832             : 
    1833             : namespace {
    1834      310340 : HandlerTable::CatchPrediction PredictException(JavaScriptFrame* frame) {
    1835             :   HandlerTable::CatchPrediction prediction;
    1836      620680 :   if (frame->is_optimized()) {
    1837       45542 :     if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) {
    1838             :       // This optimized frame will catch. It's handler table does not include
    1839             :       // exception prediction, and we need to use the corresponding handler
    1840             :       // tables on the unoptimized code objects.
    1841         101 :       std::vector<FrameSummary> summaries;
    1842        1366 :       frame->Summarize(&summaries);
    1843        1582 :       for (size_t i = summaries.size(); i != 0; i--) {
    1844        1373 :         const FrameSummary& summary = summaries[i - 1];
    1845             :         Handle<AbstractCode> code = summary.AsJavaScript().abstract_code();
    1846        1875 :         if (code->IsCode() && code->kind() == AbstractCode::BUILTIN) {
    1847         502 :           prediction = code->GetCode()->GetBuiltinCatchPrediction();
    1848         610 :           if (prediction == HandlerTable::UNCAUGHT) continue;
    1849        1265 :           return prediction;
    1850             :         }
    1851             : 
    1852             :         // Must have been constructed from a bytecode array.
    1853         871 :         CHECK_EQ(AbstractCode::INTERPRETED_FUNCTION, code->kind());
    1854         871 :         int code_offset = summary.code_offset();
    1855         871 :         HandlerTable table(code->GetBytecodeArray());
    1856         871 :         int index = table.LookupRange(code_offset, nullptr, &prediction);
    1857         871 :         if (index <= 0) continue;
    1858         864 :         if (prediction == HandlerTable::UNCAUGHT) continue;
    1859             :         return prediction;
    1860             :       }
    1861             :     }
    1862      264798 :   } else if (frame->LookupExceptionHandlerInTable(nullptr, &prediction) > 0) {
    1863        6149 :     return prediction;
    1864             :   }
    1865             :   return HandlerTable::UNCAUGHT;
    1866             : }
    1867             : 
    1868      159666 : Isolate::CatchType ToCatchType(HandlerTable::CatchPrediction prediction) {
    1869      159666 :   switch (prediction) {
    1870             :     case HandlerTable::UNCAUGHT:
    1871             :       return Isolate::NOT_CAUGHT;
    1872             :     case HandlerTable::CAUGHT:
    1873        2429 :       return Isolate::CAUGHT_BY_JAVASCRIPT;
    1874             :     case HandlerTable::PROMISE:
    1875        1261 :       return Isolate::CAUGHT_BY_PROMISE;
    1876             :     case HandlerTable::DESUGARING:
    1877           0 :       return Isolate::CAUGHT_BY_DESUGARING;
    1878             :     case HandlerTable::ASYNC_AWAIT:
    1879        2102 :       return Isolate::CAUGHT_BY_ASYNC_AWAIT;
    1880             :     default:
    1881           0 :       UNREACHABLE();
    1882             :   }
    1883             : }
    1884             : }  // anonymous namespace
    1885             : 
    1886        6283 : Isolate::CatchType Isolate::PredictExceptionCatcher() {
    1887             :   Address external_handler = thread_local_top()->try_catch_handler_address();
    1888        6283 :   if (IsExternalHandlerOnTop(Object())) return CAUGHT_BY_EXTERNAL;
    1889             : 
    1890             :   // Search for an exception handler by performing a full walk over the stack.
    1891      172786 :   for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) {
    1892             :     StackFrame* frame = iter.frame();
    1893             : 
    1894      172454 :     switch (frame->type()) {
    1895             :       case StackFrame::ENTRY:
    1896             :       case StackFrame::CONSTRUCT_ENTRY: {
    1897             :         Address entry_handler = frame->top_handler()->next_address();
    1898             :         // The exception has been externally caught if and only if there is an
    1899             :         // external handler which is on top of the top-most JS_ENTRY handler.
    1900         857 :         if (external_handler != kNullAddress &&
    1901         351 :             !try_catch_handler()->is_verbose_) {
    1902         256 :           if (entry_handler == kNullAddress ||
    1903         128 :               entry_handler > external_handler) {
    1904             :             return CAUGHT_BY_EXTERNAL;
    1905             :           }
    1906             :         }
    1907             :       } break;
    1908             : 
    1909             :       // For JavaScript frames we perform a lookup in the handler table.
    1910             :       case StackFrame::OPTIMIZED:
    1911             :       case StackFrame::INTERPRETED:
    1912             :       case StackFrame::BUILTIN: {
    1913             :         JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
    1914      158756 :         Isolate::CatchType prediction = ToCatchType(PredictException(js_frame));
    1915      158756 :         if (prediction == NOT_CAUGHT) break;
    1916             :         return prediction;
    1917             :       } break;
    1918             : 
    1919             :       case StackFrame::STUB: {
    1920        5296 :         Handle<Code> code(frame->LookupCode(), this);
    1921       11502 :         if (!code->IsCode() || code->kind() != Code::BUILTIN ||
    1922        7116 :             !code->has_handler_table() || !code->is_turbofanned()) {
    1923             :           break;
    1924             :         }
    1925             : 
    1926         910 :         CatchType prediction = ToCatchType(code->GetBuiltinCatchPrediction());
    1927         910 :         if (prediction != NOT_CAUGHT) return prediction;
    1928             :       } break;
    1929             : 
    1930             :       case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH: {
    1931           0 :         Handle<Code> code(frame->LookupCode(), this);
    1932           0 :         CatchType prediction = ToCatchType(code->GetBuiltinCatchPrediction());
    1933           0 :         if (prediction != NOT_CAUGHT) return prediction;
    1934             :       } break;
    1935             : 
    1936             :       default:
    1937             :         // All other types can not handle exception.
    1938             :         break;
    1939             :     }
    1940             :   }
    1941             : 
    1942             :   // Handler not found.
    1943         332 :   return NOT_CAUGHT;
    1944             : }
    1945             : 
    1946           5 : Object Isolate::ThrowIllegalOperation() {
    1947           5 :   if (FLAG_stack_trace_on_illegal) PrintStack(stdout);
    1948           5 :   return Throw(ReadOnlyRoots(heap()).illegal_access_string());
    1949             : }
    1950             : 
    1951       30048 : void Isolate::ScheduleThrow(Object exception) {
    1952             :   // When scheduling a throw we first throw the exception to get the
    1953             :   // error reporting if it is uncaught before rescheduling it.
    1954       30048 :   Throw(exception);
    1955       30048 :   PropagatePendingExceptionToExternalTryCatch();
    1956       30048 :   if (has_pending_exception()) {
    1957       30048 :     thread_local_top()->scheduled_exception_ = pending_exception();
    1958       30048 :     thread_local_top()->external_caught_exception_ = false;
    1959             :     clear_pending_exception();
    1960             :   }
    1961       30048 : }
    1962             : 
    1963         121 : void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) {
    1964             :   DCHECK(handler == try_catch_handler());
    1965             :   DCHECK(handler->HasCaught());
    1966             :   DCHECK(handler->rethrow_);
    1967             :   DCHECK(handler->capture_message_);
    1968         121 :   Object message(reinterpret_cast<Address>(handler->message_obj_));
    1969             :   DCHECK(message->IsJSMessageObject() || message->IsTheHole(this));
    1970         121 :   thread_local_top()->pending_message_obj_ = message;
    1971         121 : }
    1972             : 
    1973             : 
    1974         273 : void Isolate::CancelScheduledExceptionFromTryCatch(v8::TryCatch* handler) {
    1975             :   DCHECK(has_scheduled_exception());
    1976         546 :   if (reinterpret_cast<void*>(scheduled_exception().ptr()) ==
    1977         273 :       handler->exception_) {
    1978             :     DCHECK_NE(scheduled_exception(),
    1979             :               ReadOnlyRoots(heap()).termination_exception());
    1980             :     clear_scheduled_exception();
    1981             :   } else {
    1982             :     DCHECK_EQ(scheduled_exception(),
    1983             :               ReadOnlyRoots(heap()).termination_exception());
    1984             :     // Clear termination once we returned from all V8 frames.
    1985         183 :     if (handle_scope_implementer()->CallDepthIsZero()) {
    1986         133 :       thread_local_top()->external_caught_exception_ = false;
    1987             :       clear_scheduled_exception();
    1988             :     }
    1989             :   }
    1990         546 :   if (reinterpret_cast<void*>(thread_local_top()->pending_message_obj_.ptr()) ==
    1991         273 :       handler->message_obj_) {
    1992             :     clear_pending_message();
    1993             :   }
    1994         273 : }
    1995             : 
    1996       31576 : Object Isolate::PromoteScheduledException() {
    1997             :   Object thrown = scheduled_exception();
    1998             :   clear_scheduled_exception();
    1999             :   // Re-throw the exception to avoid getting repeated error reporting.
    2000       31576 :   return ReThrow(thrown);
    2001             : }
    2002             : 
    2003           0 : void Isolate::PrintCurrentStackTrace(FILE* out) {
    2004           0 :   IncrementalStringBuilder builder(this);
    2005           0 :   for (StackTraceFrameIterator it(this); !it.done(); it.Advance()) {
    2006           0 :     if (!it.is_javascript()) continue;
    2007             : 
    2008             :     HandleScope scope(this);
    2009             :     JavaScriptFrame* frame = it.javascript_frame();
    2010             : 
    2011           0 :     Handle<Object> receiver(frame->receiver(), this);
    2012           0 :     Handle<JSFunction> function(frame->function(), this);
    2013             :     Handle<AbstractCode> code;
    2014             :     int offset;
    2015           0 :     if (frame->is_interpreted()) {
    2016             :       InterpretedFrame* interpreted_frame = InterpretedFrame::cast(frame);
    2017           0 :       code = handle(AbstractCode::cast(interpreted_frame->GetBytecodeArray()),
    2018             :                     this);
    2019           0 :       offset = interpreted_frame->GetBytecodeOffset();
    2020             :     } else {
    2021           0 :       code = handle(AbstractCode::cast(frame->LookupCode()), this);
    2022           0 :       offset = static_cast<int>(frame->pc() - code->InstructionStart());
    2023             :     }
    2024             : 
    2025             :     // To preserve backwards compatiblity, only append a newline when
    2026             :     // the current stringified frame actually has characters.
    2027           0 :     const int old_length = builder.Length();
    2028           0 :     JSStackFrame site(this, receiver, function, code, offset);
    2029           0 :     site.ToString(builder);
    2030           0 :     if (old_length != builder.Length()) builder.AppendCharacter('\n');
    2031             :   }
    2032             : 
    2033           0 :   Handle<String> stack_trace = builder.Finish().ToHandleChecked();
    2034           0 :   stack_trace->PrintOn(out);
    2035           0 : }
    2036             : 
    2037      978234 : bool Isolate::ComputeLocation(MessageLocation* target) {
    2038      978234 :   StackTraceFrameIterator it(this);
    2039      978234 :   if (it.done()) return false;
    2040             :   StandardFrame* frame = it.frame();
    2041             :   // Compute the location from the function and the relocation info of the
    2042             :   // baseline code. For optimized code this will use the deoptimization
    2043             :   // information to get canonical location information.
    2044      970365 :   std::vector<FrameSummary> frames;
    2045      970365 :   frame->Summarize(&frames);
    2046             :   FrameSummary& summary = frames.back();
    2047      970365 :   int pos = summary.SourcePosition();
    2048             :   Handle<SharedFunctionInfo> shared;
    2049      970365 :   Handle<Object> script = summary.script();
    2050     1940414 :   if (!script->IsScript() ||
    2051             :       (Script::cast(*script)->source()->IsUndefined(this))) {
    2052             :     return false;
    2053             :   }
    2054             : 
    2055      970049 :   if (summary.IsJavaScript()) {
    2056      820026 :     shared = handle(summary.AsJavaScript().function()->shared(), this);
    2057             :   }
    2058      970049 :   *target = MessageLocation(Handle<Script>::cast(script), pos, pos + 1, shared);
    2059      970049 :   return true;
    2060             : }
    2061             : 
    2062        4562 : bool Isolate::ComputeLocationFromException(MessageLocation* target,
    2063             :                                            Handle<Object> exception) {
    2064        4562 :   if (!exception->IsJSObject()) return false;
    2065             : 
    2066             :   Handle<Name> start_pos_symbol = factory()->error_start_pos_symbol();
    2067             :   Handle<Object> start_pos = JSReceiver::GetDataProperty(
    2068        2629 :       Handle<JSObject>::cast(exception), start_pos_symbol);
    2069        2629 :   if (!start_pos->IsSmi()) return false;
    2070             :   int start_pos_value = Handle<Smi>::cast(start_pos)->value();
    2071             : 
    2072             :   Handle<Name> end_pos_symbol = factory()->error_end_pos_symbol();
    2073             :   Handle<Object> end_pos = JSReceiver::GetDataProperty(
    2074          15 :       Handle<JSObject>::cast(exception), end_pos_symbol);
    2075          15 :   if (!end_pos->IsSmi()) return false;
    2076             :   int end_pos_value = Handle<Smi>::cast(end_pos)->value();
    2077             : 
    2078             :   Handle<Name> script_symbol = factory()->error_script_symbol();
    2079             :   Handle<Object> script = JSReceiver::GetDataProperty(
    2080          15 :       Handle<JSObject>::cast(exception), script_symbol);
    2081          15 :   if (!script->IsScript()) return false;
    2082             : 
    2083             :   Handle<Script> cast_script(Script::cast(*script), this);
    2084          15 :   *target = MessageLocation(cast_script, start_pos_value, end_pos_value);
    2085          15 :   return true;
    2086             : }
    2087             : 
    2088             : 
    2089        4583 : bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target,
    2090             :                                             Handle<Object> exception) {
    2091        4583 :   if (!exception->IsJSObject()) return false;
    2092             :   Handle<Name> key = factory()->stack_trace_symbol();
    2093             :   Handle<Object> property =
    2094        2650 :       JSReceiver::GetDataProperty(Handle<JSObject>::cast(exception), key);
    2095        2650 :   if (!property->IsJSArray()) return false;
    2096             :   Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property);
    2097             : 
    2098             :   Handle<FrameArray> elements(FrameArray::cast(simple_stack_trace->elements()),
    2099             :                               this);
    2100             : 
    2101             :   const int frame_count = elements->FrameCount();
    2102        3217 :   for (int i = 0; i < frame_count; i++) {
    2103        3072 :     if (elements->IsWasmFrame(i) || elements->IsAsmJsWasmFrame(i)) {
    2104          96 :       Handle<WasmInstanceObject> instance(elements->WasmInstance(i), this);
    2105             :       uint32_t func_index =
    2106          96 :           static_cast<uint32_t>(elements->WasmFunctionIndex(i)->value());
    2107             :       wasm::WasmCode* wasm_code = reinterpret_cast<wasm::WasmCode*>(
    2108          96 :           elements->WasmCodeObject(i)->foreign_address());
    2109          96 :       int code_offset = elements->Offset(i)->value();
    2110             :       bool is_at_number_conversion =
    2111         144 :           elements->IsAsmJsWasmFrame(i) &&
    2112          48 :           elements->Flags(i)->value() & FrameArray::kAsmJsAtNumberConversion;
    2113             :       int byte_offset =
    2114             :           FrameSummary::WasmCompiledFrameSummary::GetWasmSourcePosition(
    2115          48 :               wasm_code, code_offset);
    2116          48 :       int pos = WasmModuleObject::GetSourcePosition(
    2117             :           handle(instance->module_object(), this), func_index, byte_offset,
    2118          48 :           is_at_number_conversion);
    2119             :       Handle<Script> script(instance->module_object()->script(), this);
    2120             : 
    2121          48 :       *target = MessageLocation(script, pos, pos + 1);
    2122             :       return true;
    2123             :     }
    2124             : 
    2125        1488 :     Handle<JSFunction> fun = handle(elements->Function(i), this);
    2126        1060 :     if (!fun->shared()->IsSubjectToDebugging()) continue;
    2127             : 
    2128         428 :     Object script = fun->shared()->script();
    2129         856 :     if (script->IsScript() &&
    2130             :         !(Script::cast(script)->source()->IsUndefined(this))) {
    2131         428 :       AbstractCode abstract_code = elements->Code(i);
    2132         856 :       const int code_offset = elements->Offset(i)->value();
    2133         428 :       const int pos = abstract_code->SourcePosition(code_offset);
    2134             : 
    2135             :       Handle<Script> casted_script(Script::cast(script), this);
    2136         428 :       *target = MessageLocation(casted_script, pos, pos + 1);
    2137             :       return true;
    2138             :     }
    2139             :   }
    2140             :   return false;
    2141             : }
    2142             : 
    2143             : 
    2144     1359008 : Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception,
    2145             :                                                MessageLocation* location) {
    2146             :   Handle<FixedArray> stack_trace_object;
    2147     1359008 :   if (capture_stack_trace_for_uncaught_exceptions_) {
    2148         452 :     if (exception->IsJSError()) {
    2149             :       // We fetch the stack trace that corresponds to this error object.
    2150             :       // If the lookup fails, the exception is probably not a valid Error
    2151             :       // object. In that case, we fall through and capture the stack trace
    2152             :       // at this throw site.
    2153             :       stack_trace_object =
    2154         271 :           GetDetailedStackTrace(Handle<JSObject>::cast(exception));
    2155             :     }
    2156         452 :     if (stack_trace_object.is_null()) {
    2157             :       // Not an error object, we capture stack and location at throw site.
    2158             :       stack_trace_object = CaptureCurrentStackTrace(
    2159             :           stack_trace_for_uncaught_exceptions_frame_limit_,
    2160         186 :           stack_trace_for_uncaught_exceptions_options_);
    2161             :     }
    2162             :   }
    2163     1359008 :   MessageLocation computed_location;
    2164     2722578 :   if (location == nullptr &&
    2165        9109 :       (ComputeLocationFromException(&computed_location, exception) ||
    2166        8654 :        ComputeLocationFromStackTrace(&computed_location, exception) ||
    2167        4107 :        ComputeLocation(&computed_location))) {
    2168             :     location = &computed_location;
    2169             :   }
    2170             : 
    2171             :   return MessageHandler::MakeMessageObject(
    2172             :       this, MessageTemplate::kUncaughtException, location, exception,
    2173     1359008 :       stack_trace_object);
    2174             : }
    2175             : 
    2176           0 : bool Isolate::IsJavaScriptHandlerOnTop(Object exception) {
    2177             :   DCHECK_NE(ReadOnlyRoots(heap()).the_hole_value(), exception);
    2178             : 
    2179             :   // For uncatchable exceptions, the JavaScript handler cannot be on top.
    2180      169348 :   if (!is_catchable_by_javascript(exception)) return false;
    2181             : 
    2182             :   // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist.
    2183             :   Address entry_handler = Isolate::handler(thread_local_top());
    2184      165055 :   if (entry_handler == kNullAddress) return false;
    2185             : 
    2186             :   // Get the address of the external handler so we can compare the address to
    2187             :   // determine which one is closer to the top of the stack.
    2188             :   Address external_handler = thread_local_top()->try_catch_handler_address();
    2189      147375 :   if (external_handler == kNullAddress) return true;
    2190             : 
    2191             :   // The exception has been externally caught if and only if there is an
    2192             :   // external handler which is on top of the top-most JS_ENTRY handler.
    2193             :   //
    2194             :   // Note, that finally clauses would re-throw an exception unless it's aborted
    2195             :   // by jumps in control flow (like return, break, etc.) and we'll have another
    2196             :   // chance to set proper v8::TryCatch later.
    2197      146007 :   return (entry_handler < external_handler);
    2198             : }
    2199             : 
    2200           0 : bool Isolate::IsExternalHandlerOnTop(Object exception) {
    2201             :   DCHECK_NE(ReadOnlyRoots(heap()).the_hole_value(), exception);
    2202             : 
    2203             :   // Get the address of the external handler so we can compare the address to
    2204             :   // determine which one is closer to the top of the stack.
    2205             :   Address external_handler = thread_local_top()->try_catch_handler_address();
    2206       52303 :   if (external_handler == kNullAddress) return false;
    2207             : 
    2208             :   // For uncatchable exceptions, the external handler is always on top.
    2209       45364 :   if (!is_catchable_by_javascript(exception)) return true;
    2210             : 
    2211             :   // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist.
    2212             :   Address entry_handler = Isolate::handler(thread_local_top());
    2213       41950 :   if (entry_handler == kNullAddress) return true;
    2214             : 
    2215             :   // The exception has been externally caught if and only if there is an
    2216             :   // external handler which is on top of the top-most JS_ENTRY handler.
    2217             :   //
    2218             :   // Note, that finally clauses would re-throw an exception unless it's aborted
    2219             :   // by jumps in control flow (like return, break, etc.) and we'll have another
    2220             :   // chance to set proper v8::TryCatch later.
    2221       20121 :   return (entry_handler > external_handler);
    2222             : }
    2223             : 
    2224       15107 : void Isolate::ReportPendingMessagesImpl(bool report_externally) {
    2225             :   Object exception = pending_exception();
    2226             : 
    2227             :   // Clear the pending message object early to avoid endless recursion.
    2228       15107 :   Object message_obj = thread_local_top()->pending_message_obj_;
    2229             :   clear_pending_message();
    2230             : 
    2231             :   // For uncatchable exceptions we do nothing. If needed, the exception and the
    2232             :   // message have already been propagated to v8::TryCatch.
    2233       15107 :   if (!is_catchable_by_javascript(exception)) return;
    2234             : 
    2235             :   // Determine whether the message needs to be reported to all message handlers
    2236             :   // depending on whether and external v8::TryCatch or an internal JavaScript
    2237             :   // handler is on top.
    2238             :   bool should_report_exception;
    2239       12336 :   if (report_externally) {
    2240             :     // Only report the exception if the external handler is verbose.
    2241       11377 :     should_report_exception = try_catch_handler()->is_verbose_;
    2242             :   } else {
    2243             :     // Report the exception if it isn't caught by JavaScript code.
    2244         959 :     should_report_exception = !IsJavaScriptHandlerOnTop(exception);
    2245             :   }
    2246             : 
    2247             :   // Actually report the pending message to all message handlers.
    2248       12336 :   if (!message_obj->IsTheHole(this) && should_report_exception) {
    2249             :     HandleScope scope(this);
    2250             :     Handle<JSMessageObject> message(JSMessageObject::cast(message_obj), this);
    2251             :     Handle<Script> script(message->script(), this);
    2252             :     int start_pos = message->start_position();
    2253             :     int end_pos = message->end_position();
    2254        8019 :     MessageLocation location(script, start_pos, end_pos);
    2255        8019 :     MessageHandler::ReportMessage(this, &location, message);
    2256             :   }
    2257             : }
    2258             : 
    2259      121345 : void Isolate::ReportPendingMessages() {
    2260             :   DCHECK(AllowExceptions::IsAllowed(this));
    2261             : 
    2262             :   // The embedder might run script in response to an exception.
    2263             :   AllowJavascriptExecutionDebugOnly allow_script(this);
    2264             : 
    2265             :   Object exception = pending_exception();
    2266             : 
    2267             :   // Try to propagate the exception to an external v8::TryCatch handler. If
    2268             :   // propagation was unsuccessful, then we will get another chance at reporting
    2269             :   // the pending message if the exception is re-thrown.
    2270      121345 :   bool has_been_propagated = PropagatePendingExceptionToExternalTryCatch();
    2271      121345 :   if (!has_been_propagated) return;
    2272             : 
    2273       15107 :   ReportPendingMessagesImpl(IsExternalHandlerOnTop(exception));
    2274             : }
    2275             : 
    2276          33 : void Isolate::ReportPendingMessagesFromJavaScript() {
    2277             :   DCHECK(AllowExceptions::IsAllowed(this));
    2278             : 
    2279             :   auto IsHandledByJavaScript = [=]() {
    2280             :     // In this situation, the exception is always a non-terminating exception.
    2281             : 
    2282             :     // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist.
    2283          33 :     Address entry_handler = Isolate::handler(thread_local_top());
    2284             :     DCHECK_NE(entry_handler, kNullAddress);
    2285             :     entry_handler = StackHandler::FromAddress(entry_handler)->next_address();
    2286             : 
    2287             :     // Get the address of the external handler so we can compare the address to
    2288             :     // determine which one is closer to the top of the stack.
    2289             :     Address external_handler = thread_local_top()->try_catch_handler_address();
    2290          33 :     if (external_handler == kNullAddress) return true;
    2291             : 
    2292          33 :     return (entry_handler < external_handler);
    2293             :   };
    2294             : 
    2295             :   auto IsHandledExternally = [=]() {
    2296           0 :     Address external_handler = thread_local_top()->try_catch_handler_address();
    2297           0 :     if (external_handler == kNullAddress) return false;
    2298             : 
    2299             :     // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist.
    2300             :     Address entry_handler = Isolate::handler(thread_local_top());
    2301             :     DCHECK_NE(entry_handler, kNullAddress);
    2302             :     entry_handler = StackHandler::FromAddress(entry_handler)->next_address();
    2303           0 :     return (entry_handler > external_handler);
    2304             :   };
    2305             : 
    2306          33 :   auto PropagateToExternalHandler = [=]() {
    2307          33 :     if (IsHandledByJavaScript()) {
    2308          33 :       thread_local_top()->external_caught_exception_ = false;
    2309          33 :       return false;
    2310             :     }
    2311             : 
    2312           0 :     if (!IsHandledExternally()) {
    2313           0 :       thread_local_top()->external_caught_exception_ = false;
    2314           0 :       return true;
    2315             :     }
    2316             : 
    2317           0 :     thread_local_top()->external_caught_exception_ = true;
    2318             :     v8::TryCatch* handler = try_catch_handler();
    2319             :     DCHECK(thread_local_top()->pending_message_obj_->IsJSMessageObject() ||
    2320             :            thread_local_top()->pending_message_obj_->IsTheHole(this));
    2321           0 :     handler->can_continue_ = true;
    2322           0 :     handler->has_terminated_ = false;
    2323           0 :     handler->exception_ = reinterpret_cast<void*>(pending_exception().ptr());
    2324             :     // Propagate to the external try-catch only if we got an actual message.
    2325           0 :     if (thread_local_top()->pending_message_obj_->IsTheHole(this)) return true;
    2326             : 
    2327             :     handler->message_obj_ =
    2328           0 :         reinterpret_cast<void*>(thread_local_top()->pending_message_obj_.ptr());
    2329           0 :     return true;
    2330          33 :   };
    2331             : 
    2332             :   // Try to propagate to an external v8::TryCatch handler.
    2333          66 :   if (!PropagateToExternalHandler()) return;
    2334             : 
    2335           0 :   ReportPendingMessagesImpl(true);
    2336             : }
    2337             : 
    2338           0 : MessageLocation Isolate::GetMessageLocation() {
    2339             :   DCHECK(has_pending_exception());
    2340             : 
    2341           0 :   if (thread_local_top()->pending_exception_ !=
    2342           0 :           ReadOnlyRoots(heap()).termination_exception() &&
    2343             :       !thread_local_top()->pending_message_obj_->IsTheHole(this)) {
    2344             :     Handle<JSMessageObject> message_obj(
    2345             :         JSMessageObject::cast(thread_local_top()->pending_message_obj_), this);
    2346             :     Handle<Script> script(message_obj->script(), this);
    2347             :     int start_pos = message_obj->start_position();
    2348             :     int end_pos = message_obj->end_position();
    2349           0 :     return MessageLocation(script, start_pos, end_pos);
    2350             :   }
    2351             : 
    2352           0 :   return MessageLocation();
    2353             : }
    2354             : 
    2355       16996 : bool Isolate::OptionalRescheduleException(bool clear_exception) {
    2356             :   DCHECK(has_pending_exception());
    2357       16996 :   PropagatePendingExceptionToExternalTryCatch();
    2358             : 
    2359             :   bool is_termination_exception =
    2360             :       pending_exception() == ReadOnlyRoots(this).termination_exception();
    2361             : 
    2362       16996 :   if (is_termination_exception) {
    2363        1522 :     if (clear_exception) {
    2364        1080 :       thread_local_top()->external_caught_exception_ = false;
    2365             :       clear_pending_exception();
    2366        1080 :       return false;
    2367             :     }
    2368       15474 :   } else if (thread_local_top()->external_caught_exception_) {
    2369             :     // If the exception is externally caught, clear it if there are no
    2370             :     // JavaScript frames on the way to the C++ frame that has the
    2371             :     // external handler.
    2372             :     DCHECK_NE(thread_local_top()->try_catch_handler_address(), kNullAddress);
    2373             :     Address external_handler_address =
    2374             :         thread_local_top()->try_catch_handler_address();
    2375       12945 :     JavaScriptFrameIterator it(this);
    2376       12945 :     if (it.done() || (it.frame()->sp() > external_handler_address)) {
    2377             :       clear_exception = true;
    2378             :     }
    2379             :   }
    2380             : 
    2381             :   // Clear the exception if needed.
    2382       15916 :   if (clear_exception) {
    2383       14042 :     thread_local_top()->external_caught_exception_ = false;
    2384             :     clear_pending_exception();
    2385       14042 :     return false;
    2386             :   }
    2387             : 
    2388             :   // Reschedule the exception.
    2389        1874 :   thread_local_top()->scheduled_exception_ = pending_exception();
    2390             :   clear_pending_exception();
    2391        1874 :   return true;
    2392             : }
    2393             : 
    2394       17420 : void Isolate::PushPromise(Handle<JSObject> promise) {
    2395             :   ThreadLocalTop* tltop = thread_local_top();
    2396       17420 :   PromiseOnStack* prev = tltop->promise_on_stack_;
    2397             :   Handle<JSObject> global_promise = global_handles()->Create(*promise);
    2398       34840 :   tltop->promise_on_stack_ = new PromiseOnStack(global_promise, prev);
    2399       17420 : }
    2400             : 
    2401             : 
    2402       17440 : void Isolate::PopPromise() {
    2403             :   ThreadLocalTop* tltop = thread_local_top();
    2404       17440 :   if (tltop->promise_on_stack_ == nullptr) return;
    2405             :   PromiseOnStack* prev = tltop->promise_on_stack_->prev();
    2406             :   Handle<Object> global_promise = tltop->promise_on_stack_->promise();
    2407       17420 :   delete tltop->promise_on_stack_;
    2408       17420 :   tltop->promise_on_stack_ = prev;
    2409       17420 :   global_handles()->Destroy(global_promise.location());
    2410             : }
    2411             : 
    2412             : namespace {
    2413             : bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate,
    2414             :                                                 Handle<JSPromise> promise);
    2415             : 
    2416         985 : bool PromiseHandlerCheck(Isolate* isolate, Handle<JSReceiver> handler,
    2417             :                          Handle<JSReceiver> deferred_promise) {
    2418             :   // Recurse to the forwarding Promise, if any. This may be due to
    2419             :   //  - await reaction forwarding to the throwaway Promise, which has
    2420             :   //    a dependency edge to the outer Promise.
    2421             :   //  - PromiseIdResolveHandler forwarding to the output of .then
    2422             :   //  - Promise.all/Promise.race forwarding to a throwaway Promise, which
    2423             :   //    has a dependency edge to the generated outer Promise.
    2424             :   // Otherwise, this is a real reject handler for the Promise.
    2425             :   Handle<Symbol> key = isolate->factory()->promise_forwarding_handler_symbol();
    2426         985 :   Handle<Object> forwarding_handler = JSReceiver::GetDataProperty(handler, key);
    2427         985 :   if (forwarding_handler->IsUndefined(isolate)) {
    2428             :     return true;
    2429             :   }
    2430             : 
    2431         365 :   if (!deferred_promise->IsJSPromise()) {
    2432             :     return true;
    2433             :   }
    2434             : 
    2435             :   return InternalPromiseHasUserDefinedRejectHandler(
    2436         365 :       isolate, Handle<JSPromise>::cast(deferred_promise));
    2437             : }
    2438             : 
    2439        4876 : bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate,
    2440             :                                                 Handle<JSPromise> promise) {
    2441             :   // If this promise was marked as being handled by a catch block
    2442             :   // in an async function, then it has a user-defined reject handler.
    2443        4876 :   if (promise->handled_hint()) return true;
    2444             : 
    2445             :   // If this Promise is subsumed by another Promise (a Promise resolved
    2446             :   // with another Promise, or an intermediate, hidden, throwaway Promise
    2447             :   // within async/await), then recurse on the outer Promise.
    2448             :   // In this case, the dependency is one possible way that the Promise
    2449             :   // could be resolved, so it does not subsume the other following cases.
    2450             :   Handle<Symbol> key = isolate->factory()->promise_handled_by_symbol();
    2451        4330 :   Handle<Object> outer_promise_obj = JSObject::GetDataProperty(promise, key);
    2452        5333 :   if (outer_promise_obj->IsJSPromise() &&
    2453        1003 :       InternalPromiseHasUserDefinedRejectHandler(
    2454             :           isolate, Handle<JSPromise>::cast(outer_promise_obj))) {
    2455             :     return true;
    2456             :   }
    2457             : 
    2458        3608 :   if (promise->status() == Promise::kPending) {
    2459        3797 :     for (Handle<Object> current(promise->reactions(), isolate);
    2460             :          !current->IsSmi();) {
    2461             :       Handle<PromiseReaction> reaction = Handle<PromiseReaction>::cast(current);
    2462             :       Handle<HeapObject> promise_or_capability(
    2463             :           reaction->promise_or_capability(), isolate);
    2464        1076 :       if (!promise_or_capability->IsUndefined(isolate)) {
    2465             :         Handle<JSPromise> promise = Handle<JSPromise>::cast(
    2466             :             promise_or_capability->IsJSPromise()
    2467             :                 ? promise_or_capability
    2468             :                 : handle(Handle<PromiseCapability>::cast(promise_or_capability)
    2469             :                              ->promise(),
    2470        1076 :                          isolate));
    2471        1076 :         if (reaction->reject_handler()->IsUndefined(isolate)) {
    2472          91 :           if (InternalPromiseHasUserDefinedRejectHandler(isolate, promise)) {
    2473             :             return true;
    2474             :           }
    2475             :         } else {
    2476             :           Handle<JSReceiver> current_handler(
    2477             :               JSReceiver::cast(reaction->reject_handler()), isolate);
    2478         985 :           if (PromiseHandlerCheck(isolate, current_handler, promise)) {
    2479         805 :             return true;
    2480             :           }
    2481             :         }
    2482             :       }
    2483             :       current = handle(reaction->next(), isolate);
    2484             :     }
    2485             :   }
    2486             : 
    2487             :   return false;
    2488             : }
    2489             : 
    2490             : }  // namespace
    2491             : 
    2492        3417 : bool Isolate::PromiseHasUserDefinedRejectHandler(Handle<Object> promise) {
    2493        3417 :   if (!promise->IsJSPromise()) return false;
    2494             :   return InternalPromiseHasUserDefinedRejectHandler(
    2495        3417 :       this, Handle<JSPromise>::cast(promise));
    2496             : }
    2497             : 
    2498        4206 : Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
    2499             :   Handle<Object> undefined = factory()->undefined_value();
    2500             :   ThreadLocalTop* tltop = thread_local_top();
    2501        4206 :   if (tltop->promise_on_stack_ == nullptr) return undefined;
    2502             :   // Find the top-most try-catch or try-finally handler.
    2503        1593 :   CatchType prediction = PredictExceptionCatcher();
    2504        1593 :   if (prediction == NOT_CAUGHT || prediction == CAUGHT_BY_EXTERNAL) {
    2505           5 :     return undefined;
    2506             :   }
    2507             :   Handle<Object> retval = undefined;
    2508        1588 :   PromiseOnStack* promise_on_stack = tltop->promise_on_stack_;
    2509      156672 :   for (StackFrameIterator it(this); !it.done(); it.Advance()) {
    2510             :     StackFrame* frame = it.frame();
    2511             :     HandlerTable::CatchPrediction catch_prediction;
    2512      156262 :     if (frame->is_java_script()) {
    2513      151584 :       catch_prediction = PredictException(JavaScriptFrame::cast(frame));
    2514        4678 :     } else if (frame->type() == StackFrame::STUB) {
    2515        1621 :       Code code = frame->LookupCode();
    2516        3650 :       if (!code->IsCode() || code->kind() != Code::BUILTIN ||
    2517        2437 :           !code->has_handler_table() || !code->is_turbofanned()) {
    2518        1213 :         continue;
    2519             :       }
    2520         408 :       catch_prediction = code->GetBuiltinCatchPrediction();
    2521             :     } else {
    2522             :       continue;
    2523             :     }
    2524             : 
    2525      151992 :     switch (catch_prediction) {
    2526             :       case HandlerTable::UNCAUGHT:
    2527             :         continue;
    2528             :       case HandlerTable::CAUGHT:
    2529             :       case HandlerTable::DESUGARING:
    2530         462 :         if (retval->IsJSPromise()) {
    2531             :           // Caught the result of an inner async/await invocation.
    2532             :           // Mark the inner promise as caught in the "synchronous case" so
    2533             :           // that Debug::OnException will see. In the synchronous case,
    2534             :           // namely in the code in an async function before the first
    2535             :           // await, the function which has this exception event has not yet
    2536             :           // returned, so the generated Promise has not yet been marked
    2537             :           // by AsyncFunctionAwaitCaught with promiseHandledHintSymbol.
    2538         325 :           Handle<JSPromise>::cast(retval)->set_handled_hint(true);
    2539             :         }
    2540         462 :         return retval;
    2541             :       case HandlerTable::PROMISE:
    2542             :         return promise_on_stack
    2543             :                    ? Handle<Object>::cast(promise_on_stack->promise())
    2544         482 :                    : undefined;
    2545             :       case HandlerTable::ASYNC_AWAIT: {
    2546             :         // If in the initial portion of async/await, continue the loop to pop up
    2547             :         // successive async/await stack frames until an asynchronous one with
    2548             :         // dependents is found, or a non-async stack frame is encountered, in
    2549             :         // order to handle the synchronous async/await catch prediction case:
    2550             :         // assume that async function calls are awaited.
    2551        1474 :         if (!promise_on_stack) return retval;
    2552             :         retval = promise_on_stack->promise();
    2553        1474 :         if (PromiseHasUserDefinedRejectHandler(retval)) {
    2554         234 :           return retval;
    2555             :         }
    2556             :         promise_on_stack = promise_on_stack->prev();
    2557        1240 :         continue;
    2558             :       }
    2559             :     }
    2560             :   }
    2561         410 :   return retval;
    2562             : }
    2563             : 
    2564             : 
    2565        1371 : void Isolate::SetCaptureStackTraceForUncaughtExceptions(
    2566             :       bool capture,
    2567             :       int frame_limit,
    2568             :       StackTrace::StackTraceOptions options) {
    2569        1371 :   capture_stack_trace_for_uncaught_exceptions_ = capture;
    2570        1371 :   stack_trace_for_uncaught_exceptions_frame_limit_ = frame_limit;
    2571        1371 :   stack_trace_for_uncaught_exceptions_options_ = options;
    2572        1371 : }
    2573             : 
    2574             : 
    2575           5 : void Isolate::SetAbortOnUncaughtExceptionCallback(
    2576             :     v8::Isolate::AbortOnUncaughtExceptionCallback callback) {
    2577           5 :   abort_on_uncaught_exception_callback_ = callback;
    2578           5 : }
    2579             : 
    2580     1536548 : bool Isolate::AreWasmThreadsEnabled(Handle<Context> context) {
    2581     1536548 :   if (wasm_threads_enabled_callback()) {
    2582          42 :     v8::Local<v8::Context> api_context = v8::Utils::ToLocal(context);
    2583          42 :     return wasm_threads_enabled_callback()(api_context);
    2584             :   }
    2585     1536506 :   return FLAG_experimental_wasm_threads;
    2586             : }
    2587             : 
    2588           4 : Handle<Context> Isolate::GetIncumbentContext() {
    2589           4 :   JavaScriptFrameIterator it(this);
    2590             : 
    2591             :   // 1st candidate: most-recently-entered author function's context
    2592             :   // if it's newer than the last Context::BackupIncumbentScope entry.
    2593             :   //
    2594             :   // NOTE: This code assumes that the stack grows downward.
    2595             :   Address top_backup_incumbent =
    2596             :       top_backup_incumbent_scope()
    2597             :           ? top_backup_incumbent_scope()->JSStackComparableAddress()
    2598           4 :           : 0;
    2599           8 :   if (!it.done() &&
    2600           2 :       (!top_backup_incumbent || it.frame()->sp() < top_backup_incumbent)) {
    2601           4 :     Context context = Context::cast(it.frame()->context());
    2602           8 :     return Handle<Context>(context->native_context(), this);
    2603             :   }
    2604             : 
    2605             :   // 2nd candidate: the last Context::Scope's incumbent context if any.
    2606           0 :   if (top_backup_incumbent_scope()) {
    2607             :     return Utils::OpenHandle(
    2608             :         *top_backup_incumbent_scope()->backup_incumbent_context_);
    2609             :   }
    2610             : 
    2611             :   // Last candidate: the entered context or microtask context.
    2612             :   // Given that there is no other author function is running, there must be
    2613             :   // no cross-context function running, then the incumbent realm must match
    2614             :   // the entry realm.
    2615             :   v8::Local<v8::Context> entered_context =
    2616           0 :       reinterpret_cast<v8::Isolate*>(this)->GetEnteredOrMicrotaskContext();
    2617             :   return Utils::OpenHandle(*entered_context);
    2618             : }
    2619             : 
    2620       32437 : char* Isolate::ArchiveThread(char* to) {
    2621             :   MemCopy(to, reinterpret_cast<char*>(thread_local_top()),
    2622             :           sizeof(ThreadLocalTop));
    2623             :   InitializeThreadLocal();
    2624             :   clear_pending_exception();
    2625             :   clear_pending_message();
    2626             :   clear_scheduled_exception();
    2627       32437 :   return to + sizeof(ThreadLocalTop);
    2628             : }
    2629             : 
    2630             : 
    2631       32437 : char* Isolate::RestoreThread(char* from) {
    2632             :   MemCopy(reinterpret_cast<char*>(thread_local_top()), from,
    2633             :           sizeof(ThreadLocalTop));
    2634             : // This might be just paranoia, but it seems to be needed in case a
    2635             : // thread_local_top_ is restored on a separate OS thread.
    2636             : #ifdef USE_SIMULATOR
    2637             :   thread_local_top()->simulator_ = Simulator::current(this);
    2638             : #endif
    2639             :   DCHECK(context().is_null() || context()->IsContext());
    2640       32437 :   return from + sizeof(ThreadLocalTop);
    2641             : }
    2642             : 
    2643       61517 : void Isolate::ReleaseSharedPtrs() {
    2644       61517 :   base::MutexGuard lock(&managed_ptr_destructors_mutex_);
    2645       72991 :   while (managed_ptr_destructors_head_) {
    2646             :     ManagedPtrDestructor* l = managed_ptr_destructors_head_;
    2647             :     ManagedPtrDestructor* n = nullptr;
    2648       11472 :     managed_ptr_destructors_head_ = nullptr;
    2649      733414 :     for (; l != nullptr; l = n) {
    2650      360971 :       l->destructor_(l->shared_ptr_ptr_);
    2651      360971 :       n = l->next_;
    2652      360971 :       delete l;
    2653             :     }
    2654             :   }
    2655       61519 : }
    2656             : 
    2657     2961681 : void Isolate::RegisterManagedPtrDestructor(ManagedPtrDestructor* destructor) {
    2658     2961681 :   base::MutexGuard lock(&managed_ptr_destructors_mutex_);
    2659             :   DCHECK_NULL(destructor->prev_);
    2660             :   DCHECK_NULL(destructor->next_);
    2661     2961686 :   if (managed_ptr_destructors_head_) {
    2662     2948960 :     managed_ptr_destructors_head_->prev_ = destructor;
    2663             :   }
    2664     2961686 :   destructor->next_ = managed_ptr_destructors_head_;
    2665     2961686 :   managed_ptr_destructors_head_ = destructor;
    2666     2961686 : }
    2667             : 
    2668     2600715 : void Isolate::UnregisterManagedPtrDestructor(ManagedPtrDestructor* destructor) {
    2669     2600715 :   base::MutexGuard lock(&managed_ptr_destructors_mutex_);
    2670     2600715 :   if (destructor->prev_) {
    2671     2581649 :     destructor->prev_->next_ = destructor->next_;
    2672             :   } else {
    2673             :     DCHECK_EQ(destructor, managed_ptr_destructors_head_);
    2674       19066 :     managed_ptr_destructors_head_ = destructor->next_;
    2675             :   }
    2676     2600715 :   if (destructor->next_) destructor->next_->prev_ = destructor->prev_;
    2677     2600715 :   destructor->prev_ = nullptr;
    2678     2600715 :   destructor->next_ = nullptr;
    2679     2600715 : }
    2680             : 
    2681       61534 : void Isolate::SetWasmEngine(std::shared_ptr<wasm::WasmEngine> engine) {
    2682             :   DCHECK_NULL(wasm_engine_);  // Only call once before {Init}.
    2683             :   wasm_engine_ = std::move(engine);
    2684       61534 :   wasm_engine_->AddIsolate(this);
    2685       61534 : }
    2686             : 
    2687             : // NOLINTNEXTLINE
    2688       67054 : Isolate::PerIsolateThreadData::~PerIsolateThreadData() {
    2689             : #if defined(USE_SIMULATOR)
    2690             :   delete simulator_;
    2691             : #endif
    2692           0 : }
    2693             : 
    2694           0 : Isolate::PerIsolateThreadData* Isolate::ThreadDataTable::Lookup(
    2695             :     ThreadId thread_id) {
    2696             :   auto t = table_.find(thread_id);
    2697      366865 :   if (t == table_.end()) return nullptr;
    2698      293761 :   return t->second;
    2699             : }
    2700             : 
    2701             : 
    2702       67069 : void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) {
    2703      134137 :   bool inserted = table_.insert(std::make_pair(data->thread_id_, data)).second;
    2704       67068 :   CHECK(inserted);
    2705       67068 : }
    2706             : 
    2707             : 
    2708           0 : void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) {
    2709         500 :   table_.erase(data->thread_id_);
    2710        1000 :   delete data;
    2711           0 : }
    2712             : 
    2713       61519 : void Isolate::ThreadDataTable::RemoveAllThreads() {
    2714      128073 :   for (auto& x : table_) {
    2715      133108 :     delete x.second;
    2716             :   }
    2717             :   table_.clear();
    2718       61518 : }
    2719             : 
    2720           0 : class VerboseAccountingAllocator : public AccountingAllocator {
    2721             :  public:
    2722             :   VerboseAccountingAllocator(Heap* heap, size_t allocation_sample_bytes)
    2723           0 :       : heap_(heap), allocation_sample_bytes_(allocation_sample_bytes) {}
    2724             : 
    2725           0 :   v8::internal::Segment* AllocateSegment(size_t size) override {
    2726           0 :     v8::internal::Segment* memory = AccountingAllocator::AllocateSegment(size);
    2727           0 :     if (!memory) return nullptr;
    2728             :     size_t malloced_current = GetCurrentMemoryUsage();
    2729             : 
    2730           0 :     if (last_memory_usage_ + allocation_sample_bytes_ < malloced_current) {
    2731           0 :       PrintMemoryJSON(malloced_current);
    2732             :       last_memory_usage_ = malloced_current;
    2733             :     }
    2734             :     return memory;
    2735             :   }
    2736             : 
    2737           0 :   void ReturnSegment(v8::internal::Segment* memory) override {
    2738           0 :     AccountingAllocator::ReturnSegment(memory);
    2739             :     size_t malloced_current = GetCurrentMemoryUsage();
    2740             : 
    2741           0 :     if (malloced_current + allocation_sample_bytes_ < last_memory_usage_) {
    2742           0 :       PrintMemoryJSON(malloced_current);
    2743             :       last_memory_usage_ = malloced_current;
    2744             :     }
    2745           0 :   }
    2746             : 
    2747           0 :   void ZoneCreation(const Zone* zone) override {
    2748           0 :     PrintZoneModificationSample(zone, "zonecreation");
    2749             :     nesting_deepth_++;
    2750           0 :   }
    2751             : 
    2752           0 :   void ZoneDestruction(const Zone* zone) override {
    2753             :     nesting_deepth_--;
    2754           0 :     PrintZoneModificationSample(zone, "zonedestruction");
    2755           0 :   }
    2756             : 
    2757             :  private:
    2758           0 :   void PrintZoneModificationSample(const Zone* zone, const char* type) {
    2759             :     PrintF(
    2760             :         "{"
    2761             :         "\"type\": \"%s\", "
    2762             :         "\"isolate\": \"%p\", "
    2763             :         "\"time\": %f, "
    2764             :         "\"ptr\": \"%p\", "
    2765             :         "\"name\": \"%s\", "
    2766             :         "\"size\": %" PRIuS
    2767             :         ","
    2768             :         "\"nesting\": %zu}\n",
    2769           0 :         type, reinterpret_cast<void*>(heap_->isolate()),
    2770           0 :         heap_->isolate()->time_millis_since_init(),
    2771             :         reinterpret_cast<const void*>(zone), zone->name(),
    2772           0 :         zone->allocation_size(), nesting_deepth_.load());
    2773           0 :   }
    2774             : 
    2775           0 :   void PrintMemoryJSON(size_t malloced) {
    2776             :     // Note: Neither isolate, nor heap is locked, so be careful with accesses
    2777             :     // as the allocator is potentially used on a concurrent thread.
    2778           0 :     double time = heap_->isolate()->time_millis_since_init();
    2779             :     PrintF(
    2780             :         "{"
    2781             :         "\"type\": \"zone\", "
    2782             :         "\"isolate\": \"%p\", "
    2783             :         "\"time\": %f, "
    2784             :         "\"allocated\": %" PRIuS "}\n",
    2785           0 :         reinterpret_cast<void*>(heap_->isolate()), time, malloced);
    2786           0 :   }
    2787             : 
    2788             :   Heap* heap_;
    2789             :   std::atomic<size_t> last_memory_usage_{0};
    2790             :   std::atomic<size_t> nesting_deepth_{0};
    2791             :   size_t allocation_sample_bytes_;
    2792             : };
    2793             : 
    2794             : #ifdef DEBUG
    2795             : std::atomic<size_t> Isolate::non_disposed_isolates_;
    2796             : #endif  // DEBUG
    2797             : 
    2798             : // static
    2799       61528 : Isolate* Isolate::New(IsolateAllocationMode mode) {
    2800             :   // IsolateAllocator allocates the memory for the Isolate object according to
    2801             :   // the given allocation mode.
    2802             :   std::unique_ptr<IsolateAllocator> isolate_allocator =
    2803       61534 :       base::make_unique<IsolateAllocator>(mode);
    2804             :   // Construct Isolate object in the allocated memory.
    2805             :   void* isolate_ptr = isolate_allocator->isolate_memory();
    2806       61534 :   Isolate* isolate = new (isolate_ptr) Isolate(std::move(isolate_allocator));
    2807             : #if V8_TARGET_ARCH_64_BIT
    2808             :   DCHECK_IMPLIES(
    2809             :       mode == IsolateAllocationMode::kInV8Heap,
    2810             :       IsAligned(isolate->isolate_root(), kPtrComprIsolateRootAlignment));
    2811             : #endif
    2812             : 
    2813             : #ifdef DEBUG
    2814             :   non_disposed_isolates_++;
    2815             : #endif  // DEBUG
    2816             : 
    2817       61534 :   return isolate;
    2818             : }
    2819             : 
    2820             : // static
    2821       61517 : void Isolate::Delete(Isolate* isolate) {
    2822             :   DCHECK_NOT_NULL(isolate);
    2823             :   // Temporarily set this isolate as current so that various parts of
    2824             :   // the isolate can access it in their destructors without having a
    2825             :   // direct pointer. We don't use Enter/Exit here to avoid
    2826             :   // initializing the thread data.
    2827             :   PerIsolateThreadData* saved_data = isolate->CurrentPerIsolateThreadData();
    2828             :   DCHECK_EQ(true, isolate_key_created_.load(std::memory_order_relaxed));
    2829             :   Isolate* saved_isolate = reinterpret_cast<Isolate*>(
    2830       61517 :       base::Thread::GetThreadLocal(isolate->isolate_key_));
    2831       61518 :   SetIsolateThreadLocals(isolate, nullptr);
    2832             : 
    2833       61517 :   isolate->Deinit();
    2834             : 
    2835             : #ifdef DEBUG
    2836             :   non_disposed_isolates_--;
    2837             : #endif  // DEBUG
    2838             : 
    2839             :   // Take ownership of the IsolateAllocator to ensure the Isolate memory will
    2840             :   // be available during Isolate descructor call.
    2841             :   std::unique_ptr<IsolateAllocator> isolate_allocator =
    2842       61519 :       std::move(isolate->isolate_allocator_);
    2843       61519 :   isolate->~Isolate();
    2844             :   // Now free the memory owned by the allocator.
    2845       61518 :   isolate_allocator.reset();
    2846             : 
    2847             :   // Restore the previous current isolate.
    2848       61519 :   SetIsolateThreadLocals(saved_isolate, saved_data);
    2849       61519 : }
    2850             : 
    2851       62548 : v8::PageAllocator* Isolate::page_allocator() {
    2852       62548 :   return isolate_allocator_->page_allocator();
    2853             : }
    2854             : 
    2855       61534 : Isolate::Isolate(std::unique_ptr<i::IsolateAllocator> isolate_allocator)
    2856             :     : isolate_allocator_(std::move(isolate_allocator)),
    2857             :       id_(isolate_counter.fetch_add(1, std::memory_order_relaxed)),
    2858             :       stack_guard_(this),
    2859             :       allocator_(FLAG_trace_zone_stats
    2860             :                      ? new VerboseAccountingAllocator(&heap_, 256 * KB)
    2861             :                      : new AccountingAllocator()),
    2862             :       builtins_(this),
    2863             :       rail_mode_(PERFORMANCE_ANIMATION),
    2864             :       code_event_dispatcher_(new CodeEventDispatcher()),
    2865     1169145 :       cancelable_task_manager_(new CancelableTaskManager()) {
    2866             :   TRACE_ISOLATE(constructor);
    2867             :   CheckIsolateLayout();
    2868             : 
    2869             :   // ThreadManager is initialized early to support locking an isolate
    2870             :   // before it is entered.
    2871       61533 :   thread_manager_ = new ThreadManager(this);
    2872             : 
    2873             :   handle_scope_data_.Initialize();
    2874             : 
    2875             : #define ISOLATE_INIT_EXECUTE(type, name, initial_value)                        \
    2876             :   name##_ = (initial_value);
    2877       61533 :   ISOLATE_INIT_LIST(ISOLATE_INIT_EXECUTE)
    2878             : #undef ISOLATE_INIT_EXECUTE
    2879             : 
    2880             : #define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length)                         \
    2881             :   memset(name##_, 0, sizeof(type) * length);
    2882      246132 :   ISOLATE_INIT_ARRAY_LIST(ISOLATE_INIT_ARRAY_EXECUTE)
    2883             : #undef ISOLATE_INIT_ARRAY_EXECUTE
    2884             : 
    2885       61533 :   InitializeLoggingAndCounters();
    2886       61534 :   debug_ = new Debug(this);
    2887             : 
    2888       61534 :   InitializeDefaultEmbeddedBlob();
    2889             : 
    2890       61534 :   MicrotaskQueue::SetUpDefaultMicrotaskQueue(this);
    2891       61534 : }
    2892             : 
    2893           0 : void Isolate::CheckIsolateLayout() {
    2894             :   CHECK_EQ(OFFSET_OF(Isolate, isolate_data_), 0);
    2895             :   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.embedder_data_)),
    2896             :            Internals::kIsolateEmbedderDataOffset);
    2897             :   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.roots_)),
    2898             :            Internals::kIsolateRootsOffset);
    2899             :   CHECK_EQ(Internals::kExternalMemoryOffset % 8, 0);
    2900             :   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.external_memory_)),
    2901             :            Internals::kExternalMemoryOffset);
    2902             :   CHECK_EQ(Internals::kExternalMemoryLimitOffset % 8, 0);
    2903             :   CHECK_EQ(static_cast<int>(
    2904             :                OFFSET_OF(Isolate, isolate_data_.external_memory_limit_)),
    2905             :            Internals::kExternalMemoryLimitOffset);
    2906             :   CHECK_EQ(Internals::kExternalMemoryAtLastMarkCompactOffset % 8, 0);
    2907             :   CHECK_EQ(static_cast<int>(OFFSET_OF(
    2908             :                Isolate, isolate_data_.external_memory_at_last_mark_compact_)),
    2909             :            Internals::kExternalMemoryAtLastMarkCompactOffset);
    2910           0 : }
    2911             : 
    2912       62775 : void Isolate::ClearSerializerData() {
    2913       63289 :   delete external_reference_map_;
    2914       62775 :   external_reference_map_ = nullptr;
    2915       62775 : }
    2916             : 
    2917       82227 : bool Isolate::LogObjectRelocation() {
    2918      163787 :   return FLAG_verify_predictable || logger()->is_logging() || is_profiling() ||
    2919      163136 :          heap()->isolate()->logger()->is_listening_to_code_events() ||
    2920       81563 :          (heap_profiler() != nullptr &&
    2921      163669 :           heap_profiler()->is_tracking_object_moves()) ||
    2922       82227 :          heap()->has_heap_object_allocation_tracker();
    2923             : }
    2924             : 
    2925       61518 : void Isolate::Deinit() {
    2926             :   TRACE_ISOLATE(deinit);
    2927             : 
    2928             :   tracing_cpu_profiler_.reset();
    2929       61519 :   if (FLAG_stress_sampling_allocation_profiler > 0) {
    2930           0 :     heap_profiler()->StopSamplingHeapProfiler();
    2931             :   }
    2932             : 
    2933       61519 :   debug()->Unload();
    2934             : 
    2935       61518 :   wasm_engine()->DeleteCompileJobsOnIsolate(this);
    2936             : 
    2937       61519 :   if (concurrent_recompilation_enabled()) {
    2938       61415 :     optimizing_compile_dispatcher_->Stop();
    2939       61415 :     delete optimizing_compile_dispatcher_;
    2940       61415 :     optimizing_compile_dispatcher_ = nullptr;
    2941             :   }
    2942             : 
    2943       61519 :   wasm_engine()->memory_tracker()->DeleteSharedMemoryObjectsOnIsolate(this);
    2944             : 
    2945       61519 :   heap_.mark_compact_collector()->EnsureSweepingCompleted();
    2946       61518 :   heap_.memory_allocator()->unmapper()->EnsureUnmappingCompleted();
    2947             : 
    2948       61518 :   DumpAndResetStats();
    2949             : 
    2950       61518 :   if (FLAG_print_deopt_stress) {
    2951           0 :     PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_);
    2952             :   }
    2953             : 
    2954             :   // We must stop the logger before we tear down other components.
    2955       61518 :   sampler::Sampler* sampler = logger_->sampler();
    2956      122977 :   if (sampler && sampler->IsActive()) sampler->Stop();
    2957             : 
    2958             :   FreeThreadResources();
    2959       61518 :   logger_->StopProfilerThread();
    2960             : 
    2961             :   // We start with the heap tear down so that releasing managed objects does
    2962             :   // not cause a GC.
    2963       61518 :   heap_.StartTearDown();
    2964             : 
    2965       61517 :   ReleaseSharedPtrs();
    2966             : 
    2967       61519 :   delete deoptimizer_data_;
    2968       61519 :   deoptimizer_data_ = nullptr;
    2969       61519 :   builtins_.TearDown();
    2970       61518 :   bootstrapper_->TearDown();
    2971             : 
    2972       61518 :   if (runtime_profiler_ != nullptr) {
    2973       61518 :     delete runtime_profiler_;
    2974       61519 :     runtime_profiler_ = nullptr;
    2975             :   }
    2976             : 
    2977       61519 :   delete heap_profiler_;
    2978       61518 :   heap_profiler_ = nullptr;
    2979             : 
    2980       61518 :   compiler_dispatcher_->AbortAll();
    2981       61519 :   delete compiler_dispatcher_;
    2982       61519 :   compiler_dispatcher_ = nullptr;
    2983             : 
    2984             :   // This stops cancelable tasks (i.e. concurrent marking tasks)
    2985       61519 :   cancelable_task_manager()->CancelAndWait();
    2986             : 
    2987       61519 :   heap_.TearDown();
    2988       61519 :   logger_->TearDown();
    2989             : 
    2990       61519 :   if (wasm_engine_) {
    2991       61519 :     wasm_engine_->RemoveIsolate(this);
    2992             :     wasm_engine_.reset();
    2993             :   }
    2994             : 
    2995       61519 :   TearDownEmbeddedBlob();
    2996             : 
    2997       61519 :   delete interpreter_;
    2998       61520 :   interpreter_ = nullptr;
    2999             : 
    3000      123039 :   delete ast_string_constants_;
    3001       61520 :   ast_string_constants_ = nullptr;
    3002             : 
    3003             :   code_event_dispatcher_.reset();
    3004             : 
    3005       77786 :   delete root_index_map_;
    3006       61519 :   root_index_map_ = nullptr;
    3007             : 
    3008       61519 :   delete compiler_zone_;
    3009       61519 :   compiler_zone_ = nullptr;
    3010       61519 :   compiler_cache_ = nullptr;
    3011             : 
    3012       61519 :   ClearSerializerData();
    3013             : 
    3014             :   {
    3015       61519 :     base::MutexGuard lock_guard(&thread_data_table_mutex_);
    3016       61519 :     thread_data_table_.RemoveAllThreads();
    3017             :   }
    3018       61519 : }
    3019             : 
    3020             : 
    3021      546770 : void Isolate::SetIsolateThreadLocals(Isolate* isolate,
    3022             :                                      PerIsolateThreadData* data) {
    3023      546770 :   base::Thread::SetThreadLocal(isolate_key_, isolate);
    3024      546730 :   base::Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
    3025      546714 : }
    3026             : 
    3027             : 
    3028      369111 : Isolate::~Isolate() {
    3029             :   TRACE_ISOLATE(destructor);
    3030             : 
    3031             :   // The entry stack must be empty when we get here.
    3032             :   DCHECK(entry_stack_ == nullptr || entry_stack_->previous_item == nullptr);
    3033             : 
    3034       61519 :   delete entry_stack_;
    3035       61519 :   entry_stack_ = nullptr;
    3036             : 
    3037       61519 :   delete unicode_cache_;
    3038       61519 :   unicode_cache_ = nullptr;
    3039             : 
    3040       61519 :   delete date_cache_;
    3041       61518 :   date_cache_ = nullptr;
    3042             : 
    3043       61518 :   delete regexp_stack_;
    3044       61518 :   regexp_stack_ = nullptr;
    3045             : 
    3046       61518 :   delete descriptor_lookup_cache_;
    3047       61518 :   descriptor_lookup_cache_ = nullptr;
    3048             : 
    3049       61518 :   delete load_stub_cache_;
    3050       61519 :   load_stub_cache_ = nullptr;
    3051       61519 :   delete store_stub_cache_;
    3052       61519 :   store_stub_cache_ = nullptr;
    3053             : 
    3054      123038 :   delete materialized_object_store_;
    3055       61518 :   materialized_object_store_ = nullptr;
    3056             : 
    3057       61518 :   delete logger_;
    3058       61518 :   logger_ = nullptr;
    3059             : 
    3060       61518 :   delete handle_scope_implementer_;
    3061       61519 :   handle_scope_implementer_ = nullptr;
    3062             : 
    3063             :   delete code_tracer();
    3064             :   set_code_tracer(nullptr);
    3065             : 
    3066       61519 :   delete compilation_cache_;
    3067       61519 :   compilation_cache_ = nullptr;
    3068       61519 :   delete bootstrapper_;
    3069       61519 :   bootstrapper_ = nullptr;
    3070       61519 :   delete inner_pointer_to_code_cache_;
    3071       61519 :   inner_pointer_to_code_cache_ = nullptr;
    3072             : 
    3073       61519 :   delete thread_manager_;
    3074       61519 :   thread_manager_ = nullptr;
    3075             : 
    3076       61519 :   delete global_handles_;
    3077       61519 :   global_handles_ = nullptr;
    3078       61519 :   delete eternal_handles_;
    3079       61519 :   eternal_handles_ = nullptr;
    3080             : 
    3081       61534 :   delete string_stream_debug_object_cache_;
    3082       61519 :   string_stream_debug_object_cache_ = nullptr;
    3083             : 
    3084       61519 :   delete random_number_generator_;
    3085       61519 :   random_number_generator_ = nullptr;
    3086             : 
    3087       61519 :   delete fuzzer_rng_;
    3088       61518 :   fuzzer_rng_ = nullptr;
    3089             : 
    3090       61518 :   delete debug_;
    3091       61518 :   debug_ = nullptr;
    3092             : 
    3093       61518 :   delete cancelable_task_manager_;
    3094       61518 :   cancelable_task_manager_ = nullptr;
    3095             : 
    3096       61518 :   delete allocator_;
    3097       61518 :   allocator_ = nullptr;
    3098             : 
    3099             :   // Assert that |default_microtask_queue_| is the last MicrotaskQueue instance.
    3100             :   DCHECK_IMPLIES(default_microtask_queue_,
    3101             :                  default_microtask_queue_ == default_microtask_queue_->next());
    3102       61518 :   delete default_microtask_queue_;
    3103       61519 :   default_microtask_queue_ = nullptr;
    3104       61518 : }
    3105             : 
    3106       93971 : void Isolate::InitializeThreadLocal() { thread_local_top()->Initialize(this); }
    3107             : 
    3108          20 : void Isolate::SetTerminationOnExternalTryCatch() {
    3109        1891 :   if (try_catch_handler() == nullptr) return;
    3110        1881 :   try_catch_handler()->can_continue_ = false;
    3111        1881 :   try_catch_handler()->has_terminated_ = true;
    3112             :   try_catch_handler()->exception_ =
    3113        1881 :       reinterpret_cast<void*>(ReadOnlyRoots(heap()).null_value().ptr());
    3114             : }
    3115             : 
    3116      168389 : bool Isolate::PropagatePendingExceptionToExternalTryCatch() {
    3117             :   Object exception = pending_exception();
    3118             : 
    3119      168389 :   if (IsJavaScriptHandlerOnTop(exception)) {
    3120      137476 :     thread_local_top()->external_caught_exception_ = false;
    3121      137476 :     return false;
    3122             :   }
    3123             : 
    3124       30913 :   if (!IsExternalHandlerOnTop(exception)) {
    3125        4492 :     thread_local_top()->external_caught_exception_ = false;
    3126        4492 :     return true;
    3127             :   }
    3128             : 
    3129       26421 :   thread_local_top()->external_caught_exception_ = true;
    3130       26421 :   if (!is_catchable_by_javascript(exception)) {
    3131             :     SetTerminationOnExternalTryCatch();
    3132             :   } else {
    3133             :     v8::TryCatch* handler = try_catch_handler();
    3134             :     DCHECK(thread_local_top()->pending_message_obj_->IsJSMessageObject() ||
    3135             :            thread_local_top()->pending_message_obj_->IsTheHole(this));
    3136       24550 :     handler->can_continue_ = true;
    3137       24550 :     handler->has_terminated_ = false;
    3138       24550 :     handler->exception_ = reinterpret_cast<void*>(pending_exception().ptr());
    3139             :     // Propagate to the external try-catch only if we got an actual message.
    3140       24550 :     if (thread_local_top()->pending_message_obj_->IsTheHole(this)) return true;
    3141             : 
    3142             :     handler->message_obj_ =
    3143       11173 :         reinterpret_cast<void*>(thread_local_top()->pending_message_obj_.ptr());
    3144             :   }
    3145             :   return true;
    3146             : }
    3147             : 
    3148       62111 : bool Isolate::InitializeCounters() {
    3149       62111 :   if (async_counters_) return false;
    3150      123067 :   async_counters_ = std::make_shared<Counters>(this);
    3151       61534 :   return true;
    3152             : }
    3153             : 
    3154       62111 : void Isolate::InitializeLoggingAndCounters() {
    3155       62111 :   if (logger_ == nullptr) {
    3156       61533 :     logger_ = new Logger(this);
    3157             :   }
    3158       62110 :   InitializeCounters();
    3159       62113 : }
    3160             : 
    3161             : namespace {
    3162             : 
    3163          56 : void CreateOffHeapTrampolines(Isolate* isolate) {
    3164             :   DCHECK_NOT_NULL(isolate->embedded_blob());
    3165             :   DCHECK_NE(0, isolate->embedded_blob_size());
    3166             : 
    3167             :   HandleScope scope(isolate);
    3168             :   Builtins* builtins = isolate->builtins();
    3169             : 
    3170          56 :   EmbeddedData d = EmbeddedData::FromBlob();
    3171             : 
    3172      169736 :   for (int i = 0; i < Builtins::builtin_count; i++) {
    3173             :     if (!Builtins::IsIsolateIndependent(i)) continue;
    3174             : 
    3175       84840 :     Address instruction_start = d.InstructionStartOfBuiltin(i);
    3176             :     Handle<Code> trampoline = isolate->factory()->NewOffHeapTrampolineFor(
    3177       84840 :         builtins->builtin_handle(i), instruction_start);
    3178             : 
    3179             :     // From this point onwards, the old builtin code object is unreachable and
    3180             :     // will be collected by the next GC.
    3181       84840 :     builtins->set_builtin(i, *trampoline);
    3182             : 
    3183       84840 :     if (isolate->logger()->is_listening_to_code_events() ||
    3184             :         isolate->is_profiling()) {
    3185           0 :       isolate->logger()->LogCodeObject(*trampoline);
    3186             :     }
    3187             :   }
    3188          56 : }
    3189             : 
    3190             : #ifdef DEBUG
    3191             : bool IsolateIsCompatibleWithEmbeddedBlob(Isolate* isolate) {
    3192             :   if (!FLAG_embedded_builtins) return true;
    3193             :   EmbeddedData d = EmbeddedData::FromBlob(isolate);
    3194             :   return (d.IsolateHash() == isolate->HashIsolateForEmbeddedBlob());
    3195             : }
    3196             : #endif  // DEBUG
    3197             : 
    3198             : }  // namespace
    3199             : 
    3200       61534 : void Isolate::InitializeDefaultEmbeddedBlob() {
    3201             :   const uint8_t* blob = DefaultEmbeddedBlob();
    3202             :   uint32_t size = DefaultEmbeddedBlobSize();
    3203             : 
    3204             : #ifdef V8_MULTI_SNAPSHOTS
    3205             :   if (!FLAG_untrusted_code_mitigations) {
    3206             :     blob = TrustedEmbeddedBlob();
    3207             :     size = TrustedEmbeddedBlobSize();
    3208             :   }
    3209             : #endif
    3210             : 
    3211       61534 :   if (StickyEmbeddedBlob() != nullptr) {
    3212             :     base::MutexGuard guard(current_embedded_blob_refcount_mutex_.Pointer());
    3213             :     // Check again now that we hold the lock.
    3214          55 :     if (StickyEmbeddedBlob() != nullptr) {
    3215             :       blob = StickyEmbeddedBlob();
    3216             :       size = StickyEmbeddedBlobSize();
    3217          55 :       current_embedded_blob_refs_++;
    3218             :     }
    3219             :   }
    3220             : 
    3221       61534 :   if (blob == nullptr) {
    3222           1 :     CHECK_EQ(0, size);
    3223             :   } else {
    3224       61533 :     SetEmbeddedBlob(blob, size);
    3225             :   }
    3226       61534 : }
    3227             : 
    3228          56 : void Isolate::CreateAndSetEmbeddedBlob() {
    3229             :   base::MutexGuard guard(current_embedded_blob_refcount_mutex_.Pointer());
    3230             : 
    3231             :   PrepareBuiltinSourcePositionMap();
    3232             : 
    3233             :   // If a sticky blob has been set, we reuse it.
    3234          56 :   if (StickyEmbeddedBlob() != nullptr) {
    3235           0 :     CHECK_EQ(embedded_blob(), StickyEmbeddedBlob());
    3236           0 :     CHECK_EQ(CurrentEmbeddedBlob(), StickyEmbeddedBlob());
    3237             :   } else {
    3238             :     // Create and set a new embedded blob.
    3239             :     uint8_t* data;
    3240             :     uint32_t size;
    3241          56 :     InstructionStream::CreateOffHeapInstructionStream(this, &data, &size);
    3242             : 
    3243          56 :     CHECK_EQ(0, current_embedded_blob_refs_);
    3244          56 :     const uint8_t* const_data = const_cast<const uint8_t*>(data);
    3245          56 :     SetEmbeddedBlob(const_data, size);
    3246          56 :     current_embedded_blob_refs_++;
    3247             : 
    3248          56 :     SetStickyEmbeddedBlob(const_data, size);
    3249             :   }
    3250             : 
    3251          56 :   CreateOffHeapTrampolines(this);
    3252          56 : }
    3253             : 
    3254       61519 : void Isolate::TearDownEmbeddedBlob() {
    3255             :   // Nothing to do in case the blob is embedded into the binary or unset.
    3256       61519 :   if (StickyEmbeddedBlob() == nullptr) return;
    3257             : 
    3258         111 :   CHECK_EQ(embedded_blob(), StickyEmbeddedBlob());
    3259         111 :   CHECK_EQ(CurrentEmbeddedBlob(), StickyEmbeddedBlob());
    3260             : 
    3261             :   base::MutexGuard guard(current_embedded_blob_refcount_mutex_.Pointer());
    3262         111 :   current_embedded_blob_refs_--;
    3263         111 :   if (current_embedded_blob_refs_ == 0 && enable_embedded_blob_refcounting_) {
    3264             :     // We own the embedded blob and are the last holder. Free it.
    3265             :     InstructionStream::FreeOffHeapInstructionStream(
    3266           0 :         const_cast<uint8_t*>(embedded_blob()), embedded_blob_size());
    3267           0 :     ClearEmbeddedBlob();
    3268             :   }
    3269             : }
    3270             : 
    3271           1 : bool Isolate::InitWithoutSnapshot() { return Init(nullptr, nullptr); }
    3272             : 
    3273       61422 : bool Isolate::InitWithSnapshot(ReadOnlyDeserializer* read_only_deserializer,
    3274             :                                StartupDeserializer* startup_deserializer) {
    3275             :   DCHECK_NOT_NULL(read_only_deserializer);
    3276             :   DCHECK_NOT_NULL(startup_deserializer);
    3277       61422 :   return Init(read_only_deserializer, startup_deserializer);
    3278             : }
    3279             : 
    3280       61533 : bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer,
    3281             :                    StartupDeserializer* startup_deserializer) {
    3282             :   TRACE_ISOLATE(init);
    3283       61533 :   const bool create_heap_objects = (read_only_deserializer == nullptr);
    3284             :   // We either have both or neither.
    3285             :   DCHECK_EQ(create_heap_objects, startup_deserializer == nullptr);
    3286             : 
    3287             :   base::ElapsedTimer timer;
    3288       61533 :   if (create_heap_objects && FLAG_profile_deserialization) timer.Start();
    3289             : 
    3290       61533 :   time_millis_at_init_ = heap_.MonotonicallyIncreasingTimeInMs();
    3291             : 
    3292       61533 :   stress_deopt_count_ = FLAG_deopt_every_n_times;
    3293       61533 :   force_slow_path_ = FLAG_force_slow_path;
    3294             : 
    3295       61533 :   has_fatal_error_ = false;
    3296             : 
    3297             :   // The initialization process does not handle memory exhaustion.
    3298             :   AlwaysAllocateScope always_allocate(this);
    3299             : 
    3300             :   // Safe after setting Heap::isolate_, and initializing StackGuard
    3301       61533 :   heap_.SetStackLimits();
    3302             : 
    3303             : #define ASSIGN_ELEMENT(CamelName, hacker_name)                  \
    3304             :   isolate_addresses_[IsolateAddressId::k##CamelName##Address] = \
    3305             :       reinterpret_cast<Address>(hacker_name##_address());
    3306      738384 :   FOR_EACH_ISOLATE_ADDRESS_NAME(ASSIGN_ELEMENT)
    3307             : #undef ASSIGN_ELEMENT
    3308             : 
    3309       61532 :   compilation_cache_ = new CompilationCache(this);
    3310      123061 :   descriptor_lookup_cache_ = new DescriptorLookupCache();
    3311      123061 :   unicode_cache_ = new UnicodeCache();
    3312       61531 :   inner_pointer_to_code_cache_ = new InnerPointerToCodeCache(this);
    3313       61534 :   global_handles_ = new GlobalHandles(this);
    3314      123066 :   eternal_handles_ = new EternalHandles();
    3315       61533 :   bootstrapper_ = new Bootstrapper(this);
    3316      123065 :   handle_scope_implementer_ = new HandleScopeImplementer(this);
    3317       61534 :   load_stub_cache_ = new StubCache(this);
    3318       61533 :   store_stub_cache_ = new StubCache(this);
    3319      123068 :   materialized_object_store_ = new MaterializedObjectStore(this);
    3320       61534 :   regexp_stack_ = new RegExpStack();
    3321       61533 :   regexp_stack_->isolate_ = this;
    3322       61533 :   date_cache_ = new DateCache();
    3323       61531 :   heap_profiler_ = new HeapProfiler(heap());
    3324       61528 :   interpreter_ = new interpreter::Interpreter(this);
    3325             : 
    3326             :   compiler_dispatcher_ =
    3327       61531 :       new CompilerDispatcher(this, V8::GetCurrentPlatform(), FLAG_stack_size);
    3328             : 
    3329             :   // Enable logging before setting up the heap
    3330       61534 :   logger_->SetUp(this);
    3331             : 
    3332             :   { // NOLINT
    3333             :     // Ensure that the thread has a valid stack guard.  The v8::Locker object
    3334             :     // will ensure this too, but we don't have to use lockers if we are only
    3335             :     // using one thread.
    3336             :     ExecutionAccess lock(this);
    3337       61533 :     stack_guard_.InitThread(lock);
    3338             :   }
    3339             : 
    3340             :   // SetUp the object heap.
    3341             :   DCHECK(!heap_.HasBeenSetUp());
    3342       61532 :   heap_.SetUp();
    3343       61534 :   ReadOnlyHeap::SetUp(this, read_only_deserializer);
    3344       61534 :   heap_.SetUpSpaces();
    3345             : 
    3346       61534 :   isolate_data_.external_reference_table()->Init(this);
    3347             : 
    3348             :   // Setup the wasm engine.
    3349       61534 :   if (wasm_engine_ == nullptr) {
    3350      122900 :     SetWasmEngine(wasm::WasmEngine::GetWasmEngine());
    3351             :   }
    3352             :   DCHECK_NOT_NULL(wasm_engine_);
    3353             : 
    3354       61534 :   deoptimizer_data_ = new DeoptimizerData(heap());
    3355             : 
    3356       61534 :   if (setup_delegate_ == nullptr) {
    3357      122538 :     setup_delegate_ = new SetupIsolateDelegate(create_heap_objects);
    3358             :   }
    3359             : 
    3360       61534 :   if (!setup_delegate_->SetupHeap(&heap_)) {
    3361           0 :     V8::FatalProcessOutOfMemory(this, "heap object creation");
    3362             :     return false;
    3363             :   }
    3364             : 
    3365       61534 :   if (create_heap_objects) {
    3366             :     // Terminate the partial snapshot cache so we can iterate.
    3367         112 :     partial_snapshot_cache_.push_back(ReadOnlyRoots(this).undefined_value());
    3368             :   }
    3369             : 
    3370             :   InitializeThreadLocal();
    3371             : 
    3372             :   // Profiler has to be created after ThreadLocal is initialized
    3373             :   // because it makes use of interrupts.
    3374       61534 :   tracing_cpu_profiler_.reset(new TracingCpuProfilerImpl(this));
    3375             : 
    3376       61534 :   bootstrapper_->Initialize(create_heap_objects);
    3377             : 
    3378       61534 :   if (FLAG_embedded_builtins && create_heap_objects) {
    3379          56 :     builtins_constants_table_builder_ = new BuiltinsConstantsTableBuilder(this);
    3380             :   }
    3381       61534 :   setup_delegate_->SetupBuiltins(this);
    3382             : #ifndef V8_TARGET_ARCH_ARM
    3383       61534 :   if (create_heap_objects) {
    3384             :     // Store the interpreter entry trampoline on the root list. It is used as a
    3385             :     // template for further copies that may later be created to help profile
    3386             :     // interpreted code.
    3387             :     // We currently cannot do this on arm due to RELATIVE_CODE_TARGETs
    3388             :     // assuming that all possible Code targets may be addressed with an int24
    3389             :     // offset, effectively limiting code space size to 32MB. We can guarantee
    3390             :     // this at mksnapshot-time, but not at runtime.
    3391             :     // See also: https://crbug.com/v8/8713.
    3392          56 :     heap_.SetInterpreterEntryTrampolineForProfiling(
    3393          56 :         heap_.builtin(Builtins::kInterpreterEntryTrampoline));
    3394             :   }
    3395             : #endif
    3396       61534 :   if (FLAG_embedded_builtins && create_heap_objects) {
    3397          56 :     builtins_constants_table_builder_->Finalize();
    3398         112 :     delete builtins_constants_table_builder_;
    3399          56 :     builtins_constants_table_builder_ = nullptr;
    3400             : 
    3401          56 :     CreateAndSetEmbeddedBlob();
    3402             :   }
    3403             : 
    3404             :   // Initialize custom memcopy and memmove functions (must happen after
    3405             :   // embedded blob setup).
    3406       61534 :   init_memcopy_functions();
    3407             : 
    3408       61534 :   if (FLAG_log_internal_timer_events) {
    3409             :     set_event_logger(Logger::DefaultEventLoggerSentinel);
    3410             :   }
    3411             : 
    3412       61534 :   if (FLAG_trace_turbo || FLAG_trace_turbo_graph || FLAG_turbo_profiling) {
    3413           5 :     PrintF("Concurrent recompilation has been disabled for tracing.\n");
    3414       61529 :   } else if (OptimizingCompileDispatcher::Enabled()) {
    3415       61430 :     optimizing_compile_dispatcher_ = new OptimizingCompileDispatcher(this);
    3416             :   }
    3417             : 
    3418             :   // Initialize runtime profiler before deserialization, because collections may
    3419             :   // occur, clearing/updating ICs.
    3420       61533 :   runtime_profiler_ = new RuntimeProfiler(this);
    3421             : 
    3422             :   // If we are deserializing, read the state into the now-empty heap.
    3423             :   {
    3424             :     AlwaysAllocateScope always_allocate(this);
    3425      123067 :     CodeSpaceMemoryModificationScope modification_scope(&heap_);
    3426             : 
    3427       61534 :     if (!create_heap_objects) {
    3428       61478 :       startup_deserializer->DeserializeInto(this);
    3429             :     } else {
    3430          56 :       heap_.read_only_heap()->OnCreateHeapObjectsComplete();
    3431             :     }
    3432       61534 :     load_stub_cache_->Initialize();
    3433       61534 :     store_stub_cache_->Initialize();
    3434       61534 :     interpreter_->Initialize();
    3435       61534 :     heap_.NotifyDeserializationComplete();
    3436             :   }
    3437       61534 :   delete setup_delegate_;
    3438       61534 :   setup_delegate_ = nullptr;
    3439             : 
    3440             :   // Initialize the builtin entry table.
    3441       61534 :   Builtins::UpdateBuiltinEntryTable(this);
    3442             : 
    3443             : #ifdef DEBUG
    3444             :   // Verify that the current heap state (usually deserialized from the snapshot)
    3445             :   // is compatible with the embedded blob. If this DCHECK fails, we've likely
    3446             :   // loaded a snapshot generated by a different V8 version or build-time
    3447             :   // configuration.
    3448             :   if (!IsolateIsCompatibleWithEmbeddedBlob(this)) {
    3449             :     FATAL(
    3450             :         "The Isolate is incompatible with the embedded blob. This is usually "
    3451             :         "caused by incorrect usage of mksnapshot. When generating custom "
    3452             :         "snapshots, embedders must ensure they pass the same flags as during "
    3453             :         "the V8 build process (e.g.: --turbo-instruction-scheduling).");
    3454             :   }
    3455             :   DCHECK_IMPLIES(FLAG_jitless, FLAG_embedded_builtins);
    3456             : #endif  // DEBUG
    3457             : 
    3458             : #ifndef V8_TARGET_ARCH_ARM
    3459             :   // The IET for profiling should always be a full on-heap Code object.
    3460             :   DCHECK(!Code::cast(heap_.interpreter_entry_trampoline_for_profiling())
    3461             :               ->is_off_heap_trampoline());
    3462             : #endif  // V8_TARGET_ARCH_ARM
    3463             : 
    3464             :   if (FLAG_print_builtin_code) builtins()->PrintBuiltinCode();
    3465             :   if (FLAG_print_builtin_size) builtins()->PrintBuiltinSize();
    3466             : 
    3467             :   // Finish initialization of ThreadLocal after deserialization is done.
    3468             :   clear_pending_exception();
    3469             :   clear_pending_message();
    3470             :   clear_scheduled_exception();
    3471             : 
    3472             :   // Deserializing may put strange things in the root array's copy of the
    3473             :   // stack guard.
    3474       61534 :   heap_.SetStackLimits();
    3475             : 
    3476             :   // Quiet the heap NaN if needed on target platform.
    3477             :   if (!create_heap_objects)
    3478             :     Assembler::QuietNaN(ReadOnlyRoots(this).nan_value());
    3479             : 
    3480       61534 :   if (FLAG_trace_turbo) {
    3481             :     // Create an empty file.
    3482          10 :     std::ofstream(GetTurboCfgFileName(this).c_str(), std::ios_base::trunc);
    3483             :   }
    3484             : 
    3485             :   {
    3486             :     HandleScope scope(this);
    3487       61534 :     ast_string_constants_ = new AstStringConstants(this, HashSeed(this));
    3488             :   }
    3489             : 
    3490       61533 :   initialized_from_snapshot_ = !create_heap_objects;
    3491             : 
    3492       61533 :   if (!FLAG_inline_new) heap_.DisableInlineAllocation();
    3493             : 
    3494       61533 :   if (FLAG_stress_sampling_allocation_profiler > 0) {
    3495           0 :     uint64_t sample_interval = FLAG_stress_sampling_allocation_profiler;
    3496             :     int stack_depth = 128;
    3497             :     v8::HeapProfiler::SamplingFlags sampling_flags =
    3498             :         v8::HeapProfiler::SamplingFlags::kSamplingForceGC;
    3499             :     heap_profiler()->StartSamplingHeapProfiler(sample_interval, stack_depth,
    3500           0 :                                                sampling_flags);
    3501             :   }
    3502             : 
    3503       61533 :   if (create_heap_objects && FLAG_profile_deserialization) {
    3504           0 :     double ms = timer.Elapsed().InMillisecondsF();
    3505           0 :     PrintF("[Initializing isolate from scratch took %0.3f ms]\n", ms);
    3506             :   }
    3507             : 
    3508             :   return true;
    3509             : }
    3510             : 
    3511      222125 : void Isolate::Enter() {
    3512             :   Isolate* current_isolate = nullptr;
    3513             :   PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
    3514      222119 :   if (current_data != nullptr) {
    3515       11387 :     current_isolate = current_data->isolate_;
    3516             :     DCHECK_NOT_NULL(current_isolate);
    3517       11387 :     if (current_isolate == this) {
    3518             :       DCHECK(Current() == this);
    3519             :       DCHECK_NOT_NULL(entry_stack_);
    3520             :       DCHECK(entry_stack_->previous_thread_data == nullptr ||
    3521             :              entry_stack_->previous_thread_data->thread_id() ==
    3522             :                  ThreadId::Current());
    3523             :       // Same thread re-enters the isolate, no need to re-init anything.
    3524       10233 :       entry_stack_->entry_count++;
    3525       10233 :       return;
    3526             :     }
    3527             :   }
    3528             : 
    3529      211886 :   PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread();
    3530             :   DCHECK_NOT_NULL(data);
    3531             :   DCHECK(data->isolate_ == this);
    3532             : 
    3533             :   EntryStackItem* item = new EntryStackItem(current_data,
    3534             :                                             current_isolate,
    3535      211892 :                                             entry_stack_);
    3536      211893 :   entry_stack_ = item;
    3537             : 
    3538      211893 :   SetIsolateThreadLocals(this, data);
    3539             : 
    3540             :   // In case it's the first time some thread enters the isolate.
    3541             :   set_thread_id(data->thread_id());
    3542             : }
    3543             : 
    3544             : 
    3545      222111 : void Isolate::Exit() {
    3546             :   DCHECK_NOT_NULL(entry_stack_);
    3547             :   DCHECK(entry_stack_->previous_thread_data == nullptr ||
    3548             :          entry_stack_->previous_thread_data->thread_id() ==
    3549             :              ThreadId::Current());
    3550             : 
    3551      222111 :   if (--entry_stack_->entry_count > 0) return;
    3552             : 
    3553             :   DCHECK_NOT_NULL(CurrentPerIsolateThreadData());
    3554             :   DCHECK(CurrentPerIsolateThreadData()->isolate_ == this);
    3555             : 
    3556             :   // Pop the stack.
    3557      211879 :   EntryStackItem* item = entry_stack_;
    3558      211879 :   entry_stack_ = item->previous_item;
    3559             : 
    3560      211879 :   PerIsolateThreadData* previous_thread_data = item->previous_thread_data;
    3561      211879 :   Isolate* previous_isolate = item->previous_isolate;
    3562             : 
    3563      211879 :   delete item;
    3564             : 
    3565             :   // Reinit the current thread for the isolate it was running before this one.
    3566      211884 :   SetIsolateThreadLocals(previous_isolate, previous_thread_data);
    3567             : }
    3568             : 
    3569             : 
    3570        7162 : void Isolate::LinkDeferredHandles(DeferredHandles* deferred) {
    3571        7162 :   deferred->next_ = deferred_handles_head_;
    3572        7162 :   if (deferred_handles_head_ != nullptr) {
    3573        2051 :     deferred_handles_head_->previous_ = deferred;
    3574             :   }
    3575        7162 :   deferred_handles_head_ = deferred;
    3576        7162 : }
    3577             : 
    3578             : 
    3579        7162 : void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) {
    3580             : #ifdef DEBUG
    3581             :   // In debug mode assert that the linked list is well-formed.
    3582             :   DeferredHandles* deferred_iterator = deferred;
    3583             :   while (deferred_iterator->previous_ != nullptr) {
    3584             :     deferred_iterator = deferred_iterator->previous_;
    3585             :   }
    3586             :   DCHECK(deferred_handles_head_ == deferred_iterator);
    3587             : #endif
    3588        7162 :   if (deferred_handles_head_ == deferred) {
    3589        5440 :     deferred_handles_head_ = deferred_handles_head_->next_;
    3590             :   }
    3591        7162 :   if (deferred->next_ != nullptr) {
    3592         822 :     deferred->next_->previous_ = deferred->previous_;
    3593             :   }
    3594        7162 :   if (deferred->previous_ != nullptr) {
    3595        1722 :     deferred->previous_->next_ = deferred->next_;
    3596             :   }
    3597        7162 : }
    3598             : 
    3599       61518 : void Isolate::DumpAndResetStats() {
    3600       61518 :   if (turbo_statistics() != nullptr) {
    3601             :     DCHECK(FLAG_turbo_stats || FLAG_turbo_stats_nvp);
    3602           0 :     StdoutStream os;
    3603           0 :     if (FLAG_turbo_stats) {
    3604           0 :       AsPrintableStatistics ps = {*turbo_statistics(), false};
    3605           0 :       os << ps << std::endl;
    3606             :     }
    3607           0 :     if (FLAG_turbo_stats_nvp) {
    3608           0 :       AsPrintableStatistics ps = {*turbo_statistics(), true};
    3609           0 :       os << ps << std::endl;
    3610             :     }
    3611           0 :     delete turbo_statistics_;
    3612           0 :     turbo_statistics_ = nullptr;
    3613             :   }
    3614             :   // TODO(7424): There is no public API for the {WasmEngine} yet. So for now we
    3615             :   // just dump and reset the engines statistics together with the Isolate.
    3616       61518 :   if (FLAG_turbo_stats_wasm) {
    3617           0 :     wasm_engine()->DumpAndResetTurboStatistics();
    3618             :   }
    3619       61518 :   if (V8_UNLIKELY(TracingFlags::runtime_stats.load(std::memory_order_relaxed) ==
    3620             :                   v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE)) {
    3621             :     counters()->worker_thread_runtime_call_stats()->AddToMainTable(
    3622           0 :         counters()->runtime_call_stats());
    3623           0 :     counters()->runtime_call_stats()->Print();
    3624           0 :     counters()->runtime_call_stats()->Reset();
    3625             :   }
    3626       61518 : }
    3627             : 
    3628       28691 : void Isolate::AbortConcurrentOptimization(BlockingBehavior behavior) {
    3629       28691 :   if (concurrent_recompilation_enabled()) {
    3630             :     DisallowHeapAllocation no_recursive_gc;
    3631       28635 :     optimizing_compile_dispatcher()->Flush(behavior);
    3632             :   }
    3633       28691 : }
    3634             : 
    3635           0 : CompilationStatistics* Isolate::GetTurboStatistics() {
    3636           0 :   if (turbo_statistics() == nullptr)
    3637           0 :     set_turbo_statistics(new CompilationStatistics());
    3638           0 :   return turbo_statistics();
    3639             : }
    3640             : 
    3641             : 
    3642         263 : CodeTracer* Isolate::GetCodeTracer() {
    3643         268 :   if (code_tracer() == nullptr) set_code_tracer(new CodeTracer(id()));
    3644         263 :   return code_tracer();
    3645             : }
    3646             : 
    3647     1736716 : bool Isolate::use_optimizer() {
    3648      168908 :   return FLAG_opt && !serializer_enabled_ && CpuFeatures::SupportsOptimizer() &&
    3649     1905592 :          !is_precise_count_code_coverage() && !is_block_count_code_coverage();
    3650             : }
    3651             : 
    3652      482611 : bool Isolate::NeedsDetailedOptimizedCodeLineInfo() const {
    3653      482611 :   return NeedsSourcePositionsForProfiling() ||
    3654      482618 :          detailed_source_positions_for_profiling();
    3655             : }
    3656             : 
    3657     1592149 : bool Isolate::NeedsSourcePositionsForProfiling() const {
    3658     1591016 :   return FLAG_trace_deopt || FLAG_trace_turbo || FLAG_trace_turbo_graph ||
    3659     3181525 :          FLAG_turbo_profiling || FLAG_perf_prof || is_profiling() ||
    3660     4736304 :          debug_->is_active() || logger_->is_logging() || FLAG_trace_maps;
    3661             : }
    3662             : 
    3663        1498 : void Isolate::SetFeedbackVectorsForProfilingTools(Object value) {
    3664             :   DCHECK(value->IsUndefined(this) || value->IsArrayList());
    3665             :   heap()->set_feedback_vectors_for_profiling_tools(value);
    3666        1498 : }
    3667             : 
    3668         164 : void Isolate::MaybeInitializeVectorListFromHeap() {
    3669         164 :   if (!heap()->feedback_vectors_for_profiling_tools()->IsUndefined(this)) {
    3670             :     // Already initialized, return early.
    3671             :     DCHECK(heap()->feedback_vectors_for_profiling_tools()->IsArrayList());
    3672           8 :     return;
    3673             :   }
    3674             : 
    3675             :   // Collect existing feedback vectors.
    3676             :   std::vector<Handle<FeedbackVector>> vectors;
    3677             : 
    3678             :   {
    3679         312 :     HeapIterator heap_iterator(heap());
    3680     1184242 :     for (HeapObject current_obj = heap_iterator.next(); !current_obj.is_null();
    3681             :          current_obj = heap_iterator.next()) {
    3682     2367740 :       if (!current_obj->IsFeedbackVector()) continue;
    3683             : 
    3684         432 :       FeedbackVector vector = FeedbackVector::cast(current_obj);
    3685         432 :       SharedFunctionInfo shared = vector->shared_function_info();
    3686             : 
    3687             :       // No need to preserve the feedback vector for non-user-visible functions.
    3688         432 :       if (!shared->IsSubjectToDebugging()) continue;
    3689             : 
    3690         432 :       vectors.emplace_back(vector, this);
    3691             :     }
    3692             :   }
    3693             : 
    3694             :   // Add collected feedback vectors to the root list lest we lose them to GC.
    3695             :   Handle<ArrayList> list =
    3696         156 :       ArrayList::New(this, static_cast<int>(vectors.size()));
    3697        1020 :   for (const auto& vector : vectors) list = ArrayList::Add(this, list, vector);
    3698             :   SetFeedbackVectorsForProfilingTools(*list);
    3699             : }
    3700             : 
    3701           5 : void Isolate::set_date_cache(DateCache* date_cache) {
    3702           5 :   if (date_cache != date_cache_) {
    3703           5 :     delete date_cache_;
    3704             :   }
    3705           5 :   date_cache_ = date_cache;
    3706           5 : }
    3707             : 
    3708       15309 : bool Isolate::IsArrayOrObjectOrStringPrototype(Object object) {
    3709             :   Object context = heap()->native_contexts_list();
    3710       68237 :   while (!context->IsUndefined(this)) {
    3711       27307 :     Context current_context = Context::cast(context);
    3712       81776 :     if (current_context->initial_object_prototype() == object ||
    3713       53829 :         current_context->initial_array_prototype() == object ||
    3714       26522 :         current_context->initial_string_prototype() == object) {
    3715         843 :       return true;
    3716             :     }
    3717       26464 :     context = current_context->next_context_link();
    3718             :   }
    3719             :   return false;
    3720             : }
    3721             : 
    3722     6719781 : bool Isolate::IsInAnyContext(Object object, uint32_t index) {
    3723             :   DisallowHeapAllocation no_gc;
    3724             :   Object context = heap()->native_contexts_list();
    3725    11609575 :   while (!context->IsUndefined(this)) {
    3726     8045002 :     Context current_context = Context::cast(context);
    3727    16090008 :     if (current_context->get(index) == object) {
    3728     5600109 :       return true;
    3729             :     }
    3730     2444897 :     context = current_context->next_context_link();
    3731             :   }
    3732             :   return false;
    3733             : }
    3734             : 
    3735       99430 : bool Isolate::IsNoElementsProtectorIntact(Context context) {
    3736             :   PropertyCell no_elements_cell = heap()->no_elements_protector();
    3737             :   bool cell_reports_intact =
    3738    11686158 :       no_elements_cell->value()->IsSmi() &&
    3739             :       Smi::ToInt(no_elements_cell->value()) == kProtectorValid;
    3740             : 
    3741             : #ifdef DEBUG
    3742             :   Context native_context = context->native_context();
    3743             : 
    3744             :   Map root_array_map =
    3745             :       native_context->GetInitialJSArrayMap(GetInitialFastElementsKind());
    3746             :   JSObject initial_array_proto = JSObject::cast(
    3747             :       native_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
    3748             :   JSObject initial_object_proto = JSObject::cast(
    3749             :       native_context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX));
    3750             :   JSObject initial_string_proto = JSObject::cast(
    3751             :       native_context->get(Context::INITIAL_STRING_PROTOTYPE_INDEX));
    3752             : 
    3753             :   if (root_array_map.is_null() || initial_array_proto == initial_object_proto) {
    3754             :     // We are in the bootstrapping process, and the entire check sequence
    3755             :     // shouldn't be performed.
    3756             :     return cell_reports_intact;
    3757             :   }
    3758             : 
    3759             :   // Check that the array prototype hasn't been altered WRT empty elements.
    3760             :   if (root_array_map->prototype() != initial_array_proto) {
    3761             :     DCHECK_EQ(false, cell_reports_intact);
    3762             :     return cell_reports_intact;
    3763             :   }
    3764             : 
    3765             :   FixedArrayBase elements = initial_array_proto->elements();
    3766             :   ReadOnlyRoots roots(heap());
    3767             :   if (elements != roots.empty_fixed_array() &&
    3768             :       elements != roots.empty_slow_element_dictionary()) {
    3769             :     DCHECK_EQ(false, cell_reports_intact);
    3770             :     return cell_reports_intact;
    3771             :   }
    3772             : 
    3773             :   // Check that the Object.prototype hasn't been altered WRT empty elements.
    3774             :   elements = initial_object_proto->elements();
    3775             :   if (elements != roots.empty_fixed_array() &&
    3776             :       elements != roots.empty_slow_element_dictionary()) {
    3777             :     DCHECK_EQ(false, cell_reports_intact);
    3778             :     return cell_reports_intact;
    3779             :   }
    3780             : 
    3781             :   // Check that the Array.prototype has the Object.prototype as its
    3782             :   // [[Prototype]] and that the Object.prototype has a null [[Prototype]].
    3783             :   PrototypeIterator iter(this, initial_array_proto);
    3784             :   if (iter.IsAtEnd() || iter.GetCurrent() != initial_object_proto) {
    3785             :     DCHECK_EQ(false, cell_reports_intact);
    3786             :     DCHECK(!has_pending_exception());
    3787             :     return cell_reports_intact;
    3788             :   }
    3789             :   iter.Advance();
    3790             :   if (!iter.IsAtEnd()) {
    3791             :     DCHECK_EQ(false, cell_reports_intact);
    3792             :     DCHECK(!has_pending_exception());
    3793             :     return cell_reports_intact;
    3794             :   }
    3795             :   DCHECK(!has_pending_exception());
    3796             : 
    3797             :   // Check that the String.prototype hasn't been altered WRT empty elements.
    3798             :   elements = initial_string_proto->elements();
    3799             :   if (elements != roots.empty_fixed_array() &&
    3800             :       elements != roots.empty_slow_element_dictionary()) {
    3801             :     DCHECK_EQ(false, cell_reports_intact);
    3802             :     return cell_reports_intact;
    3803             :   }
    3804             : 
    3805             :   // Check that the String.prototype has the Object.prototype
    3806             :   // as its [[Prototype]] still.
    3807             :   if (initial_string_proto->map()->prototype() != initial_object_proto) {
    3808             :     DCHECK_EQ(false, cell_reports_intact);
    3809             :     return cell_reports_intact;
    3810             :   }
    3811             : #endif
    3812             : 
    3813       99430 :   return cell_reports_intact;
    3814             : }
    3815             : 
    3816     5726915 : bool Isolate::IsNoElementsProtectorIntact() {
    3817     5726915 :   return Isolate::IsNoElementsProtectorIntact(context());
    3818             : }
    3819             : 
    3820      300905 : bool Isolate::IsIsConcatSpreadableLookupChainIntact() {
    3821             :   Cell is_concat_spreadable_cell = heap()->is_concat_spreadable_protector();
    3822             :   bool is_is_concat_spreadable_set =
    3823             :       Smi::ToInt(is_concat_spreadable_cell->value()) == kProtectorInvalid;
    3824             : #ifdef DEBUG
    3825             :   Map root_array_map =
    3826             :       raw_native_context()->GetInitialJSArrayMap(GetInitialFastElementsKind());
    3827             :   if (root_array_map.is_null()) {
    3828             :     // Ignore the value of is_concat_spreadable during bootstrap.
    3829             :     return !is_is_concat_spreadable_set;
    3830             :   }
    3831             :   Handle<Object> array_prototype(array_function()->prototype(), this);
    3832             :   Handle<Symbol> key = factory()->is_concat_spreadable_symbol();
    3833             :   Handle<Object> value;
    3834             :   LookupIterator it(this, array_prototype, key);
    3835             :   if (it.IsFound() && !JSReceiver::GetDataProperty(&it)->IsUndefined(this)) {
    3836             :     // TODO(cbruni): Currently we do not revert if we unset the
    3837             :     // @@isConcatSpreadable property on Array.prototype or Object.prototype
    3838             :     // hence the reverse implication doesn't hold.
    3839             :     DCHECK(is_is_concat_spreadable_set);
    3840             :     return false;
    3841             :   }
    3842             : #endif  // DEBUG
    3843             : 
    3844      300905 :   return !is_is_concat_spreadable_set;
    3845             : }
    3846             : 
    3847       10321 : bool Isolate::IsIsConcatSpreadableLookupChainIntact(JSReceiver receiver) {
    3848       10321 :   if (!IsIsConcatSpreadableLookupChainIntact()) return false;
    3849        4216 :   return !receiver->HasProxyInPrototype(this);
    3850             : }
    3851             : 
    3852           0 : bool Isolate::IsPromiseHookProtectorIntact() {
    3853             :   PropertyCell promise_hook_cell = heap()->promise_hook_protector();
    3854             :   bool is_promise_hook_protector_intact =
    3855           0 :       Smi::ToInt(promise_hook_cell->value()) == kProtectorValid;
    3856             :   DCHECK_IMPLIES(is_promise_hook_protector_intact,
    3857             :                  !promise_hook_or_async_event_delegate_);
    3858             :   DCHECK_IMPLIES(is_promise_hook_protector_intact,
    3859             :                  !promise_hook_or_debug_is_active_or_async_event_delegate_);
    3860           0 :   return is_promise_hook_protector_intact;
    3861             : }
    3862             : 
    3863        1728 : bool Isolate::IsPromiseResolveLookupChainIntact() {
    3864             :   Cell promise_resolve_cell = heap()->promise_resolve_protector();
    3865             :   bool is_promise_resolve_protector_intact =
    3866        1728 :       Smi::ToInt(promise_resolve_cell->value()) == kProtectorValid;
    3867        1728 :   return is_promise_resolve_protector_intact;
    3868             : }
    3869             : 
    3870        1686 : bool Isolate::IsPromiseThenLookupChainIntact() {
    3871             :   PropertyCell promise_then_cell = heap()->promise_then_protector();
    3872             :   bool is_promise_then_protector_intact =
    3873        3216 :       Smi::ToInt(promise_then_cell->value()) == kProtectorValid;
    3874        1686 :   return is_promise_then_protector_intact;
    3875             : }
    3876             : 
    3877        3590 : bool Isolate::IsPromiseThenLookupChainIntact(Handle<JSReceiver> receiver) {
    3878             :   DisallowHeapAllocation no_gc;
    3879        3590 :   if (!receiver->IsJSPromise()) return false;
    3880        1530 :   if (!IsInAnyContext(receiver->map()->prototype(),
    3881             :                       Context::PROMISE_PROTOTYPE_INDEX)) {
    3882             :     return false;
    3883             :   }
    3884        1530 :   return IsPromiseThenLookupChainIntact();
    3885             : }
    3886             : 
    3887     1199874 : void Isolate::UpdateNoElementsProtectorOnSetElement(Handle<JSObject> object) {
    3888             :   DisallowHeapAllocation no_gc;
    3889     1199874 :   if (!object->map()->is_prototype_map()) return;
    3890       16728 :   if (!IsNoElementsProtectorIntact()) return;
    3891       15309 :   if (!IsArrayOrObjectOrStringPrototype(*object)) return;
    3892         843 :   PropertyCell::SetValueWithInvalidation(
    3893             :       this, factory()->no_elements_protector(),
    3894         843 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3895             : }
    3896             : 
    3897          65 : void Isolate::InvalidateIsConcatSpreadableProtector() {
    3898             :   DCHECK(factory()->is_concat_spreadable_protector()->value()->IsSmi());
    3899             :   DCHECK(IsIsConcatSpreadableLookupChainIntact());
    3900         130 :   factory()->is_concat_spreadable_protector()->set_value(
    3901         195 :       Smi::FromInt(kProtectorInvalid));
    3902             :   DCHECK(!IsIsConcatSpreadableLookupChainIntact());
    3903          65 : }
    3904             : 
    3905         230 : void Isolate::InvalidateArrayConstructorProtector() {
    3906             :   DCHECK(factory()->array_constructor_protector()->value()->IsSmi());
    3907             :   DCHECK(IsArrayConstructorIntact());
    3908         460 :   factory()->array_constructor_protector()->set_value(
    3909         690 :       Smi::FromInt(kProtectorInvalid));
    3910             :   DCHECK(!IsArrayConstructorIntact());
    3911         230 : }
    3912             : 
    3913         118 : void Isolate::InvalidateArraySpeciesProtector() {
    3914             :   DCHECK(factory()->array_species_protector()->value()->IsSmi());
    3915             :   DCHECK(IsArraySpeciesLookupChainIntact());
    3916         118 :   PropertyCell::SetValueWithInvalidation(
    3917             :       this, factory()->array_species_protector(),
    3918         118 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3919             :   DCHECK(!IsArraySpeciesLookupChainIntact());
    3920         118 : }
    3921             : 
    3922         245 : void Isolate::InvalidateTypedArraySpeciesProtector() {
    3923             :   DCHECK(factory()->typed_array_species_protector()->value()->IsSmi());
    3924             :   DCHECK(IsTypedArraySpeciesLookupChainIntact());
    3925         245 :   PropertyCell::SetValueWithInvalidation(
    3926             :       this, factory()->typed_array_species_protector(),
    3927         245 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3928             :   DCHECK(!IsTypedArraySpeciesLookupChainIntact());
    3929         245 : }
    3930             : 
    3931          25 : void Isolate::InvalidateRegExpSpeciesProtector() {
    3932             :   DCHECK(factory()->regexp_species_protector()->value()->IsSmi());
    3933             :   DCHECK(IsRegExpSpeciesLookupChainIntact());
    3934          25 :   PropertyCell::SetValueWithInvalidation(
    3935             :       this, factory()->regexp_species_protector(),
    3936          25 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3937             :   DCHECK(!IsRegExpSpeciesLookupChainIntact());
    3938          25 : }
    3939             : 
    3940          59 : void Isolate::InvalidatePromiseSpeciesProtector() {
    3941             :   DCHECK(factory()->promise_species_protector()->value()->IsSmi());
    3942             :   DCHECK(IsPromiseSpeciesLookupChainIntact());
    3943          59 :   PropertyCell::SetValueWithInvalidation(
    3944             :       this, factory()->promise_species_protector(),
    3945          59 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3946             :   DCHECK(!IsPromiseSpeciesLookupChainIntact());
    3947          59 : }
    3948             : 
    3949         158 : void Isolate::InvalidateStringLengthOverflowProtector() {
    3950             :   DCHECK(factory()->string_length_protector()->value()->IsSmi());
    3951             :   DCHECK(IsStringLengthOverflowIntact());
    3952         316 :   factory()->string_length_protector()->set_value(
    3953         474 :       Smi::FromInt(kProtectorInvalid));
    3954             :   DCHECK(!IsStringLengthOverflowIntact());
    3955         158 : }
    3956             : 
    3957         107 : void Isolate::InvalidateArrayIteratorProtector() {
    3958             :   DCHECK(factory()->array_iterator_protector()->value()->IsSmi());
    3959             :   DCHECK(IsArrayIteratorLookupChainIntact());
    3960         107 :   PropertyCell::SetValueWithInvalidation(
    3961             :       this, factory()->array_iterator_protector(),
    3962         107 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3963             :   DCHECK(!IsArrayIteratorLookupChainIntact());
    3964         107 : }
    3965             : 
    3966          55 : void Isolate::InvalidateMapIteratorProtector() {
    3967             :   DCHECK(factory()->map_iterator_protector()->value()->IsSmi());
    3968             :   DCHECK(IsMapIteratorLookupChainIntact());
    3969          55 :   PropertyCell::SetValueWithInvalidation(
    3970             :       this, factory()->map_iterator_protector(),
    3971          55 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3972             :   DCHECK(!IsMapIteratorLookupChainIntact());
    3973          55 : }
    3974             : 
    3975          65 : void Isolate::InvalidateSetIteratorProtector() {
    3976             :   DCHECK(factory()->set_iterator_protector()->value()->IsSmi());
    3977             :   DCHECK(IsSetIteratorLookupChainIntact());
    3978          65 :   PropertyCell::SetValueWithInvalidation(
    3979             :       this, factory()->set_iterator_protector(),
    3980          65 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3981             :   DCHECK(!IsSetIteratorLookupChainIntact());
    3982          65 : }
    3983             : 
    3984          25 : void Isolate::InvalidateStringIteratorProtector() {
    3985             :   DCHECK(factory()->string_iterator_protector()->value()->IsSmi());
    3986             :   DCHECK(IsStringIteratorLookupChainIntact());
    3987          25 :   PropertyCell::SetValueWithInvalidation(
    3988             :       this, factory()->string_iterator_protector(),
    3989          25 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3990             :   DCHECK(!IsStringIteratorLookupChainIntact());
    3991          25 : }
    3992             : 
    3993         434 : void Isolate::InvalidateArrayBufferDetachingProtector() {
    3994             :   DCHECK(factory()->array_buffer_detaching_protector()->value()->IsSmi());
    3995             :   DCHECK(IsArrayBufferDetachingIntact());
    3996         434 :   PropertyCell::SetValueWithInvalidation(
    3997             :       this, factory()->array_buffer_detaching_protector(),
    3998         434 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3999             :   DCHECK(!IsArrayBufferDetachingIntact());
    4000         434 : }
    4001             : 
    4002        2777 : void Isolate::InvalidatePromiseHookProtector() {
    4003             :   DCHECK(factory()->promise_hook_protector()->value()->IsSmi());
    4004             :   DCHECK(IsPromiseHookProtectorIntact());
    4005        2777 :   PropertyCell::SetValueWithInvalidation(
    4006             :       this, factory()->promise_hook_protector(),
    4007        2777 :       handle(Smi::FromInt(kProtectorInvalid), this));
    4008             :   DCHECK(!IsPromiseHookProtectorIntact());
    4009        2777 : }
    4010             : 
    4011           0 : void Isolate::InvalidatePromiseResolveProtector() {
    4012             :   DCHECK(factory()->promise_resolve_protector()->value()->IsSmi());
    4013             :   DCHECK(IsPromiseResolveLookupChainIntact());
    4014           0 :   factory()->promise_resolve_protector()->set_value(
    4015           0 :       Smi::FromInt(kProtectorInvalid));
    4016             :   DCHECK(!IsPromiseResolveLookupChainIntact());
    4017           0 : }
    4018             : 
    4019         103 : void Isolate::InvalidatePromiseThenProtector() {
    4020             :   DCHECK(factory()->promise_then_protector()->value()->IsSmi());
    4021             :   DCHECK(IsPromiseThenLookupChainIntact());
    4022         103 :   PropertyCell::SetValueWithInvalidation(
    4023             :       this, factory()->promise_then_protector(),
    4024         103 :       handle(Smi::FromInt(kProtectorInvalid), this));
    4025             :   DCHECK(!IsPromiseThenLookupChainIntact());
    4026         103 : }
    4027             : 
    4028     6490230 : bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
    4029             :   DisallowHeapAllocation no_gc;
    4030     6490230 :   return IsInAnyContext(*array, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
    4031             : }
    4032             : 
    4033      126357 : static base::RandomNumberGenerator* ensure_rng_exists(
    4034             :     base::RandomNumberGenerator** rng, int seed) {
    4035      126357 :   if (*rng == nullptr) {
    4036       61416 :     if (seed != 0) {
    4037      119872 :       *rng = new base::RandomNumberGenerator(seed);
    4038             :     } else {
    4039        1480 :       *rng = new base::RandomNumberGenerator();
    4040             :     }
    4041             :   }
    4042      126357 :   return *rng;
    4043             : }
    4044             : 
    4045       72377 : base::RandomNumberGenerator* Isolate::random_number_generator() {
    4046             :   // TODO(bmeurer) Initialized lazily because it depends on flags; can
    4047             :   // be fixed once the default isolate cleanup is done.
    4048      126357 :   return ensure_rng_exists(&random_number_generator_, FLAG_random_seed);
    4049             : }
    4050             : 
    4051           0 : base::RandomNumberGenerator* Isolate::fuzzer_rng() {
    4052           0 :   if (fuzzer_rng_ == nullptr) {
    4053           0 :     int64_t seed = FLAG_fuzzer_random_seed;
    4054           0 :     if (seed == 0) {
    4055             :       seed = random_number_generator()->initial_seed();
    4056             :     }
    4057             : 
    4058           0 :     fuzzer_rng_ = new base::RandomNumberGenerator(seed);
    4059             :   }
    4060             : 
    4061           0 :   return fuzzer_rng_;
    4062             : }
    4063             : 
    4064       53980 : int Isolate::GenerateIdentityHash(uint32_t mask) {
    4065             :   int hash;
    4066             :   int attempts = 0;
    4067       53980 :   do {
    4068       53980 :     hash = random_number_generator()->NextInt() & mask;
    4069       53980 :   } while (hash == 0 && attempts++ < 30);
    4070       53980 :   return hash != 0 ? hash : 1;
    4071             : }
    4072             : 
    4073       25129 : Code Isolate::FindCodeObject(Address a) {
    4074       25129 :   return heap()->GcSafeFindCodeForInnerPointer(a);
    4075             : }
    4076             : 
    4077             : 
    4078             : #ifdef DEBUG
    4079             : #define ISOLATE_FIELD_OFFSET(type, name, ignored)                       \
    4080             : const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
    4081             : ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
    4082             : ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
    4083             : #undef ISOLATE_FIELD_OFFSET
    4084             : #endif
    4085             : 
    4086      254999 : Handle<Symbol> Isolate::SymbolFor(RootIndex dictionary_index,
    4087             :                                   Handle<String> name, bool private_symbol) {
    4088      254999 :   Handle<String> key = factory()->InternalizeString(name);
    4089             :   Handle<NameDictionary> dictionary =
    4090             :       Handle<NameDictionary>::cast(root_handle(dictionary_index));
    4091      254999 :   int entry = dictionary->FindEntry(this, key);
    4092             :   Handle<Symbol> symbol;
    4093      254999 :   if (entry == NameDictionary::kNotFound) {
    4094             :     symbol =
    4095        2715 :         private_symbol ? factory()->NewPrivateSymbol() : factory()->NewSymbol();
    4096        5430 :     symbol->set_name(*key);
    4097             :     dictionary = NameDictionary::Add(this, dictionary, key, symbol,
    4098        2715 :                                      PropertyDetails::Empty(), &entry);
    4099        2715 :     switch (dictionary_index) {
    4100             :       case RootIndex::kPublicSymbolTable:
    4101             :         symbol->set_is_public(true);
    4102             :         heap()->set_public_symbol_table(*dictionary);
    4103             :         break;
    4104             :       case RootIndex::kApiSymbolTable:
    4105             :         heap()->set_api_symbol_table(*dictionary);
    4106             :         break;
    4107             :       case RootIndex::kApiPrivateSymbolTable:
    4108             :         heap()->set_api_private_symbol_table(*dictionary);
    4109             :         break;
    4110             :       default:
    4111           0 :         UNREACHABLE();
    4112             :     }
    4113             :   } else {
    4114      504568 :     symbol = Handle<Symbol>(Symbol::cast(dictionary->ValueAt(entry)), this);
    4115             :   }
    4116      254999 :   return symbol;
    4117             : }
    4118             : 
    4119          15 : void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
    4120             :   auto pos = std::find(before_call_entered_callbacks_.begin(),
    4121          15 :                        before_call_entered_callbacks_.end(), callback);
    4122          20 :   if (pos != before_call_entered_callbacks_.end()) return;
    4123          10 :   before_call_entered_callbacks_.push_back(callback);
    4124             : }
    4125             : 
    4126           5 : void Isolate::RemoveBeforeCallEnteredCallback(
    4127             :     BeforeCallEnteredCallback callback) {
    4128             :   auto pos = std::find(before_call_entered_callbacks_.begin(),
    4129           5 :                        before_call_entered_callbacks_.end(), callback);
    4130           5 :   if (pos == before_call_entered_callbacks_.end()) return;
    4131           5 :   before_call_entered_callbacks_.erase(pos);
    4132             : }
    4133             : 
    4134          65 : void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
    4135             :   auto pos = std::find(call_completed_callbacks_.begin(),
    4136          65 :                        call_completed_callbacks_.end(), callback);
    4137          70 :   if (pos != call_completed_callbacks_.end()) return;
    4138          60 :   call_completed_callbacks_.push_back(callback);
    4139             : }
    4140             : 
    4141        3717 : void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
    4142             :   auto pos = std::find(call_completed_callbacks_.begin(),
    4143        3717 :                        call_completed_callbacks_.end(), callback);
    4144        3717 :   if (pos == call_completed_callbacks_.end()) return;
    4145          45 :   call_completed_callbacks_.erase(pos);
    4146             : }
    4147             : 
    4148     5425377 : void Isolate::FireCallCompletedCallback(MicrotaskQueue* microtask_queue) {
    4149    10850720 :   if (!handle_scope_implementer()->CallDepthIsZero()) return;
    4150             : 
    4151             :   bool run_microtasks =
    4152      545518 :       microtask_queue && microtask_queue->size() &&
    4153      572561 :       !microtask_queue->HasMicrotasksSuppressions() &&
    4154             :       microtask_queue->microtasks_policy() == v8::MicrotasksPolicy::kAuto;
    4155             : 
    4156      545518 :   if (run_microtasks) {
    4157        1948 :     microtask_queue->RunMicrotasks(this);
    4158             :   } else {
    4159             :     // TODO(marja): (spec) The discussion about when to clear the KeepDuringJob
    4160             :     // set is still open (whether to clear it after every microtask or once
    4161             :     // during a microtask checkpoint). See also
    4162             :     // https://github.com/tc39/proposal-weakrefs/issues/39 .
    4163      543570 :     heap()->ClearKeepDuringJobSet();
    4164             :   }
    4165             : 
    4166      545514 :   if (call_completed_callbacks_.empty()) return;
    4167             :   // Fire callbacks.  Increase call depth to prevent recursive callbacks.
    4168             :   v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this);
    4169          60 :   v8::Isolate::SuppressMicrotaskExecutionScope suppress(isolate);
    4170          30 :   std::vector<CallCompletedCallback> callbacks(call_completed_callbacks_);
    4171          65 :   for (auto& callback : callbacks) {
    4172          35 :     callback(reinterpret_cast<v8::Isolate*>(this));
    4173             :   }
    4174             : }
    4175             : 
    4176        8457 : void Isolate::PromiseHookStateUpdated() {
    4177             :   bool promise_hook_or_async_event_delegate =
    4178        8457 :       promise_hook_ || async_event_delegate_;
    4179             :   bool promise_hook_or_debug_is_active_or_async_event_delegate =
    4180        8457 :       promise_hook_or_async_event_delegate || debug()->is_active();
    4181       12936 :   if (promise_hook_or_debug_is_active_or_async_event_delegate &&
    4182             :       IsPromiseHookProtectorIntact()) {
    4183             :     HandleScope scope(this);
    4184        2776 :     InvalidatePromiseHookProtector();
    4185             :   }
    4186        8457 :   promise_hook_or_async_event_delegate_ = promise_hook_or_async_event_delegate;
    4187             :   promise_hook_or_debug_is_active_or_async_event_delegate_ =
    4188        8457 :       promise_hook_or_debug_is_active_or_async_event_delegate;
    4189        8457 : }
    4190             : 
    4191             : namespace {
    4192             : 
    4193          72 : MaybeHandle<JSPromise> NewRejectedPromise(Isolate* isolate,
    4194             :                                           v8::Local<v8::Context> api_context,
    4195             :                                           Handle<Object> exception) {
    4196             :   v8::Local<v8::Promise::Resolver> resolver;
    4197         144 :   ASSIGN_RETURN_ON_SCHEDULED_EXCEPTION_VALUE(
    4198             :       isolate, resolver, v8::Promise::Resolver::New(api_context),
    4199             :       MaybeHandle<JSPromise>());
    4200             : 
    4201         144 :   RETURN_ON_SCHEDULED_EXCEPTION_VALUE(
    4202             :       isolate, resolver->Reject(api_context, v8::Utils::ToLocal(exception)),
    4203             :       MaybeHandle<JSPromise>());
    4204             : 
    4205          72 :   v8::Local<v8::Promise> promise = resolver->GetPromise();
    4206          72 :   return v8::Utils::OpenHandle(*promise);
    4207             : }
    4208             : 
    4209             : }  // namespace
    4210             : 
    4211         482 : MaybeHandle<JSPromise> Isolate::RunHostImportModuleDynamicallyCallback(
    4212             :     Handle<Script> referrer, Handle<Object> specifier) {
    4213             :   v8::Local<v8::Context> api_context =
    4214         482 :       v8::Utils::ToLocal(Handle<Context>(native_context()));
    4215             : 
    4216         482 :   if (host_import_module_dynamically_callback_ == nullptr) {
    4217             :     Handle<Object> exception =
    4218           0 :         factory()->NewError(error_function(), MessageTemplate::kUnsupported);
    4219           0 :     return NewRejectedPromise(this, api_context, exception);
    4220             :   }
    4221             : 
    4222             :   Handle<String> specifier_str;
    4223         482 :   MaybeHandle<String> maybe_specifier = Object::ToString(this, specifier);
    4224         482 :   if (!maybe_specifier.ToHandle(&specifier_str)) {
    4225             :     Handle<Object> exception(pending_exception(), this);
    4226             :     clear_pending_exception();
    4227             : 
    4228          72 :     return NewRejectedPromise(this, api_context, exception);
    4229             :   }
    4230             :   DCHECK(!has_pending_exception());
    4231             : 
    4232             :   v8::Local<v8::Promise> promise;
    4233         820 :   ASSIGN_RETURN_ON_SCHEDULED_EXCEPTION_VALUE(
    4234             :       this, promise,
    4235             :       host_import_module_dynamically_callback_(
    4236             :           api_context, v8::Utils::ScriptOrModuleToLocal(referrer),
    4237             :           v8::Utils::ToLocal(specifier_str)),
    4238             :       MaybeHandle<JSPromise>());
    4239         410 :   return v8::Utils::OpenHandle(*promise);
    4240             : }
    4241             : 
    4242       30493 : void Isolate::SetHostImportModuleDynamicallyCallback(
    4243             :     HostImportModuleDynamicallyCallback callback) {
    4244       30493 :   host_import_module_dynamically_callback_ = callback;
    4245       30493 : }
    4246             : 
    4247          39 : Handle<JSObject> Isolate::RunHostInitializeImportMetaObjectCallback(
    4248             :     Handle<Module> module) {
    4249             :   Handle<Object> host_meta(module->import_meta(), this);
    4250          39 :   if (host_meta->IsTheHole(this)) {
    4251          23 :     host_meta = factory()->NewJSObjectWithNullProto();
    4252          23 :     if (host_initialize_import_meta_object_callback_ != nullptr) {
    4253             :       v8::Local<v8::Context> api_context =
    4254          23 :           v8::Utils::ToLocal(Handle<Context>(native_context()));
    4255          23 :       host_initialize_import_meta_object_callback_(
    4256             :           api_context, Utils::ToLocal(module),
    4257          23 :           v8::Local<v8::Object>::Cast(v8::Utils::ToLocal(host_meta)));
    4258             :     }
    4259          23 :     module->set_import_meta(*host_meta);
    4260             :   }
    4261          39 :   return Handle<JSObject>::cast(host_meta);
    4262             : }
    4263             : 
    4264       30493 : void Isolate::SetHostInitializeImportMetaObjectCallback(
    4265             :     HostInitializeImportMetaObjectCallback callback) {
    4266       30493 :   host_initialize_import_meta_object_callback_ = callback;
    4267       30493 : }
    4268             : 
    4269          12 : MaybeHandle<Object> Isolate::RunPrepareStackTraceCallback(
    4270             :     Handle<Context> context, Handle<JSObject> error, Handle<JSArray> sites) {
    4271          12 :   v8::Local<v8::Context> api_context = Utils::ToLocal(context);
    4272             : 
    4273             :   v8::Local<v8::Value> stack;
    4274          42 :   ASSIGN_RETURN_ON_SCHEDULED_EXCEPTION_VALUE(
    4275             :       this, stack,
    4276             :       prepare_stack_trace_callback_(api_context, Utils::ToLocal(error),
    4277             :                                     Utils::ToLocal(sites)),
    4278             :       MaybeHandle<Object>());
    4279           6 :   return Utils::OpenHandle(*stack);
    4280             : }
    4281             : 
    4282      863532 : int Isolate::LookupOrAddExternallyCompiledFilename(const char* filename) {
    4283      863532 :   if (embedded_file_writer_ != nullptr) {
    4284             :     return embedded_file_writer_->LookupOrAddExternallyCompiledFilename(
    4285       15419 :         filename);
    4286             :   }
    4287             :   return 0;
    4288             : }
    4289             : 
    4290           0 : const char* Isolate::GetExternallyCompiledFilename(int index) const {
    4291           0 :   if (embedded_file_writer_ != nullptr) {
    4292           0 :     return embedded_file_writer_->GetExternallyCompiledFilename(index);
    4293             :   }
    4294             :   return "";
    4295             : }
    4296             : 
    4297           0 : int Isolate::GetExternallyCompiledFilenameCount() const {
    4298           0 :   if (embedded_file_writer_ != nullptr) {
    4299           0 :     return embedded_file_writer_->GetExternallyCompiledFilenameCount();
    4300             :   }
    4301             :   return 0;
    4302             : }
    4303             : 
    4304           0 : void Isolate::PrepareBuiltinSourcePositionMap() {
    4305          56 :   if (embedded_file_writer_ != nullptr) {
    4306             :     return embedded_file_writer_->PrepareBuiltinSourcePositionMap(
    4307           2 :         this->builtins());
    4308             :   }
    4309             : }
    4310             : 
    4311          12 : void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) {
    4312          12 :   prepare_stack_trace_callback_ = callback;
    4313          12 : }
    4314             : 
    4315       15186 : bool Isolate::HasPrepareStackTraceCallback() const {
    4316       15186 :   return prepare_stack_trace_callback_ != nullptr;
    4317             : }
    4318             : 
    4319          13 : void Isolate::SetAtomicsWaitCallback(v8::Isolate::AtomicsWaitCallback callback,
    4320             :                                      void* data) {
    4321          13 :   atomics_wait_callback_ = callback;
    4322          13 :   atomics_wait_callback_data_ = data;
    4323          13 : }
    4324             : 
    4325        1833 : void Isolate::RunAtomicsWaitCallback(v8::Isolate::AtomicsWaitEvent event,
    4326             :                                      Handle<JSArrayBuffer> array_buffer,
    4327             :                                      size_t offset_in_bytes, int64_t value,
    4328             :                                      double timeout_in_ms,
    4329             :                                      AtomicsWaitWakeHandle* stop_handle) {
    4330             :   DCHECK(array_buffer->is_shared());
    4331        1833 :   if (atomics_wait_callback_ == nullptr) return;
    4332             :   HandleScope handle_scope(this);
    4333         169 :   atomics_wait_callback_(
    4334             :       event, v8::Utils::ToLocalShared(array_buffer), offset_in_bytes, value,
    4335             :       timeout_in_ms,
    4336             :       reinterpret_cast<v8::Isolate::AtomicsWaitWakeHandle*>(stop_handle),
    4337         169 :       atomics_wait_callback_data_);
    4338             : }
    4339             : 
    4340         119 : void Isolate::SetPromiseHook(PromiseHook hook) {
    4341         119 :   promise_hook_ = hook;
    4342         119 :   PromiseHookStateUpdated();
    4343         119 : }
    4344             : 
    4345       99015 : void Isolate::RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise,
    4346             :                              Handle<Object> parent) {
    4347       99015 :   RunPromiseHookForAsyncEventDelegate(type, promise);
    4348       99015 :   if (promise_hook_ == nullptr) return;
    4349             :   promise_hook_(type, v8::Utils::PromiseToLocal(promise),
    4350        1145 :                 v8::Utils::ToLocal(parent));
    4351             : }
    4352             : 
    4353       99015 : void Isolate::RunPromiseHookForAsyncEventDelegate(PromiseHookType type,
    4354             :                                                   Handle<JSPromise> promise) {
    4355       99015 :   if (!async_event_delegate_) return;
    4356       37139 :   if (type == PromiseHookType::kResolve) return;
    4357             : 
    4358       21822 :   if (type == PromiseHookType::kBefore) {
    4359        3655 :     if (!promise->async_task_id()) return;
    4360        6345 :     async_event_delegate_->AsyncEventOccurred(debug::kDebugWillHandle,
    4361        4230 :                                               promise->async_task_id(), false);
    4362       18167 :   } else if (type == PromiseHookType::kAfter) {
    4363        3650 :     if (!promise->async_task_id()) return;
    4364        6300 :     async_event_delegate_->AsyncEventOccurred(debug::kDebugDidHandle,
    4365        4200 :                                               promise->async_task_id(), false);
    4366             :   } else {
    4367             :     DCHECK(type == PromiseHookType::kInit);
    4368             :     debug::DebugAsyncActionType type = debug::kDebugPromiseThen;
    4369             :     bool last_frame_was_promise_builtin = false;
    4370       14517 :     JavaScriptFrameIterator it(this);
    4371       28649 :     while (!it.done()) {
    4372             :       std::vector<Handle<SharedFunctionInfo>> infos;
    4373       26474 :       it.frame()->GetFunctions(&infos);
    4374       54738 :       for (size_t i = 1; i <= infos.size(); ++i) {
    4375       52948 :         Handle<SharedFunctionInfo> info = infos[infos.size() - i];
    4376       26474 :         if (info->IsUserJavaScript()) {
    4377             :           // We should not report PromiseThen and PromiseCatch which is called
    4378             :           // indirectly, e.g. Promise.all calls Promise.then internally.
    4379       12342 :           if (last_frame_was_promise_builtin) {
    4380        1855 :             if (!promise->async_task_id()) {
    4381        3710 :               promise->set_async_task_id(++async_task_count_);
    4382             :             }
    4383        7420 :             async_event_delegate_->AsyncEventOccurred(
    4384        3710 :                 type, promise->async_task_id(), debug()->IsBlackboxed(info));
    4385             :           }
    4386             :           return;
    4387             :         }
    4388             :         last_frame_was_promise_builtin = false;
    4389       14132 :         if (info->HasBuiltinId()) {
    4390       14132 :           if (info->builtin_id() == Builtins::kPromisePrototypeThen) {
    4391             :             type = debug::kDebugPromiseThen;
    4392             :             last_frame_was_promise_builtin = true;
    4393       10782 :           } else if (info->builtin_id() == Builtins::kPromisePrototypeCatch) {
    4394             :             type = debug::kDebugPromiseCatch;
    4395             :             last_frame_was_promise_builtin = true;
    4396       10482 :           } else if (info->builtin_id() == Builtins::kPromisePrototypeFinally) {
    4397             :             type = debug::kDebugPromiseFinally;
    4398             :             last_frame_was_promise_builtin = true;
    4399             :           }
    4400             :         }
    4401             :       }
    4402       14132 :       it.Advance();
    4403             :     }
    4404             :   }
    4405             : }
    4406             : 
    4407        3692 : void Isolate::OnAsyncFunctionStateChanged(Handle<JSPromise> promise,
    4408             :                                           debug::DebugAsyncActionType event) {
    4409        3692 :   if (!async_event_delegate_) return;
    4410         440 :   if (!promise->async_task_id()) {
    4411         370 :     promise->set_async_task_id(++async_task_count_);
    4412             :   }
    4413        1320 :   async_event_delegate_->AsyncEventOccurred(event, promise->async_task_id(),
    4414         880 :                                             false);
    4415             : }
    4416             : 
    4417        1150 : void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
    4418        1150 :   promise_reject_callback_ = callback;
    4419        1150 : }
    4420             : 
    4421       15573 : void Isolate::ReportPromiseReject(Handle<JSPromise> promise,
    4422             :                                   Handle<Object> value,
    4423             :                                   v8::PromiseRejectEvent event) {
    4424       15573 :   if (promise_reject_callback_ == nullptr) return;
    4425         490 :   promise_reject_callback_(v8::PromiseRejectMessage(
    4426         490 :       v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value)));
    4427             : }
    4428             : 
    4429          60 : void Isolate::SetUseCounterCallback(v8::Isolate::UseCounterCallback callback) {
    4430             :   DCHECK(!use_counter_callback_);
    4431          60 :   use_counter_callback_ = callback;
    4432          60 : }
    4433             : 
    4434             : 
    4435     2337526 : void Isolate::CountUsage(v8::Isolate::UseCounterFeature feature) {
    4436             :   // The counter callback may cause the embedder to call into V8, which is not
    4437             :   // generally possible during GC.
    4438     2337526 :   if (heap_.gc_state() == Heap::NOT_IN_GC) {
    4439     2337526 :     if (use_counter_callback_) {
    4440             :       HandleScope handle_scope(this);
    4441         199 :       use_counter_callback_(reinterpret_cast<v8::Isolate*>(this), feature);
    4442             :     }
    4443             :   } else {
    4444           0 :     heap_.IncrementDeferredCount(feature);
    4445             :   }
    4446     2337526 : }
    4447             : 
    4448             : // static
    4449          15 : std::string Isolate::GetTurboCfgFileName(Isolate* isolate) {
    4450          15 :   if (FLAG_trace_turbo_cfg_file == nullptr) {
    4451           0 :     std::ostringstream os;
    4452           0 :     os << "turbo-" << base::OS::GetCurrentProcessId() << "-";
    4453           0 :     if (isolate != nullptr) {
    4454           0 :       os << isolate->id();
    4455             :     } else {
    4456           0 :       os << "any";
    4457             :     }
    4458           0 :     os << ".cfg";
    4459             :     return os.str();
    4460             :   } else {
    4461          15 :     return FLAG_trace_turbo_cfg_file;
    4462             :   }
    4463             : }
    4464             : 
    4465             : // Heap::detached_contexts tracks detached contexts as pairs
    4466             : // (number of GC since the context was detached, the context).
    4467         121 : void Isolate::AddDetachedContext(Handle<Context> context) {
    4468             :   HandleScope scope(this);
    4469             :   Handle<WeakArrayList> detached_contexts = factory()->detached_contexts();
    4470             :   detached_contexts = WeakArrayList::AddToEnd(
    4471         121 :       this, detached_contexts, MaybeObjectHandle(Smi::kZero, this));
    4472             :   detached_contexts = WeakArrayList::AddToEnd(this, detached_contexts,
    4473         121 :                                               MaybeObjectHandle::Weak(context));
    4474             :   heap()->set_detached_contexts(*detached_contexts);
    4475         121 : }
    4476             : 
    4477             : 
    4478       73955 : void Isolate::CheckDetachedContextsAfterGC() {
    4479             :   HandleScope scope(this);
    4480             :   Handle<WeakArrayList> detached_contexts = factory()->detached_contexts();
    4481             :   int length = detached_contexts->length();
    4482       73955 :   if (length == 0) return;
    4483             :   int new_length = 0;
    4484         658 :   for (int i = 0; i < length; i += 2) {
    4485             :     int mark_sweeps = detached_contexts->Get(i).ToSmi().value();
    4486             :     MaybeObject context = detached_contexts->Get(i + 1);
    4487             :     DCHECK(context->IsWeakOrCleared());
    4488         298 :     if (!context->IsCleared()) {
    4489         732 :       detached_contexts->Set(
    4490         244 :           new_length, MaybeObject::FromSmi(Smi::FromInt(mark_sweeps + 1)));
    4491         488 :       detached_contexts->Set(new_length + 1, context);
    4492         244 :       new_length += 2;
    4493             :     }
    4494             :   }
    4495             :   detached_contexts->set_length(new_length);
    4496         278 :   while (new_length < length) {
    4497         108 :     detached_contexts->Set(new_length, MaybeObject::FromSmi(Smi::zero()));
    4498         108 :     ++new_length;
    4499             :   }
    4500             : 
    4501          62 :   if (FLAG_trace_detached_contexts) {
    4502           0 :     PrintF("%d detached contexts are collected out of %d\n",
    4503           0 :            length - new_length, length);
    4504           0 :     for (int i = 0; i < new_length; i += 2) {
    4505             :       int mark_sweeps = detached_contexts->Get(i).ToSmi().value();
    4506             :       MaybeObject context = detached_contexts->Get(i + 1);
    4507             :       DCHECK(context->IsWeakOrCleared());
    4508           0 :       if (mark_sweeps > 3) {
    4509           0 :         PrintF("detached context %p\n survived %d GCs (leak?)\n",
    4510           0 :                reinterpret_cast<void*>(context.ptr()), mark_sweeps);
    4511             :       }
    4512             :     }
    4513             :   }
    4514             : }
    4515             : 
    4516           0 : double Isolate::LoadStartTimeMs() {
    4517           0 :   base::MutexGuard guard(&rail_mutex_);
    4518           0 :   return load_start_time_ms_;
    4519             : }
    4520             : 
    4521           0 : void Isolate::SetRAILMode(RAILMode rail_mode) {
    4522             :   RAILMode old_rail_mode = rail_mode_.load();
    4523           0 :   if (old_rail_mode != PERFORMANCE_LOAD && rail_mode == PERFORMANCE_LOAD) {
    4524           0 :     base::MutexGuard guard(&rail_mutex_);
    4525           0 :     load_start_time_ms_ = heap()->MonotonicallyIncreasingTimeInMs();
    4526             :   }
    4527             :   rail_mode_.store(rail_mode);
    4528           0 :   if (old_rail_mode == PERFORMANCE_LOAD && rail_mode != PERFORMANCE_LOAD) {
    4529             :     heap()->incremental_marking()->incremental_marking_job()->ScheduleTask(
    4530           0 :         heap());
    4531             :   }
    4532           0 :   if (FLAG_trace_rail) {
    4533           0 :     PrintIsolate(this, "RAIL mode: %s\n", RAILModeName(rail_mode));
    4534             :   }
    4535           0 : }
    4536             : 
    4537           0 : void Isolate::IsolateInBackgroundNotification() {
    4538           0 :   is_isolate_in_background_ = true;
    4539           0 :   heap()->ActivateMemoryReducerIfNeeded();
    4540           0 : }
    4541             : 
    4542           0 : void Isolate::IsolateInForegroundNotification() {
    4543           0 :   is_isolate_in_background_ = false;
    4544           0 : }
    4545             : 
    4546          94 : void Isolate::PrintWithTimestamp(const char* format, ...) {
    4547          94 :   base::OS::Print("[%d:%p] %8.0f ms: ", base::OS::GetCurrentProcessId(),
    4548          94 :                   static_cast<void*>(this), time_millis_since_init());
    4549             :   va_list arguments;
    4550          94 :   va_start(arguments, format);
    4551          94 :   base::OS::VPrint(format, arguments);
    4552          94 :   va_end(arguments);
    4553          94 : }
    4554             : 
    4555          10 : void Isolate::SetIdle(bool is_idle) {
    4556          10 :   if (!is_profiling()) return;
    4557             :   StateTag state = current_vm_state();
    4558             :   DCHECK(state == EXTERNAL || state == IDLE);
    4559          10 :   if (js_entry_sp() != kNullAddress) return;
    4560          10 :   if (is_idle) {
    4561             :     set_current_vm_state(IDLE);
    4562           5 :   } else if (state == IDLE) {
    4563             :     set_current_vm_state(EXTERNAL);
    4564             :   }
    4565             : }
    4566             : 
    4567             : #ifdef V8_INTL_SUPPORT
    4568       64688 : icu::UObject* Isolate::get_cached_icu_object(ICUObjectCacheType cache_type) {
    4569       64688 :   return icu_object_cache_[cache_type].get();
    4570             : }
    4571             : 
    4572         104 : void Isolate::set_icu_object_in_cache(ICUObjectCacheType cache_type,
    4573             :                                       std::shared_ptr<icu::UObject> obj) {
    4574             :   icu_object_cache_[cache_type] = obj;
    4575         104 : }
    4576             : 
    4577           0 : void Isolate::clear_cached_icu_object(ICUObjectCacheType cache_type) {
    4578             :   icu_object_cache_.erase(cache_type);
    4579           0 : }
    4580             : #endif  // V8_INTL_SUPPORT
    4581             : 
    4582     2691266 : bool StackLimitCheck::JsHasOverflowed(uintptr_t gap) const {
    4583     2691266 :   StackGuard* stack_guard = isolate_->stack_guard();
    4584             : #ifdef USE_SIMULATOR
    4585             :   // The simulator uses a separate JS stack.
    4586             :   Address jssp_address = Simulator::current(isolate_)->get_sp();
    4587             :   uintptr_t jssp = static_cast<uintptr_t>(jssp_address);
    4588             :   if (jssp - gap < stack_guard->real_jslimit()) return true;
    4589             : #endif  // USE_SIMULATOR
    4590     2691266 :   return GetCurrentStackPosition() - gap < stack_guard->real_climit();
    4591             : }
    4592             : 
    4593    20559700 : SaveContext::SaveContext(Isolate* isolate) : isolate_(isolate) {
    4594    20559700 :   if (!isolate->context().is_null()) {
    4595    20356053 :     context_ = Handle<Context>(isolate->context(), isolate);
    4596             :   }
    4597             : 
    4598    20559710 :   c_entry_fp_ = isolate->c_entry_fp(isolate->thread_local_top());
    4599    20559710 : }
    4600             : 
    4601    41119416 : SaveContext::~SaveContext() {
    4602    41119416 :   isolate_->set_context(context_.is_null() ? Context() : *context_);
    4603    20559708 : }
    4604             : 
    4605           0 : bool SaveContext::IsBelowFrame(StandardFrame* frame) {
    4606           0 :   return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp());
    4607             : }
    4608             : 
    4609      370680 : SaveAndSwitchContext::SaveAndSwitchContext(Isolate* isolate,
    4610             :                                            Context new_context)
    4611      370680 :     : SaveContext(isolate) {
    4612             :   isolate->set_context(new_context);
    4613      370680 : }
    4614             : 
    4615             : #ifdef DEBUG
    4616             : AssertNoContextChange::AssertNoContextChange(Isolate* isolate)
    4617             :     : isolate_(isolate), context_(isolate->context(), isolate) {}
    4618             : #endif  // DEBUG
    4619             : 
    4620       73350 : bool InterruptsScope::Intercept(StackGuard::InterruptFlag flag) {
    4621             :   InterruptsScope* last_postpone_scope = nullptr;
    4622      220462 :   for (InterruptsScope* current = this; current; current = current->prev_) {
    4623             :     // We only consider scopes related to passed flag.
    4624       73718 :     if (!(current->intercept_mask_ & flag)) continue;
    4625       73324 :     if (current->mode_ == kRunInterrupts) {
    4626             :       // If innermost scope is kRunInterrupts scope, prevent interrupt from
    4627             :       // being intercepted.
    4628             :       break;
    4629             :     } else {
    4630             :       DCHECK_EQ(current->mode_, kPostponeInterrupts);
    4631             :       last_postpone_scope = current;
    4632             :     }
    4633             :   }
    4634             :   // If there is no postpone scope for passed flag then we should not intercept.
    4635       73350 :   if (!last_postpone_scope) return false;
    4636       72905 :   last_postpone_scope->intercepted_flags_ |= flag;
    4637       72905 :   return true;
    4638             : }
    4639             : 
    4640             : #undef TRACE_ISOLATE
    4641             : 
    4642             : }  // namespace internal
    4643      120216 : }  // namespace v8

Generated by: LCOV version 1.10