LCOV - code coverage report
Current view: top level - src - isolate.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1454 1708 85.1 %
Date: 2019-04-17 Functions: 197 234 84.2 %

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

Generated by: LCOV version 1.10