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-19 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       62441 : const uint8_t* DefaultEmbeddedBlob() { return v8_Default_embedded_blob_; }
     111       62441 : 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      126390 : 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       62496 : void Isolate::SetEmbeddedBlob(const uint8_t* blob, uint32_t blob_size) {
     217       62496 :   CHECK_NOT_NULL(blob);
     218             : 
     219       62496 :   embedded_blob_ = blob;
     220       62496 :   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       62496 : }
     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   205004877 : const uint8_t* Isolate::embedded_blob() const { return embedded_blob_; }
     251    97165341 : uint32_t Isolate::embedded_blob_size() const { return embedded_blob_size_; }
     252             : 
     253             : // static
     254   416162865 : const uint8_t* Isolate::CurrentEmbeddedBlob() {
     255   416162865 :   return current_embedded_blob_.load(std::memory_order::memory_order_relaxed);
     256             : }
     257             : 
     258             : // static
     259   260438283 : uint32_t Isolate::CurrentEmbeddedBlobSize() {
     260             :   return current_embedded_blob_size_.load(
     261   260438283 :       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      170520 :   for (int i = 0; i < Builtins::builtin_count; i++) {
     276       85232 :     Code code = heap_.builtin(i);
     277             : 
     278             :     DCHECK(Internals::HasHeapObjectTag(code.ptr()));
     279             :     uint8_t* const code_ptr =
     280       85232 :         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     2812656 :     for (int j = kStartOffset; j < Code::kUnalignedHeaderSize; j++) {
     292     1363712 :       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      328485 :     Isolate::FindOrAllocatePerThreadDataForThisThread() {
     317             :   ThreadId thread_id = ThreadId::Current();
     318             :   PerIsolateThreadData* per_thread = nullptr;
     319             :   {
     320      328478 :     base::MutexGuard lock_guard(&thread_data_table_mutex_);
     321             :     per_thread = thread_data_table_.Lookup(thread_id);
     322      328489 :     if (per_thread == nullptr) {
     323       67977 :       per_thread = new PerIsolateThreadData(this, thread_id);
     324       67977 :       thread_data_table_.Insert(per_thread);
     325             :     }
     326             :     DCHECK(thread_data_table_.Lookup(thread_id) == per_thread);
     327             :   }
     328      328498 :   return per_thread;
     329             : }
     330             : 
     331             : 
     332        1498 : void Isolate::DiscardPerThreadDataForThisThread() {
     333        1498 :   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       61008 : void Isolate::InitializeOncePerProcess() {
     365       61008 :   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       61008 :   per_isolate_thread_data_key_ = base::Thread::CreateThreadLocalKey();
     372       61008 : }
     373             : 
     374      801480 : Address Isolate::get_address_from_id(IsolateAddressId id) {
     375      801480 :   return isolate_addresses_[id];
     376             : }
     377             : 
     378        6336 : char* Isolate::Iterate(RootVisitor* v, char* thread_storage) {
     379             :   ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage);
     380        6336 :   Iterate(v, thread);
     381        6336 :   return thread_storage + sizeof(ThreadLocalTop);
     382             : }
     383             : 
     384             : 
     385         215 : void Isolate::IterateThread(ThreadVisitor* v, char* t) {
     386             :   ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t);
     387         215 :   v->VisitThread(this, thread);
     388         215 : }
     389             : 
     390      281875 : void Isolate::Iterate(RootVisitor* v, ThreadLocalTop* thread) {
     391             :   // Visit the roots from the top for a given thread.
     392      281875 :   v->VisitRootPointer(Root::kTop, nullptr,
     393      563750 :                       FullObjectSlot(&thread->pending_exception_));
     394      281875 :   v->VisitRootPointer(Root::kTop, nullptr,
     395      563750 :                       FullObjectSlot(&thread->pending_message_obj_));
     396      563750 :   v->VisitRootPointer(Root::kTop, nullptr, FullObjectSlot(&thread->context_));
     397      281875 :   v->VisitRootPointer(Root::kTop, nullptr,
     398      563750 :                       FullObjectSlot(&thread->scheduled_exception_));
     399             : 
     400      448466 :   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      333182 :     v->VisitRootPointer(
     404             :         Root::kTop, nullptr,
     405      333182 :         FullObjectSlot(reinterpret_cast<Address>(&(block->exception_))));
     406      333182 :     v->VisitRootPointer(
     407             :         Root::kTop, nullptr,
     408      333182 :         FullObjectSlot(reinterpret_cast<Address>(&(block->message_obj_))));
     409             :   }
     410             : 
     411             :   // Iterate over pointers on native execution stack.
     412      563750 :   wasm::WasmCodeRefScope wasm_code_ref_scope;
     413     4984898 :   for (StackFrameIterator it(this, thread); !it.done(); it.Advance()) {
     414     4703023 :     it.frame()->Iterate(v);
     415             :   }
     416      281875 : }
     417             : 
     418      275539 : void Isolate::Iterate(RootVisitor* v) {
     419             :   ThreadLocalTop* current_t = thread_local_top();
     420      275539 :   Iterate(v, current_t);
     421      275539 : }
     422             : 
     423      275539 : void Isolate::IterateDeferredHandles(RootVisitor* visitor) {
     424      279289 :   for (DeferredHandles* deferred = deferred_handles_head_; deferred != nullptr;
     425             :        deferred = deferred->next_) {
     426        3750 :     deferred->Iterate(visitor);
     427             :   }
     428      275539 : }
     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    20997455 : void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) {
     460    20997455 :   thread_local_top()->try_catch_handler_ = that;
     461    20997455 : }
     462             : 
     463             : 
     464    20997466 : void Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) {
     465             :   DCHECK(thread_local_top()->try_catch_handler_ == that);
     466    20997466 :   thread_local_top()->try_catch_handler_ = that->next_;
     467    20997466 : }
     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       61856 :   static MaybeHandle<StackTraceFrame> LookupCachedFrame(
     543             :       Isolate* isolate, Handle<AbstractCode> code, int code_offset) {
     544       61856 :     if (FLAG_optimize_for_size) return MaybeHandle<StackTraceFrame>();
     545             : 
     546      123712 :     const auto maybe_cache = handle(code->stack_frame_cache(), isolate);
     547       61856 :     if (!maybe_cache->IsSimpleNumberDictionary())
     548        8194 :       return MaybeHandle<StackTraceFrame>();
     549             : 
     550             :     const auto cache = Handle<SimpleNumberDictionary>::cast(maybe_cache);
     551      107324 :     const int entry = cache->FindEntry(isolate, code_offset);
     552       53662 :     if (entry != NumberDictionary::kNotFound) {
     553       51284 :       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     1315670 :   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     1315670 :         check_security_context_(filter_mode == CURRENT_SECURITY_CONTEXT) {
     589     1315670 :     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     1292676 :         skip_next_frame_ = false;
     599     1292676 :         break;
     600             :     }
     601             : 
     602     1315670 :     elements_ = isolate->factory()->NewFrameArray(Min(limit, 10));
     603     1315670 :   }
     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     4984423 :   void AppendJavaScriptFrame(
     653             :       FrameSummary::JavaScriptFrameSummary const& summary) {
     654             :     // Filter out internal frames that we do not want to show.
     655     4992479 :     if (!IsVisibleInStackTrace(summary.function())) return;
     656             : 
     657     4976367 :     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     4976367 :     Handle<JSFunction> function = summary.function();
     664     4976367 :     if (IsStrictFrame(function)) flags |= FrameArray::kIsStrict;
     665     4976367 :     if (is_constructor) flags |= FrameArray::kIsConstructor;
     666             : 
     667     9952734 :     Handle<FixedArray> parameters = isolate_->factory()->empty_fixed_array();
     668     4976367 :     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     4976367 :         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       61925 :   void AppendBuiltinExitFrame(BuiltinExitFrame* exit_frame) {
     706      123850 :     Handle<JSFunction> function = handle(exit_frame->function(), isolate_);
     707             : 
     708             :     // Filter out internal frames that we do not want to show.
     709       92322 :     if (!IsVisibleInStackTrace(function)) return;
     710             : 
     711       31528 :     Handle<Object> receiver(exit_frame->receiver(), isolate_);
     712       31528 :     Handle<Code> code(exit_frame->LookupCode(), isolate_);
     713             :     const int offset =
     714       94584 :         static_cast<int>(exit_frame->pc() - code->InstructionStart());
     715             : 
     716             :     int flags = 0;
     717       31528 :     if (IsStrictFrame(function)) flags |= FrameArray::kIsStrict;
     718       31528 :     if (exit_frame->IsConstructor()) flags |= FrameArray::kIsConstructor;
     719             : 
     720       31528 :     Handle<FixedArray> parameters = isolate_->factory()->empty_fixed_array();
     721       31528 :     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       31528 :                                           offset, flags, parameters);
     732             :   }
     733             : 
     734    14707043 :   bool full() { return elements_->FrameCount() >= limit_; }
     735             : 
     736             :   Handle<FrameArray> GetElements() {
     737     2501360 :     elements_->ShrinkToFit(isolate_);
     738     1250680 :     return elements_;
     739             :   }
     740             : 
     741             :   // Creates a StackTraceFrame object for each frame in the FrameArray.
     742       64990 :   Handle<FixedArray> GetElementsAsStackTraceFrameArray() {
     743      129980 :     elements_->ShrinkToFit(isolate_);
     744             :     const int frame_count = elements_->FrameCount();
     745             :     Handle<FixedArray> stack_trace =
     746       64990 :         isolate_->factory()->NewFixedArray(frame_count);
     747             : 
     748      189598 :     for (int i = 0; i < frame_count; ++i) {
     749             :       // Caching stack frames only happens for non-Wasm frames.
     750       62304 :       if (!elements_->IsAnyWasmFrame(i)) {
     751             :         MaybeHandle<StackTraceFrame> maybe_frame =
     752             :             StackFrameCacheHelper::LookupCachedFrame(
     753             :                 isolate_, handle(elements_->Code(i), isolate_),
     754      123712 :                 Smi::ToInt(elements_->Offset(i)));
     755       61856 :         if (!maybe_frame.is_null()) {
     756             :           Handle<StackTraceFrame> frame = maybe_frame.ToHandleChecked();
     757      102568 :           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       64990 :     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     5009250 :   bool IsStrictFrame(Handle<JSFunction> function) {
     781     5009250 :     if (!encountered_strict_function_) {
     782             :       encountered_strict_function_ =
     783     3698738 :           is_strict(function->shared()->language_mode());
     784             :     }
     785     5009250 :     return encountered_strict_function_;
     786             :   }
     787             : 
     788             :   // Determines whether the given stack frame should be displayed in a stack
     789             :   // trace.
     790     5047811 :   bool IsVisibleInStackTrace(Handle<JSFunction> function) {
     791    10059545 :     return ShouldIncludeFrame(function) && IsNotHidden(function) &&
     792     5047811 :            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     5047811 :   bool ShouldIncludeFrame(Handle<JSFunction> function) {
     800     5047811 :     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      166949 :         if (skip_next_frame_ && (*function == *caller_)) {
     809       22143 :           skip_next_frame_ = false;
     810       22143 :           return false;
     811             :         }
     812      119180 :         return !skip_next_frame_;
     813             :     }
     814           0 :     UNREACHABLE();
     815             :   }
     816             : 
     817     5021595 :   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    15064641 :     if (!FLAG_builtins_in_stack_traces &&
     823    10043046 :         !function->shared()->IsUserJavaScript()) {
     824             :       return function->shared()->native();
     825             :     }
     826             :     return true;
     827             :   }
     828             : 
     829             :   bool IsInSameSecurityContext(Handle<JSFunction> function) {
     830     5011734 :     if (!check_security_context_) return true;
     831     4950744 :     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     4976367 :                : 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     1258201 : bool GetStackTraceLimit(Isolate* isolate, int* result) {
     853     1258201 :   Handle<JSObject> error = isolate->error_function();
     854             : 
     855             :   Handle<String> key = isolate->factory()->stackTraceLimit_string();
     856     1258201 :   Handle<Object> stack_trace_limit = JSReceiver::GetDataProperty(error, key);
     857     1258201 :   if (!stack_trace_limit->IsNumber()) return false;
     858             : 
     859             :   // Ensure that limit is not negative.
     860     1250680 :   *result = Max(FastD2IChecked(stack_trace_limit->Number()), 0);
     861             : 
     862     1250680 :   if (*result != FLAG_stack_trace_limit) {
     863          54 :     isolate->CountUsage(v8::Isolate::kErrorStackTraceLimit);
     864             :   }
     865             : 
     866             :   return true;
     867             : }
     868             : 
     869      280426 : bool NoExtension(const v8::FunctionCallbackInfo<v8::Value>&) { return false; }
     870             : 
     871      673065 : bool IsBuiltinFunction(Isolate* isolate, HeapObject object,
     872             :                        Builtins::Name builtin_index) {
     873      673065 :   if (!object->IsJSFunction()) return false;
     874             :   JSFunction const function = JSFunction::cast(object);
     875      901634 :   return function->code() == isolate->builtins()->builtin(builtin_index);
     876             : }
     877             : 
     878        2954 : void CaptureAsyncStackTrace(Isolate* isolate, Handle<JSPromise> promise,
     879             :                             FrameArrayBuilder* builder) {
     880      170388 :   while (!builder->full()) {
     881             :     // Check that the {promise} is not settled.
     882      170379 :     if (promise->status() != Promise::kPending) return;
     883             : 
     884             :     // Check that we have exactly one PromiseReaction on the {promise}.
     885      170341 :     if (!promise->reactions()->IsPromiseReaction()) return;
     886             :     Handle<PromiseReaction> reaction(
     887             :         PromiseReaction::cast(promise->reactions()), isolate);
     888      167434 :     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      334868 :     if (IsBuiltinFunction(isolate, reaction->fulfill_handler(),
     893      166151 :                           Builtins::kAsyncFunctionAwaitResolveClosure) ||
     894      166151 :         IsBuiltinFunction(isolate, reaction->fulfill_handler(),
     895      333549 :                           Builtins::kAsyncGeneratorAwaitResolveClosure) ||
     896      166115 :         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      166079 :     } 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      165971 :       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     1315670 : Handle<Object> CaptureStackTrace(Isolate* isolate, Handle<Object> caller,
     985             :                                  CaptureStackTraceOptions options) {
     986     2631340 :   DisallowJavascriptExecution no_js(isolate);
     987             : 
     988     2631340 :   wasm::WasmCodeRefScope code_ref_scope;
     989             :   FrameArrayBuilder builder(isolate, options.skip_mode, options.limit, caller,
     990     1315670 :                             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    10707498 :   for (StackFrameIterator it(isolate); !it.done() && !builder.full();
     996     9142026 :        it.Advance()) {
     997             :     StackFrame* const frame = it.frame();
     998     9142026 :     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     4988822 :         std::vector<FrameSummary> frames;
    1009     4988822 :         StandardFrame::cast(frame)->Summarize(&frames);
    1010    15275416 :         for (size_t i = frames.size(); i-- != 0 && !builder.full();) {
    1011             :           auto& summary = frames[i];
    1012     5207709 :           if (options.capture_only_frames_subject_to_debugging &&
    1013       64479 :               !summary.is_subject_to_debugging()) {
    1014             :             continue;
    1015             :           }
    1016             : 
    1017     5141055 :           if (summary.IsJavaScript()) {
    1018             :             //=========================================================
    1019             :             // Handle a JavaScript frame.
    1020             :             //=========================================================
    1021             :             auto const& java_script = summary.AsJavaScript();
    1022     4984423 :             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       69801 :         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       61925 :         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     1315670 :   if (options.async_stack_trace) {
    1057             :     Handle<Object> current_microtask = isolate->factory()->current_microtask();
    1058     1250302 :     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        6162 :       if (IsBuiltinFunction(isolate, promise_reaction_job_task->handler(),
    1064        2170 :                             Builtins::kAsyncFunctionAwaitResolveClosure) ||
    1065        2170 :           IsBuiltinFunction(isolate, promise_reaction_job_task->handler(),
    1066        5116 :                             Builtins::kAsyncGeneratorAwaitResolveClosure) ||
    1067        2035 :           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        2035 :         if (promise_or_capability->IsJSPromise()) {
    1102             :           Handle<JSPromise> promise =
    1103        1927 :               Handle<JSPromise>::cast(promise_or_capability);
    1104        1927 :           CaptureAsyncStackTrace(isolate, promise, &builder);
    1105             :         }
    1106             :       }
    1107             :     }
    1108             :   }
    1109             : 
    1110             :   // TODO(yangguo): Queue this structured stack trace for preprocessing on GC.
    1111     1315670 :   if (options.capture_result == CaptureStackTraceOptions::RAW_FRAME_ARRAY) {
    1112     1250680 :     return builder.GetElements();
    1113             :   }
    1114       64990 :   return builder.GetElementsAsStackTraceFrameArray();
    1115             : }
    1116             : 
    1117             : }  // namespace
    1118             : 
    1119     1258201 : Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSReceiver> error_object,
    1120             :                                                 FrameSkipMode mode,
    1121             :                                                 Handle<Object> caller) {
    1122             :   int limit;
    1123     1265722 :   if (!GetStackTraceLimit(this, &limit)) return factory()->undefined_value();
    1124             : 
    1125             :   CaptureStackTraceOptions options;
    1126     1250680 :   options.limit = limit;
    1127             :   options.skip_mode = mode;
    1128             :   options.capture_builtin_exit_frames = true;
    1129     1250680 :   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     1250680 :   return CaptureStackTrace(this, caller, options);
    1135             : }
    1136             : 
    1137     1209921 : MaybeHandle<JSReceiver> Isolate::CaptureAndSetDetailedStackTrace(
    1138             :     Handle<JSReceiver> error_object) {
    1139     1209921 :   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     1209921 :   return error_object;
    1153             : }
    1154             : 
    1155     1258201 : 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     1258201 :       CaptureSimpleStackTrace(error_object, mode, caller);
    1162     2516402 :   RETURN_ON_EXCEPTION(this,
    1163             :                       Object::SetProperty(this, error_object, key, stack_trace,
    1164             :                                           StoreOrigin::kMaybeKeyed,
    1165             :                                           Just(ShouldThrow::kThrowOnError)),
    1166             :                       JSReceiver);
    1167     1258201 :   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       64990 : 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       64990 :       (stack_trace_options & StackTrace::kExposeFramesAcrossSecurityOrigins)
    1225             :           ? FrameArrayBuilder::ALL
    1226       64990 :           : 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       64990 :       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     6040679 : 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     6040679 :   if (bootstrapper()->IsActive()) return true;
    1331             :   {
    1332             :     DisallowHeapAllocation no_gc;
    1333             : 
    1334     6040441 :     if (receiver->IsJSGlobalProxy()) {
    1335             :       Object receiver_context =
    1336             :           JSGlobalProxy::cast(*receiver)->native_context();
    1337    12075937 :       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    12076944 :           accessing_context->global_object()->native_context();
    1343     6038472 :       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       48280 : Object Isolate::StackOverflow() {
    1373       48280 :   if (FLAG_abort_on_stack_or_string_length_overflow) {
    1374           0 :     FATAL("Aborting on stack overflow");
    1375             :   }
    1376             : 
    1377       96560 :   DisallowJavascriptExecution no_js(this);
    1378             :   HandleScope scope(this);
    1379             : 
    1380       48280 :   Handle<JSFunction> fun = range_error_function();
    1381             :   Handle<Object> msg = factory()->NewStringFromAsciiChecked(
    1382       48280 :       MessageFormatter::TemplateString(MessageTemplate::kStackOverflow));
    1383             :   Handle<Object> no_caller;
    1384             :   Handle<Object> exception;
    1385       96560 :   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
    1386             :       this, exception,
    1387             :       ErrorUtils::Construct(this, fun, fun, msg, SKIP_NONE, no_caller, true));
    1388             : 
    1389       48280 :   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       48280 :   return ReadOnlyRoots(heap()).exception();
    1399             : }
    1400             : 
    1401        4206 : Object Isolate::TerminateExecution() {
    1402        4206 :   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        3078 :   if (has_scheduled_exception() &&
    1415             :       scheduled_exception() == ReadOnlyRoots(this).termination_exception()) {
    1416          62 :     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        2165 : void Isolate::InvokeApiInterruptCallbacks() {
    1430             :   RuntimeCallTimerScope runtimeTimer(
    1431        2165 :       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       64525 :       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     1414095 : 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     1414095 :   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     1128613 :   bool requires_message = try_catch_handler() == nullptr ||
    1553     1472359 :                           try_catch_handler()->is_verbose_ ||
    1554       58264 :                           try_catch_handler()->capture_message_;
    1555     1414095 :   bool rethrowing_message = thread_local_top()->rethrowing_message_;
    1556             : 
    1557     1414095 :   thread_local_top()->rethrowing_message_ = false;
    1558             : 
    1559             :   // Notify debugger of exception.
    1560     1414095 :   if (is_catchable_by_javascript(raw_exception)) {
    1561     1409889 :     debug()->OnThrow(exception);
    1562             :   }
    1563             : 
    1564             :   // Generate the message if required.
    1565     1414095 :   if (requires_message && !rethrowing_message) {
    1566     1362635 :     MessageLocation computed_location;
    1567             :     // If no location was specified we try to use a computed one instead.
    1568     1362635 :     if (location == nullptr && ComputeLocation(&computed_location)) {
    1569             :       location = &computed_location;
    1570             :     }
    1571             : 
    1572     1362635 :     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     1362605 :       Handle<Object> message_obj = CreateMessage(exception, location);
    1579     1362605 :       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     1362605 :       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     2828190 :   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     1314162 : Object Isolate::UnwindAndFindHandler() {
    1620     1314162 :   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     1314162 :     thread_local_top()->pending_handler_context_ = context;
    1628             :     thread_local_top()->pending_handler_entrypoint_ =
    1629     1314162 :         instruction_start + handler_offset;
    1630     1314162 :     thread_local_top()->pending_handler_constant_pool_ = constant_pool_address;
    1631     1314162 :     thread_local_top()->pending_handler_fp_ = handler_fp;
    1632     1314162 :     thread_local_top()->pending_handler_sp_ = handler_sp;
    1633             : 
    1634             :     // Return and clear pending exception.
    1635             :     clear_pending_exception();
    1636     1314162 :     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    22846803 :   for (StackFrameIterator iter(this);; iter.Advance()) {
    1646             :     // Handler must exist.
    1647             :     DCHECK(!iter.done());
    1648             : 
    1649             :     StackFrame* frame = iter.frame();
    1650             : 
    1651    22846803 :     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      120477 :         thread_local_top()->handler_ = handler->next_address();
    1659             : 
    1660             :         // Gather information from the handler.
    1661      120477 :         Code code = frame->LookupCode();
    1662      120477 :         HandlerTable table(code);
    1663             :         return FoundHandler(Context(), code->InstructionStart(),
    1664      120477 :                             table.LookupReturn(0), code->constant_pool(),
    1665             :                             handler->address() + StackHandlerConstants::kSize,
    1666      120477 :                             0);
    1667             :       }
    1668             : 
    1669             :       case StackFrame::WASM_COMPILED: {
    1670     2616503 :         if (trap_handler::IsThreadInWasm()) {
    1671             :           trap_handler::ClearThreadInWasm();
    1672             :         }
    1673             : 
    1674             :         // For WebAssembly frames we perform a lookup in the handler table.
    1675     2616503 :         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     2616495 :         wasm::WasmCodeRefScope code_ref_scope;
    1680             :         WasmCompiledFrame* wasm_frame = static_cast<WasmCompiledFrame*>(frame);
    1681     2616495 :         int stack_slots = 0;  // Will contain stack slot count of frame.
    1682     2616495 :         int offset = wasm_frame->LookupExceptionHandlerInTable(&stack_slots);
    1683     2616495 :         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::WASM_COMPILE_LAZY: {
    1702             :         // Can only fail directly on invocation. This happens if an invalid
    1703             :         // function was validated lazily.
    1704             :         DCHECK_IMPLIES(trap_handler::IsTrapHandlerEnabled(),
    1705             :                        trap_handler::IsThreadInWasm());
    1706             :         DCHECK(FLAG_wasm_lazy_validation);
    1707             :         trap_handler::ClearThreadInWasm();
    1708             :         break;
    1709             :       }
    1710             : 
    1711             :       case StackFrame::OPTIMIZED: {
    1712             :         // For optimized frames we perform a lookup in the handler table.
    1713     3322413 :         if (!catchable_by_js) break;
    1714             :         OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame);
    1715     3322050 :         int stack_slots = 0;  // Will contain stack slot count of frame.
    1716             :         int offset =
    1717     3322050 :             js_frame->LookupExceptionHandlerInTable(&stack_slots, nullptr);
    1718     3322050 :         if (offset < 0) break;
    1719             :         // Compute the stack pointer from the frame pointer. This ensures
    1720             :         // that argument slots on the stack are dropped as returning would.
    1721             :         Address return_sp = frame->fp() +
    1722      330372 :                             StandardFrameConstants::kFixedFrameSizeAboveFp -
    1723      660744 :                             stack_slots * kSystemPointerSize;
    1724             : 
    1725             :         // Gather information from the frame.
    1726      330372 :         Code code = frame->LookupCode();
    1727             : 
    1728             :         // TODO(bmeurer): Turbofanned BUILTIN frames appear as OPTIMIZED,
    1729             :         // but do not have a code kind of OPTIMIZED_FUNCTION.
    1730      588247 :         if (code->kind() == Code::OPTIMIZED_FUNCTION &&
    1731      257875 :             code->marked_for_deoptimization()) {
    1732             :           // If the target code is lazy deoptimized, we jump to the original
    1733             :           // return address, but we make a note that we are throwing, so
    1734             :           // that the deoptimizer can do the right thing.
    1735       12218 :           offset = static_cast<int>(frame->pc() - code->entry());
    1736             :           set_deoptimizer_lazy_throw(true);
    1737             :         }
    1738             : 
    1739             :         return FoundHandler(Context(), code->InstructionStart(), offset,
    1740      330372 :                             code->constant_pool(), return_sp, frame->fp());
    1741             :       }
    1742             : 
    1743             :       case StackFrame::STUB: {
    1744             :         // Some stubs are able to handle exceptions.
    1745     1055145 :         if (!catchable_by_js) break;
    1746             :         StubFrame* stub_frame = static_cast<StubFrame*>(frame);
    1747     1053799 :         wasm::WasmCodeRefScope code_ref_scope;
    1748             :         wasm::WasmCode* wasm_code =
    1749     1053799 :             wasm_engine()->code_manager()->LookupCode(frame->pc());
    1750     1053799 :         if (wasm_code != nullptr) {
    1751             :           // It is safe to skip Wasm runtime stubs as none of them contain local
    1752             :           // exception handlers.
    1753           0 :           CHECK_EQ(wasm::WasmCode::kRuntimeStub, wasm_code->kind());
    1754           0 :           CHECK_EQ(0, wasm_code->handler_table_size());
    1755     1008195 :           break;
    1756             :         }
    1757     1053799 :         Code code = stub_frame->LookupCode();
    1758     2558654 :         if (!code->IsCode() || code->kind() != Code::BUILTIN ||
    1759     1550459 :             !code->has_handler_table() || !code->is_turbofanned()) {
    1760             :           break;
    1761             :         }
    1762             : 
    1763       45604 :         int stack_slots = 0;  // Will contain stack slot count of frame.
    1764       45604 :         int offset = stub_frame->LookupExceptionHandlerInTable(&stack_slots);
    1765       45604 :         if (offset < 0) break;
    1766             : 
    1767             :         // Compute the stack pointer from the frame pointer. This ensures
    1768             :         // that argument slots on the stack are dropped as returning would.
    1769             :         Address return_sp = frame->fp() +
    1770       45604 :                             StandardFrameConstants::kFixedFrameSizeAboveFp -
    1771       91208 :                             stack_slots * kSystemPointerSize;
    1772             : 
    1773             :         return FoundHandler(Context(), code->InstructionStart(), offset,
    1774       45604 :                             code->constant_pool(), return_sp, frame->fp());
    1775             :       }
    1776             : 
    1777             :       case StackFrame::INTERPRETED: {
    1778             :         // For interpreted frame we perform a range lookup in the handler table.
    1779    13294351 :         if (!catchable_by_js) break;
    1780             :         InterpretedFrame* js_frame = static_cast<InterpretedFrame*>(frame);
    1781             :         int register_slots = InterpreterFrameConstants::RegisterStackSlotCount(
    1782    26581706 :             js_frame->GetBytecodeArray()->register_count());
    1783    13290853 :         int context_reg = 0;  // Will contain register index holding context.
    1784             :         int offset =
    1785    13290853 :             js_frame->LookupExceptionHandlerInTable(&context_reg, nullptr);
    1786    13290853 :         if (offset < 0) break;
    1787             :         // Compute the stack pointer from the frame pointer. This ensures that
    1788             :         // argument slots on the stack are dropped as returning would.
    1789             :         // Note: This is only needed for interpreted frames that have been
    1790             :         //       materialized by the deoptimizer. If there is a handler frame
    1791             :         //       in between then {frame->sp()} would already be correct.
    1792             :         Address return_sp = frame->fp() -
    1793      817045 :                             InterpreterFrameConstants::kFixedFrameSizeFromFp -
    1794     1634090 :                             register_slots * kSystemPointerSize;
    1795             : 
    1796             :         // Patch the bytecode offset in the interpreted frame to reflect the
    1797             :         // position of the exception handler. The special builtin below will
    1798             :         // take care of continuing to dispatch at that position. Also restore
    1799             :         // the correct context for the handler from the interpreter register.
    1800             :         Context context =
    1801      817045 :             Context::cast(js_frame->ReadInterpreterRegister(context_reg));
    1802      817045 :         js_frame->PatchBytecodeOffset(static_cast<int>(offset));
    1803             : 
    1804             :         Code code =
    1805      817045 :             builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch);
    1806             :         return FoundHandler(context, code->InstructionStart(), 0,
    1807     1634090 :                             code->constant_pool(), return_sp, frame->fp());
    1808             :       }
    1809             : 
    1810             :       case StackFrame::BUILTIN:
    1811             :         // For builtin frames we are guaranteed not to find a handler.
    1812           0 :         if (catchable_by_js) {
    1813           0 :           CHECK_EQ(-1,
    1814             :                    JavaScriptFrame::cast(frame)->LookupExceptionHandlerInTable(
    1815             :                        nullptr, nullptr));
    1816             :         }
    1817             :         break;
    1818             : 
    1819             :       case StackFrame::WASM_INTERPRETER_ENTRY: {
    1820        3374 :         if (trap_handler::IsThreadInWasm()) {
    1821             :           trap_handler::ClearThreadInWasm();
    1822             :         }
    1823             :       } break;
    1824             : 
    1825             :       case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH: {
    1826             :         // Builtin continuation frames with catch can handle exceptions.
    1827           8 :         if (!catchable_by_js) break;
    1828             :         JavaScriptBuiltinContinuationWithCatchFrame* js_frame =
    1829             :             JavaScriptBuiltinContinuationWithCatchFrame::cast(frame);
    1830           8 :         js_frame->SetException(exception);
    1831             : 
    1832             :         // Reconstruct the stack pointer from the frame pointer.
    1833           8 :         Address return_sp = js_frame->fp() - js_frame->GetSPToFPDelta();
    1834           8 :         Code code = js_frame->LookupCode();
    1835             :         return FoundHandler(Context(), code->InstructionStart(), 0,
    1836           8 :                             code->constant_pool(), return_sp, frame->fp());
    1837             :       } break;
    1838             : 
    1839             :       default:
    1840             :         // All other types can not handle exception.
    1841             :         break;
    1842             :     }
    1843             : 
    1844    21532641 :     if (frame->is_optimized()) {
    1845             :       // Remove per-frame stored materialized objects.
    1846     2992041 :       bool removed = materialized_object_store_->Remove(frame->fp());
    1847             :       USE(removed);
    1848             :       // If there were any materialized objects, the code should be
    1849             :       // marked for deopt.
    1850             :       DCHECK_IMPLIES(removed, frame->LookupCode()->marked_for_deoptimization());
    1851             :     }
    1852             :   }
    1853             : 
    1854             :   UNREACHABLE();
    1855             : }
    1856             : 
    1857             : namespace {
    1858      310340 : HandlerTable::CatchPrediction PredictException(JavaScriptFrame* frame) {
    1859             :   HandlerTable::CatchPrediction prediction;
    1860      620680 :   if (frame->is_optimized()) {
    1861       45551 :     if (frame->LookupExceptionHandlerInTable(nullptr, nullptr) > 0) {
    1862             :       // This optimized frame will catch. It's handler table does not include
    1863             :       // exception prediction, and we need to use the corresponding handler
    1864             :       // tables on the unoptimized code objects.
    1865         101 :       std::vector<FrameSummary> summaries;
    1866        1375 :       frame->Summarize(&summaries);
    1867        1591 :       for (size_t i = summaries.size(); i != 0; i--) {
    1868        1382 :         const FrameSummary& summary = summaries[i - 1];
    1869             :         Handle<AbstractCode> code = summary.AsJavaScript().abstract_code();
    1870        1884 :         if (code->IsCode() && code->kind() == AbstractCode::BUILTIN) {
    1871         502 :           prediction = code->GetCode()->GetBuiltinCatchPrediction();
    1872         610 :           if (prediction == HandlerTable::UNCAUGHT) continue;
    1873        1274 :           return prediction;
    1874             :         }
    1875             : 
    1876             :         // Must have been constructed from a bytecode array.
    1877         880 :         CHECK_EQ(AbstractCode::INTERPRETED_FUNCTION, code->kind());
    1878         880 :         int code_offset = summary.code_offset();
    1879         880 :         HandlerTable table(code->GetBytecodeArray());
    1880         880 :         int index = table.LookupRange(code_offset, nullptr, &prediction);
    1881         880 :         if (index <= 0) continue;
    1882         873 :         if (prediction == HandlerTable::UNCAUGHT) continue;
    1883             :         return prediction;
    1884             :       }
    1885             :     }
    1886      264789 :   } else if (frame->LookupExceptionHandlerInTable(nullptr, &prediction) > 0) {
    1887        6140 :     return prediction;
    1888             :   }
    1889             :   return HandlerTable::UNCAUGHT;
    1890             : }
    1891             : 
    1892      159666 : Isolate::CatchType ToCatchType(HandlerTable::CatchPrediction prediction) {
    1893      159666 :   switch (prediction) {
    1894             :     case HandlerTable::UNCAUGHT:
    1895             :       return Isolate::NOT_CAUGHT;
    1896             :     case HandlerTable::CAUGHT:
    1897        2429 :       return Isolate::CAUGHT_BY_JAVASCRIPT;
    1898             :     case HandlerTable::PROMISE:
    1899        1261 :       return Isolate::CAUGHT_BY_PROMISE;
    1900             :     case HandlerTable::DESUGARING:
    1901           0 :       return Isolate::CAUGHT_BY_DESUGARING;
    1902             :     case HandlerTable::ASYNC_AWAIT:
    1903        2102 :       return Isolate::CAUGHT_BY_ASYNC_AWAIT;
    1904             :     default:
    1905           0 :       UNREACHABLE();
    1906             :   }
    1907             : }
    1908             : }  // anonymous namespace
    1909             : 
    1910        6283 : Isolate::CatchType Isolate::PredictExceptionCatcher() {
    1911             :   Address external_handler = thread_local_top()->try_catch_handler_address();
    1912        6283 :   if (IsExternalHandlerOnTop(Object())) return CAUGHT_BY_EXTERNAL;
    1913             : 
    1914             :   // Search for an exception handler by performing a full walk over the stack.
    1915      172780 :   for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) {
    1916             :     StackFrame* frame = iter.frame();
    1917             : 
    1918      172448 :     switch (frame->type()) {
    1919             :       case StackFrame::ENTRY:
    1920             :       case StackFrame::CONSTRUCT_ENTRY: {
    1921             :         Address entry_handler = frame->top_handler()->next_address();
    1922             :         // The exception has been externally caught if and only if there is an
    1923             :         // external handler which is on top of the top-most JS_ENTRY handler.
    1924         857 :         if (external_handler != kNullAddress &&
    1925         351 :             !try_catch_handler()->is_verbose_) {
    1926         256 :           if (entry_handler == kNullAddress ||
    1927         128 :               entry_handler > external_handler) {
    1928             :             return CAUGHT_BY_EXTERNAL;
    1929             :           }
    1930             :         }
    1931             :       } break;
    1932             : 
    1933             :       // For JavaScript frames we perform a lookup in the handler table.
    1934             :       case StackFrame::OPTIMIZED:
    1935             :       case StackFrame::INTERPRETED:
    1936             :       case StackFrame::BUILTIN: {
    1937             :         JavaScriptFrame* js_frame = JavaScriptFrame::cast(frame);
    1938      158756 :         Isolate::CatchType prediction = ToCatchType(PredictException(js_frame));
    1939      158756 :         if (prediction == NOT_CAUGHT) break;
    1940             :         return prediction;
    1941             :       } break;
    1942             : 
    1943             :       case StackFrame::STUB: {
    1944        5290 :         Handle<Code> code(frame->LookupCode(), this);
    1945       11490 :         if (!code->IsCode() || code->kind() != Code::BUILTIN ||
    1946        7110 :             !code->has_handler_table() || !code->is_turbofanned()) {
    1947             :           break;
    1948             :         }
    1949             : 
    1950         910 :         CatchType prediction = ToCatchType(code->GetBuiltinCatchPrediction());
    1951         910 :         if (prediction != NOT_CAUGHT) return prediction;
    1952             :       } break;
    1953             : 
    1954             :       case StackFrame::JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH: {
    1955           0 :         Handle<Code> code(frame->LookupCode(), this);
    1956           0 :         CatchType prediction = ToCatchType(code->GetBuiltinCatchPrediction());
    1957           0 :         if (prediction != NOT_CAUGHT) return prediction;
    1958             :       } break;
    1959             : 
    1960             :       default:
    1961             :         // All other types can not handle exception.
    1962             :         break;
    1963             :     }
    1964             :   }
    1965             : 
    1966             :   // Handler not found.
    1967         332 :   return NOT_CAUGHT;
    1968             : }
    1969             : 
    1970           5 : Object Isolate::ThrowIllegalOperation() {
    1971           5 :   if (FLAG_stack_trace_on_illegal) PrintStack(stdout);
    1972           5 :   return Throw(ReadOnlyRoots(heap()).illegal_access_string());
    1973             : }
    1974             : 
    1975       30127 : void Isolate::ScheduleThrow(Object exception) {
    1976             :   // When scheduling a throw we first throw the exception to get the
    1977             :   // error reporting if it is uncaught before rescheduling it.
    1978       30127 :   Throw(exception);
    1979       30127 :   PropagatePendingExceptionToExternalTryCatch();
    1980       30127 :   if (has_pending_exception()) {
    1981       30127 :     thread_local_top()->scheduled_exception_ = pending_exception();
    1982       30127 :     thread_local_top()->external_caught_exception_ = false;
    1983             :     clear_pending_exception();
    1984             :   }
    1985       30127 : }
    1986             : 
    1987         121 : void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) {
    1988             :   DCHECK(handler == try_catch_handler());
    1989             :   DCHECK(handler->HasCaught());
    1990             :   DCHECK(handler->rethrow_);
    1991             :   DCHECK(handler->capture_message_);
    1992         121 :   Object message(reinterpret_cast<Address>(handler->message_obj_));
    1993             :   DCHECK(message->IsJSMessageObject() || message->IsTheHole(this));
    1994         121 :   thread_local_top()->pending_message_obj_ = message;
    1995         121 : }
    1996             : 
    1997             : 
    1998         273 : void Isolate::CancelScheduledExceptionFromTryCatch(v8::TryCatch* handler) {
    1999             :   DCHECK(has_scheduled_exception());
    2000         546 :   if (reinterpret_cast<void*>(scheduled_exception().ptr()) ==
    2001         273 :       handler->exception_) {
    2002             :     DCHECK_NE(scheduled_exception(),
    2003             :               ReadOnlyRoots(heap()).termination_exception());
    2004             :     clear_scheduled_exception();
    2005             :   } else {
    2006             :     DCHECK_EQ(scheduled_exception(),
    2007             :               ReadOnlyRoots(heap()).termination_exception());
    2008             :     // Clear termination once we returned from all V8 frames.
    2009         183 :     if (handle_scope_implementer()->CallDepthIsZero()) {
    2010         133 :       thread_local_top()->external_caught_exception_ = false;
    2011             :       clear_scheduled_exception();
    2012             :     }
    2013             :   }
    2014         546 :   if (reinterpret_cast<void*>(thread_local_top()->pending_message_obj_.ptr()) ==
    2015         273 :       handler->message_obj_) {
    2016             :     clear_pending_message();
    2017             :   }
    2018         273 : }
    2019             : 
    2020       31273 : Object Isolate::PromoteScheduledException() {
    2021             :   Object thrown = scheduled_exception();
    2022             :   clear_scheduled_exception();
    2023             :   // Re-throw the exception to avoid getting repeated error reporting.
    2024       31273 :   return ReThrow(thrown);
    2025             : }
    2026             : 
    2027           0 : void Isolate::PrintCurrentStackTrace(FILE* out) {
    2028           0 :   IncrementalStringBuilder builder(this);
    2029           0 :   for (StackTraceFrameIterator it(this); !it.done(); it.Advance()) {
    2030           0 :     if (!it.is_javascript()) continue;
    2031             : 
    2032             :     HandleScope scope(this);
    2033             :     JavaScriptFrame* frame = it.javascript_frame();
    2034             : 
    2035           0 :     Handle<Object> receiver(frame->receiver(), this);
    2036           0 :     Handle<JSFunction> function(frame->function(), this);
    2037             :     Handle<AbstractCode> code;
    2038             :     int offset;
    2039           0 :     if (frame->is_interpreted()) {
    2040             :       InterpretedFrame* interpreted_frame = InterpretedFrame::cast(frame);
    2041           0 :       code = handle(AbstractCode::cast(interpreted_frame->GetBytecodeArray()),
    2042             :                     this);
    2043           0 :       offset = interpreted_frame->GetBytecodeOffset();
    2044             :     } else {
    2045           0 :       code = handle(AbstractCode::cast(frame->LookupCode()), this);
    2046           0 :       offset = static_cast<int>(frame->pc() - code->InstructionStart());
    2047             :     }
    2048             : 
    2049             :     // To preserve backwards compatiblity, only append a newline when
    2050             :     // the current stringified frame actually has characters.
    2051           0 :     const int old_length = builder.Length();
    2052           0 :     JSStackFrame site(this, receiver, function, code, offset);
    2053           0 :     site.ToString(builder);
    2054           0 :     if (old_length != builder.Length()) builder.AppendCharacter('\n');
    2055             :   }
    2056             : 
    2057           0 :   Handle<String> stack_trace = builder.Finish().ToHandleChecked();
    2058           0 :   stack_trace->PrintOn(out);
    2059           0 : }
    2060             : 
    2061      979908 : bool Isolate::ComputeLocation(MessageLocation* target) {
    2062      979908 :   StackTraceFrameIterator it(this);
    2063      979908 :   if (it.done()) return false;
    2064             :   StandardFrame* frame = it.frame();
    2065             :   // Compute the location from the function and the relocation info of the
    2066             :   // baseline code. For optimized code this will use the deoptimization
    2067             :   // information to get canonical location information.
    2068      972179 :   std::vector<FrameSummary> frames;
    2069     1944358 :   wasm::WasmCodeRefScope code_ref_scope;
    2070      972179 :   frame->Summarize(&frames);
    2071             :   FrameSummary& summary = frames.back();
    2072      972179 :   summary.EnsureSourcePositionsAvailable();
    2073      972179 :   int pos = summary.SourcePosition();
    2074             :   Handle<SharedFunctionInfo> shared;
    2075      972179 :   Handle<Object> script = summary.script();
    2076     1943970 :   if (!script->IsScript() ||
    2077             :       (Script::cast(*script)->source()->IsUndefined(this))) {
    2078             :     return false;
    2079             :   }
    2080             : 
    2081      971791 :   if (summary.IsJavaScript()) {
    2082      822330 :     shared = handle(summary.AsJavaScript().function()->shared(), this);
    2083             :   }
    2084      971791 :   *target = MessageLocation(Handle<Script>::cast(script), pos, pos + 1, shared);
    2085      971791 :   return true;
    2086             : }
    2087             : 
    2088        4564 : bool Isolate::ComputeLocationFromException(MessageLocation* target,
    2089             :                                            Handle<Object> exception) {
    2090        4564 :   if (!exception->IsJSObject()) return false;
    2091             : 
    2092             :   Handle<Name> start_pos_symbol = factory()->error_start_pos_symbol();
    2093             :   Handle<Object> start_pos = JSReceiver::GetDataProperty(
    2094        2666 :       Handle<JSObject>::cast(exception), start_pos_symbol);
    2095        2666 :   if (!start_pos->IsSmi()) return false;
    2096             :   int start_pos_value = Handle<Smi>::cast(start_pos)->value();
    2097             : 
    2098             :   Handle<Name> end_pos_symbol = factory()->error_end_pos_symbol();
    2099             :   Handle<Object> end_pos = JSReceiver::GetDataProperty(
    2100          15 :       Handle<JSObject>::cast(exception), end_pos_symbol);
    2101          15 :   if (!end_pos->IsSmi()) return false;
    2102             :   int end_pos_value = Handle<Smi>::cast(end_pos)->value();
    2103             : 
    2104             :   Handle<Name> script_symbol = factory()->error_script_symbol();
    2105             :   Handle<Object> script = JSReceiver::GetDataProperty(
    2106          15 :       Handle<JSObject>::cast(exception), script_symbol);
    2107          15 :   if (!script->IsScript()) return false;
    2108             : 
    2109             :   Handle<Script> cast_script(Script::cast(*script), this);
    2110          15 :   *target = MessageLocation(cast_script, start_pos_value, end_pos_value);
    2111          15 :   return true;
    2112             : }
    2113             : 
    2114             : 
    2115        4585 : bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target,
    2116             :                                             Handle<Object> exception) {
    2117        4585 :   if (!exception->IsJSObject()) return false;
    2118             :   Handle<Name> key = factory()->stack_trace_symbol();
    2119             :   Handle<Object> property =
    2120        2687 :       JSReceiver::GetDataProperty(Handle<JSObject>::cast(exception), key);
    2121        2687 :   if (!property->IsFixedArray()) return false;
    2122             : 
    2123             :   Handle<FrameArray> elements = Handle<FrameArray>::cast(property);
    2124             : 
    2125             :   const int frame_count = elements->FrameCount();
    2126        3398 :   for (int i = 0; i < frame_count; i++) {
    2127        1824 :     if (elements->IsWasmFrame(i) || elements->IsAsmJsWasmFrame(i)) {
    2128             :       Handle<WasmInstanceObject> instance(elements->WasmInstance(i), this);
    2129             :       uint32_t func_index =
    2130          48 :           static_cast<uint32_t>(elements->WasmFunctionIndex(i)->value());
    2131             :       int code_offset = elements->Offset(i)->value();
    2132             :       bool is_at_number_conversion =
    2133          48 :           elements->IsAsmJsWasmFrame(i) &&
    2134           0 :           elements->Flags(i)->value() & FrameArray::kAsmJsAtNumberConversion;
    2135             :       // WasmCode* held alive by the {GlobalWasmCodeRef}.
    2136             :       wasm::WasmCode* code =
    2137             :           Managed<wasm::GlobalWasmCodeRef>::cast(elements->WasmCodeObject(i))
    2138             :               ->get()
    2139             :               ->code();
    2140             :       int byte_offset =
    2141             :           FrameSummary::WasmCompiledFrameSummary::GetWasmSourcePosition(
    2142          48 :               code, code_offset);
    2143          48 :       int pos = WasmModuleObject::GetSourcePosition(
    2144             :           handle(instance->module_object(), this), func_index, byte_offset,
    2145          48 :           is_at_number_conversion);
    2146             :       Handle<Script> script(instance->module_object()->script(), this);
    2147             : 
    2148          48 :       *target = MessageLocation(script, pos, pos + 1);
    2149             :       return true;
    2150             :     }
    2151             : 
    2152             :     Handle<JSFunction> fun = handle(elements->Function(i), this);
    2153        1276 :     if (!fun->shared()->IsSubjectToDebugging()) continue;
    2154             : 
    2155         500 :     Object script = fun->shared()->script();
    2156        1000 :     if (script->IsScript() &&
    2157             :         !(Script::cast(script)->source()->IsUndefined(this))) {
    2158         500 :       Handle<SharedFunctionInfo> shared = handle(fun->shared(), this);
    2159         500 :       SharedFunctionInfo::EnsureSourcePositionsAvailable(this, shared);
    2160         500 :       AbstractCode abstract_code = elements->Code(i);
    2161             :       const int code_offset = elements->Offset(i)->value();
    2162         500 :       const int pos = abstract_code->SourcePosition(code_offset);
    2163             : 
    2164             :       Handle<Script> casted_script(Script::cast(script), this);
    2165         500 :       *target = MessageLocation(casted_script, pos, pos + 1);
    2166             :       return true;
    2167             :     }
    2168             :   }
    2169             :   return false;
    2170             : }
    2171             : 
    2172             : 
    2173     1362969 : Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception,
    2174             :                                                MessageLocation* location) {
    2175             :   Handle<FixedArray> stack_trace_object;
    2176     1362969 :   if (capture_stack_trace_for_uncaught_exceptions_) {
    2177         452 :     if (exception->IsJSError()) {
    2178             :       // We fetch the stack trace that corresponds to this error object.
    2179             :       // If the lookup fails, the exception is probably not a valid Error
    2180             :       // object. In that case, we fall through and capture the stack trace
    2181             :       // at this throw site.
    2182             :       stack_trace_object =
    2183         271 :           GetDetailedStackTrace(Handle<JSObject>::cast(exception));
    2184             :     }
    2185         452 :     if (stack_trace_object.is_null()) {
    2186             :       // Not an error object, we capture stack and location at throw site.
    2187             :       stack_trace_object = CaptureCurrentStackTrace(
    2188             :           stack_trace_for_uncaught_exceptions_frame_limit_,
    2189         186 :           stack_trace_for_uncaught_exceptions_options_);
    2190             :     }
    2191             :   }
    2192     1362969 :   MessageLocation computed_location;
    2193     2730502 :   if (location == nullptr &&
    2194        9113 :       (ComputeLocationFromException(&computed_location, exception) ||
    2195        8586 :        ComputeLocationFromStackTrace(&computed_location, exception) ||
    2196        4037 :        ComputeLocation(&computed_location))) {
    2197             :     location = &computed_location;
    2198             :   }
    2199             : 
    2200             :   return MessageHandler::MakeMessageObject(
    2201             :       this, MessageTemplate::kUncaughtException, location, exception,
    2202     1362969 :       stack_trace_object);
    2203             : }
    2204             : 
    2205           0 : bool Isolate::IsJavaScriptHandlerOnTop(Object exception) {
    2206             :   DCHECK_NE(ReadOnlyRoots(heap()).the_hole_value(), exception);
    2207             : 
    2208             :   // For uncatchable exceptions, the JavaScript handler cannot be on top.
    2209      171053 :   if (!is_catchable_by_javascript(exception)) return false;
    2210             : 
    2211             :   // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist.
    2212             :   Address entry_handler = Isolate::handler(thread_local_top());
    2213      166825 :   if (entry_handler == kNullAddress) return false;
    2214             : 
    2215             :   // Get the address of the external handler so we can compare the address to
    2216             :   // determine which one is closer to the top of the stack.
    2217             :   Address external_handler = thread_local_top()->try_catch_handler_address();
    2218      148470 :   if (external_handler == kNullAddress) return true;
    2219             : 
    2220             :   // The exception has been externally caught if and only if there is an
    2221             :   // external handler which is on top of the top-most JS_ENTRY handler.
    2222             :   //
    2223             :   // Note, that finally clauses would re-throw an exception unless it's aborted
    2224             :   // by jumps in control flow (like return, break, etc.) and we'll have another
    2225             :   // chance to set proper v8::TryCatch later.
    2226      147102 :   return (entry_handler < external_handler);
    2227             : }
    2228             : 
    2229           0 : bool Isolate::IsExternalHandlerOnTop(Object exception) {
    2230             :   DCHECK_NE(ReadOnlyRoots(heap()).the_hole_value(), exception);
    2231             : 
    2232             :   // Get the address of the external handler so we can compare the address to
    2233             :   // determine which one is closer to the top of the stack.
    2234             :   Address external_handler = thread_local_top()->try_catch_handler_address();
    2235       53401 :   if (external_handler == kNullAddress) return false;
    2236             : 
    2237             :   // For uncatchable exceptions, the external handler is always on top.
    2238       46462 :   if (!is_catchable_by_javascript(exception)) return true;
    2239             : 
    2240             :   // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist.
    2241             :   Address entry_handler = Isolate::handler(thread_local_top());
    2242       43177 :   if (entry_handler == kNullAddress) return true;
    2243             : 
    2244             :   // The exception has been externally caught if and only if there is an
    2245             :   // external handler which is on top of the top-most JS_ENTRY handler.
    2246             :   //
    2247             :   // Note, that finally clauses would re-throw an exception unless it's aborted
    2248             :   // by jumps in control flow (like return, break, etc.) and we'll have another
    2249             :   // chance to set proper v8::TryCatch later.
    2250       20333 :   return (entry_handler > external_handler);
    2251             : }
    2252             : 
    2253       15477 : void Isolate::ReportPendingMessagesImpl(bool report_externally) {
    2254             :   Object exception = pending_exception();
    2255             : 
    2256             :   // Clear the pending message object early to avoid endless recursion.
    2257       15477 :   Object message_obj = thread_local_top()->pending_message_obj_;
    2258             :   clear_pending_message();
    2259             : 
    2260             :   // For uncatchable exceptions we do nothing. If needed, the exception and the
    2261             :   // message have already been propagated to v8::TryCatch.
    2262       15477 :   if (!is_catchable_by_javascript(exception)) return;
    2263             : 
    2264             :   // Determine whether the message needs to be reported to all message handlers
    2265             :   // depending on whether and external v8::TryCatch or an internal JavaScript
    2266             :   // handler is on top.
    2267             :   bool should_report_exception;
    2268       12770 :   if (report_externally) {
    2269             :     // Only report the exception if the external handler is verbose.
    2270       11811 :     should_report_exception = try_catch_handler()->is_verbose_;
    2271             :   } else {
    2272             :     // Report the exception if it isn't caught by JavaScript code.
    2273         959 :     should_report_exception = !IsJavaScriptHandlerOnTop(exception);
    2274             :   }
    2275             : 
    2276             :   // Actually report the pending message to all message handlers.
    2277       12770 :   if (!message_obj->IsTheHole(this) && should_report_exception) {
    2278             :     HandleScope scope(this);
    2279             :     Handle<JSMessageObject> message(JSMessageObject::cast(message_obj), this);
    2280             :     Handle<Script> script(message->script(), this);
    2281             :     int start_pos = message->start_position();
    2282             :     int end_pos = message->end_position();
    2283        8116 :     MessageLocation location(script, start_pos, end_pos);
    2284        8116 :     MessageHandler::ReportMessage(this, &location, message);
    2285             :   }
    2286             : }
    2287             : 
    2288      122995 : void Isolate::ReportPendingMessages() {
    2289             :   DCHECK(AllowExceptions::IsAllowed(this));
    2290             : 
    2291             :   // The embedder might run script in response to an exception.
    2292             :   AllowJavascriptExecutionDebugOnly allow_script(this);
    2293             : 
    2294             :   Object exception = pending_exception();
    2295             : 
    2296             :   // Try to propagate the exception to an external v8::TryCatch handler. If
    2297             :   // propagation was unsuccessful, then we will get another chance at reporting
    2298             :   // the pending message if the exception is re-thrown.
    2299      122995 :   bool has_been_propagated = PropagatePendingExceptionToExternalTryCatch();
    2300      122995 :   if (!has_been_propagated) return;
    2301             : 
    2302       15477 :   ReportPendingMessagesImpl(IsExternalHandlerOnTop(exception));
    2303             : }
    2304             : 
    2305          33 : void Isolate::ReportPendingMessagesFromJavaScript() {
    2306             :   DCHECK(AllowExceptions::IsAllowed(this));
    2307             : 
    2308             :   auto IsHandledByJavaScript = [=]() {
    2309             :     // In this situation, the exception is always a non-terminating exception.
    2310             : 
    2311             :     // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist.
    2312          33 :     Address entry_handler = Isolate::handler(thread_local_top());
    2313             :     DCHECK_NE(entry_handler, kNullAddress);
    2314             :     entry_handler = StackHandler::FromAddress(entry_handler)->next_address();
    2315             : 
    2316             :     // Get the address of the external handler so we can compare the address to
    2317             :     // determine which one is closer to the top of the stack.
    2318             :     Address external_handler = thread_local_top()->try_catch_handler_address();
    2319          33 :     if (external_handler == kNullAddress) return true;
    2320             : 
    2321          33 :     return (entry_handler < external_handler);
    2322             :   };
    2323             : 
    2324             :   auto IsHandledExternally = [=]() {
    2325           0 :     Address external_handler = thread_local_top()->try_catch_handler_address();
    2326           0 :     if (external_handler == kNullAddress) return false;
    2327             : 
    2328             :     // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist.
    2329             :     Address entry_handler = Isolate::handler(thread_local_top());
    2330             :     DCHECK_NE(entry_handler, kNullAddress);
    2331             :     entry_handler = StackHandler::FromAddress(entry_handler)->next_address();
    2332           0 :     return (entry_handler > external_handler);
    2333             :   };
    2334             : 
    2335          33 :   auto PropagateToExternalHandler = [=]() {
    2336          33 :     if (IsHandledByJavaScript()) {
    2337          33 :       thread_local_top()->external_caught_exception_ = false;
    2338          33 :       return false;
    2339             :     }
    2340             : 
    2341           0 :     if (!IsHandledExternally()) {
    2342           0 :       thread_local_top()->external_caught_exception_ = false;
    2343           0 :       return true;
    2344             :     }
    2345             : 
    2346           0 :     thread_local_top()->external_caught_exception_ = true;
    2347             :     v8::TryCatch* handler = try_catch_handler();
    2348             :     DCHECK(thread_local_top()->pending_message_obj_->IsJSMessageObject() ||
    2349             :            thread_local_top()->pending_message_obj_->IsTheHole(this));
    2350           0 :     handler->can_continue_ = true;
    2351           0 :     handler->has_terminated_ = false;
    2352           0 :     handler->exception_ = reinterpret_cast<void*>(pending_exception().ptr());
    2353             :     // Propagate to the external try-catch only if we got an actual message.
    2354           0 :     if (thread_local_top()->pending_message_obj_->IsTheHole(this)) return true;
    2355             : 
    2356             :     handler->message_obj_ =
    2357           0 :         reinterpret_cast<void*>(thread_local_top()->pending_message_obj_.ptr());
    2358           0 :     return true;
    2359          33 :   };
    2360             : 
    2361             :   // Try to propagate to an external v8::TryCatch handler.
    2362          66 :   if (!PropagateToExternalHandler()) return;
    2363             : 
    2364           0 :   ReportPendingMessagesImpl(true);
    2365             : }
    2366             : 
    2367       16972 : bool Isolate::OptionalRescheduleException(bool clear_exception) {
    2368             :   DCHECK(has_pending_exception());
    2369       16972 :   PropagatePendingExceptionToExternalTryCatch();
    2370             : 
    2371             :   bool is_termination_exception =
    2372             :       pending_exception() == ReadOnlyRoots(this).termination_exception();
    2373             : 
    2374       16972 :   if (is_termination_exception) {
    2375        1521 :     if (clear_exception) {
    2376        1080 :       thread_local_top()->external_caught_exception_ = false;
    2377             :       clear_pending_exception();
    2378        1080 :       return false;
    2379             :     }
    2380       15451 :   } else if (thread_local_top()->external_caught_exception_) {
    2381             :     // If the exception is externally caught, clear it if there are no
    2382             :     // JavaScript frames on the way to the C++ frame that has the
    2383             :     // external handler.
    2384             :     DCHECK_NE(thread_local_top()->try_catch_handler_address(), kNullAddress);
    2385             :     Address external_handler_address =
    2386             :         thread_local_top()->try_catch_handler_address();
    2387       13304 :     JavaScriptFrameIterator it(this);
    2388       13304 :     if (it.done() || (it.frame()->sp() > external_handler_address)) {
    2389             :       clear_exception = true;
    2390             :     }
    2391             :   }
    2392             : 
    2393             :   // Clear the exception if needed.
    2394       15892 :   if (clear_exception) {
    2395       14401 :     thread_local_top()->external_caught_exception_ = false;
    2396             :     clear_pending_exception();
    2397       14401 :     return false;
    2398             :   }
    2399             : 
    2400             :   // Reschedule the exception.
    2401        1491 :   thread_local_top()->scheduled_exception_ = pending_exception();
    2402             :   clear_pending_exception();
    2403        1491 :   return true;
    2404             : }
    2405             : 
    2406       17420 : void Isolate::PushPromise(Handle<JSObject> promise) {
    2407             :   ThreadLocalTop* tltop = thread_local_top();
    2408       17420 :   PromiseOnStack* prev = tltop->promise_on_stack_;
    2409             :   Handle<JSObject> global_promise = global_handles()->Create(*promise);
    2410       34840 :   tltop->promise_on_stack_ = new PromiseOnStack(global_promise, prev);
    2411       17420 : }
    2412             : 
    2413             : 
    2414       17440 : void Isolate::PopPromise() {
    2415             :   ThreadLocalTop* tltop = thread_local_top();
    2416       17440 :   if (tltop->promise_on_stack_ == nullptr) return;
    2417             :   PromiseOnStack* prev = tltop->promise_on_stack_->prev();
    2418             :   Handle<Object> global_promise = tltop->promise_on_stack_->promise();
    2419       17420 :   delete tltop->promise_on_stack_;
    2420       17420 :   tltop->promise_on_stack_ = prev;
    2421       17420 :   global_handles()->Destroy(global_promise.location());
    2422             : }
    2423             : 
    2424             : namespace {
    2425             : bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate,
    2426             :                                                 Handle<JSPromise> promise);
    2427             : 
    2428         985 : bool PromiseHandlerCheck(Isolate* isolate, Handle<JSReceiver> handler,
    2429             :                          Handle<JSReceiver> deferred_promise) {
    2430             :   // Recurse to the forwarding Promise, if any. This may be due to
    2431             :   //  - await reaction forwarding to the throwaway Promise, which has
    2432             :   //    a dependency edge to the outer Promise.
    2433             :   //  - PromiseIdResolveHandler forwarding to the output of .then
    2434             :   //  - Promise.all/Promise.race forwarding to a throwaway Promise, which
    2435             :   //    has a dependency edge to the generated outer Promise.
    2436             :   // Otherwise, this is a real reject handler for the Promise.
    2437             :   Handle<Symbol> key = isolate->factory()->promise_forwarding_handler_symbol();
    2438         985 :   Handle<Object> forwarding_handler = JSReceiver::GetDataProperty(handler, key);
    2439         985 :   if (forwarding_handler->IsUndefined(isolate)) {
    2440             :     return true;
    2441             :   }
    2442             : 
    2443         365 :   if (!deferred_promise->IsJSPromise()) {
    2444             :     return true;
    2445             :   }
    2446             : 
    2447             :   return InternalPromiseHasUserDefinedRejectHandler(
    2448         365 :       isolate, Handle<JSPromise>::cast(deferred_promise));
    2449             : }
    2450             : 
    2451        4876 : bool InternalPromiseHasUserDefinedRejectHandler(Isolate* isolate,
    2452             :                                                 Handle<JSPromise> promise) {
    2453             :   // If this promise was marked as being handled by a catch block
    2454             :   // in an async function, then it has a user-defined reject handler.
    2455        4876 :   if (promise->handled_hint()) return true;
    2456             : 
    2457             :   // If this Promise is subsumed by another Promise (a Promise resolved
    2458             :   // with another Promise, or an intermediate, hidden, throwaway Promise
    2459             :   // within async/await), then recurse on the outer Promise.
    2460             :   // In this case, the dependency is one possible way that the Promise
    2461             :   // could be resolved, so it does not subsume the other following cases.
    2462             :   Handle<Symbol> key = isolate->factory()->promise_handled_by_symbol();
    2463        4330 :   Handle<Object> outer_promise_obj = JSObject::GetDataProperty(promise, key);
    2464        5333 :   if (outer_promise_obj->IsJSPromise() &&
    2465        1003 :       InternalPromiseHasUserDefinedRejectHandler(
    2466             :           isolate, Handle<JSPromise>::cast(outer_promise_obj))) {
    2467             :     return true;
    2468             :   }
    2469             : 
    2470        3608 :   if (promise->status() == Promise::kPending) {
    2471        3797 :     for (Handle<Object> current(promise->reactions(), isolate);
    2472             :          !current->IsSmi();) {
    2473             :       Handle<PromiseReaction> reaction = Handle<PromiseReaction>::cast(current);
    2474             :       Handle<HeapObject> promise_or_capability(
    2475             :           reaction->promise_or_capability(), isolate);
    2476        1076 :       if (!promise_or_capability->IsUndefined(isolate)) {
    2477             :         Handle<JSPromise> promise = Handle<JSPromise>::cast(
    2478             :             promise_or_capability->IsJSPromise()
    2479             :                 ? promise_or_capability
    2480             :                 : handle(Handle<PromiseCapability>::cast(promise_or_capability)
    2481             :                              ->promise(),
    2482        1076 :                          isolate));
    2483        1076 :         if (reaction->reject_handler()->IsUndefined(isolate)) {
    2484          91 :           if (InternalPromiseHasUserDefinedRejectHandler(isolate, promise)) {
    2485             :             return true;
    2486             :           }
    2487             :         } else {
    2488             :           Handle<JSReceiver> current_handler(
    2489             :               JSReceiver::cast(reaction->reject_handler()), isolate);
    2490         985 :           if (PromiseHandlerCheck(isolate, current_handler, promise)) {
    2491         805 :             return true;
    2492             :           }
    2493             :         }
    2494             :       }
    2495             :       current = handle(reaction->next(), isolate);
    2496             :     }
    2497             :   }
    2498             : 
    2499             :   return false;
    2500             : }
    2501             : 
    2502             : }  // namespace
    2503             : 
    2504        3417 : bool Isolate::PromiseHasUserDefinedRejectHandler(Handle<Object> promise) {
    2505        3417 :   if (!promise->IsJSPromise()) return false;
    2506             :   return InternalPromiseHasUserDefinedRejectHandler(
    2507        3417 :       this, Handle<JSPromise>::cast(promise));
    2508             : }
    2509             : 
    2510        4206 : Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
    2511             :   Handle<Object> undefined = factory()->undefined_value();
    2512             :   ThreadLocalTop* tltop = thread_local_top();
    2513        4206 :   if (tltop->promise_on_stack_ == nullptr) return undefined;
    2514             :   // Find the top-most try-catch or try-finally handler.
    2515        1593 :   CatchType prediction = PredictExceptionCatcher();
    2516        1593 :   if (prediction == NOT_CAUGHT || prediction == CAUGHT_BY_EXTERNAL) {
    2517           5 :     return undefined;
    2518             :   }
    2519             :   Handle<Object> retval = undefined;
    2520        1588 :   PromiseOnStack* promise_on_stack = tltop->promise_on_stack_;
    2521      156669 :   for (StackFrameIterator it(this); !it.done(); it.Advance()) {
    2522             :     StackFrame* frame = it.frame();
    2523             :     HandlerTable::CatchPrediction catch_prediction;
    2524      156259 :     if (frame->is_java_script()) {
    2525      151584 :       catch_prediction = PredictException(JavaScriptFrame::cast(frame));
    2526        4675 :     } else if (frame->type() == StackFrame::STUB) {
    2527        1618 :       Code code = frame->LookupCode();
    2528        3644 :       if (!code->IsCode() || code->kind() != Code::BUILTIN ||
    2529        2434 :           !code->has_handler_table() || !code->is_turbofanned()) {
    2530        1210 :         continue;
    2531             :       }
    2532         408 :       catch_prediction = code->GetBuiltinCatchPrediction();
    2533             :     } else {
    2534             :       continue;
    2535             :     }
    2536             : 
    2537      151992 :     switch (catch_prediction) {
    2538             :       case HandlerTable::UNCAUGHT:
    2539             :         continue;
    2540             :       case HandlerTable::CAUGHT:
    2541             :       case HandlerTable::DESUGARING:
    2542         462 :         if (retval->IsJSPromise()) {
    2543             :           // Caught the result of an inner async/await invocation.
    2544             :           // Mark the inner promise as caught in the "synchronous case" so
    2545             :           // that Debug::OnException will see. In the synchronous case,
    2546             :           // namely in the code in an async function before the first
    2547             :           // await, the function which has this exception event has not yet
    2548             :           // returned, so the generated Promise has not yet been marked
    2549             :           // by AsyncFunctionAwaitCaught with promiseHandledHintSymbol.
    2550         325 :           Handle<JSPromise>::cast(retval)->set_handled_hint(true);
    2551             :         }
    2552         462 :         return retval;
    2553             :       case HandlerTable::PROMISE:
    2554             :         return promise_on_stack
    2555             :                    ? Handle<Object>::cast(promise_on_stack->promise())
    2556         482 :                    : undefined;
    2557             :       case HandlerTable::ASYNC_AWAIT: {
    2558             :         // If in the initial portion of async/await, continue the loop to pop up
    2559             :         // successive async/await stack frames until an asynchronous one with
    2560             :         // dependents is found, or a non-async stack frame is encountered, in
    2561             :         // order to handle the synchronous async/await catch prediction case:
    2562             :         // assume that async function calls are awaited.
    2563        1474 :         if (!promise_on_stack) return retval;
    2564             :         retval = promise_on_stack->promise();
    2565        1474 :         if (PromiseHasUserDefinedRejectHandler(retval)) {
    2566         234 :           return retval;
    2567             :         }
    2568             :         promise_on_stack = promise_on_stack->prev();
    2569        1240 :         continue;
    2570             :       }
    2571             :     }
    2572             :   }
    2573         410 :   return retval;
    2574             : }
    2575             : 
    2576             : 
    2577        1371 : void Isolate::SetCaptureStackTraceForUncaughtExceptions(
    2578             :       bool capture,
    2579             :       int frame_limit,
    2580             :       StackTrace::StackTraceOptions options) {
    2581        1371 :   capture_stack_trace_for_uncaught_exceptions_ = capture;
    2582        1371 :   stack_trace_for_uncaught_exceptions_frame_limit_ = frame_limit;
    2583        1371 :   stack_trace_for_uncaught_exceptions_options_ = options;
    2584        1371 : }
    2585             : 
    2586             : 
    2587           5 : void Isolate::SetAbortOnUncaughtExceptionCallback(
    2588             :     v8::Isolate::AbortOnUncaughtExceptionCallback callback) {
    2589           5 :   abort_on_uncaught_exception_callback_ = callback;
    2590           5 : }
    2591             : 
    2592     1537297 : bool Isolate::AreWasmThreadsEnabled(Handle<Context> context) {
    2593     1537297 :   if (wasm_threads_enabled_callback()) {
    2594          42 :     v8::Local<v8::Context> api_context = v8::Utils::ToLocal(context);
    2595          42 :     return wasm_threads_enabled_callback()(api_context);
    2596             :   }
    2597     1537255 :   return FLAG_experimental_wasm_threads;
    2598             : }
    2599             : 
    2600           4 : Handle<Context> Isolate::GetIncumbentContext() {
    2601           4 :   JavaScriptFrameIterator it(this);
    2602             : 
    2603             :   // 1st candidate: most-recently-entered author function's context
    2604             :   // if it's newer than the last Context::BackupIncumbentScope entry.
    2605             :   //
    2606             :   // NOTE: This code assumes that the stack grows downward.
    2607             :   Address top_backup_incumbent =
    2608             :       top_backup_incumbent_scope()
    2609             :           ? top_backup_incumbent_scope()->JSStackComparableAddress()
    2610           4 :           : 0;
    2611           8 :   if (!it.done() &&
    2612           2 :       (!top_backup_incumbent || it.frame()->sp() < top_backup_incumbent)) {
    2613           4 :     Context context = Context::cast(it.frame()->context());
    2614           4 :     return Handle<Context>(context->native_context(), this);
    2615             :   }
    2616             : 
    2617             :   // 2nd candidate: the last Context::Scope's incumbent context if any.
    2618           0 :   if (top_backup_incumbent_scope()) {
    2619             :     return Utils::OpenHandle(
    2620             :         *top_backup_incumbent_scope()->backup_incumbent_context_);
    2621             :   }
    2622             : 
    2623             :   // Last candidate: the entered context or microtask context.
    2624             :   // Given that there is no other author function is running, there must be
    2625             :   // no cross-context function running, then the incumbent realm must match
    2626             :   // the entry realm.
    2627             :   v8::Local<v8::Context> entered_context =
    2628           0 :       reinterpret_cast<v8::Isolate*>(this)->GetEnteredOrMicrotaskContext();
    2629             :   return Utils::OpenHandle(*entered_context);
    2630             : }
    2631             : 
    2632       32424 : char* Isolate::ArchiveThread(char* to) {
    2633             :   MemCopy(to, reinterpret_cast<char*>(thread_local_top()),
    2634             :           sizeof(ThreadLocalTop));
    2635             :   InitializeThreadLocal();
    2636             :   clear_pending_exception();
    2637             :   clear_pending_message();
    2638             :   clear_scheduled_exception();
    2639       32424 :   return to + sizeof(ThreadLocalTop);
    2640             : }
    2641             : 
    2642             : 
    2643       32424 : char* Isolate::RestoreThread(char* from) {
    2644             :   MemCopy(reinterpret_cast<char*>(thread_local_top()), from,
    2645             :           sizeof(ThreadLocalTop));
    2646             : // This might be just paranoia, but it seems to be needed in case a
    2647             : // thread_local_top_ is restored on a separate OS thread.
    2648             : #ifdef USE_SIMULATOR
    2649             :   thread_local_top()->simulator_ = Simulator::current(this);
    2650             : #endif
    2651             :   DCHECK(context().is_null() || context()->IsContext());
    2652       32424 :   return from + sizeof(ThreadLocalTop);
    2653             : }
    2654             : 
    2655       62427 : void Isolate::ReleaseSharedPtrs() {
    2656       62427 :   base::MutexGuard lock(&managed_ptr_destructors_mutex_);
    2657       74295 :   while (managed_ptr_destructors_head_) {
    2658             :     ManagedPtrDestructor* l = managed_ptr_destructors_head_;
    2659             :     ManagedPtrDestructor* n = nullptr;
    2660       11868 :     managed_ptr_destructors_head_ = nullptr;
    2661      843454 :     for (; l != nullptr; l = n) {
    2662      415793 :       l->destructor_(l->shared_ptr_ptr_);
    2663      415793 :       n = l->next_;
    2664      415793 :       delete l;
    2665             :     }
    2666             :   }
    2667       62427 : }
    2668             : 
    2669     3118267 : void Isolate::RegisterManagedPtrDestructor(ManagedPtrDestructor* destructor) {
    2670     3118267 :   base::MutexGuard lock(&managed_ptr_destructors_mutex_);
    2671             :   DCHECK_NULL(destructor->prev_);
    2672             :   DCHECK_NULL(destructor->next_);
    2673     3118266 :   if (managed_ptr_destructors_head_) {
    2674     3105166 :     managed_ptr_destructors_head_->prev_ = destructor;
    2675             :   }
    2676     3118266 :   destructor->next_ = managed_ptr_destructors_head_;
    2677     3118266 :   managed_ptr_destructors_head_ = destructor;
    2678     3118266 : }
    2679             : 
    2680     2702474 : void Isolate::UnregisterManagedPtrDestructor(ManagedPtrDestructor* destructor) {
    2681     2702474 :   base::MutexGuard lock(&managed_ptr_destructors_mutex_);
    2682     2702474 :   if (destructor->prev_) {
    2683     2693036 :     destructor->prev_->next_ = destructor->next_;
    2684             :   } else {
    2685             :     DCHECK_EQ(destructor, managed_ptr_destructors_head_);
    2686        9438 :     managed_ptr_destructors_head_ = destructor->next_;
    2687             :   }
    2688     2702474 :   if (destructor->next_) destructor->next_->prev_ = destructor->prev_;
    2689     2702474 :   destructor->prev_ = nullptr;
    2690     2702474 :   destructor->next_ = nullptr;
    2691     2702474 : }
    2692             : 
    2693       62442 : void Isolate::SetWasmEngine(std::shared_ptr<wasm::WasmEngine> engine) {
    2694             :   DCHECK_NULL(wasm_engine_);  // Only call once before {Init}.
    2695             :   wasm_engine_ = std::move(engine);
    2696       62442 :   wasm_engine_->AddIsolate(this);
    2697       62442 : }
    2698             : 
    2699             : // NOLINTNEXTLINE
    2700       67962 : Isolate::PerIsolateThreadData::~PerIsolateThreadData() {
    2701             : #if defined(USE_SIMULATOR)
    2702             :   delete simulator_;
    2703             : #endif
    2704           0 : }
    2705             : 
    2706           0 : Isolate::PerIsolateThreadData* Isolate::ThreadDataTable::Lookup(
    2707             :     ThreadId thread_id) {
    2708             :   auto t = table_.find(thread_id);
    2709      369792 :   if (t == table_.end()) return nullptr;
    2710      295780 :   return t->second;
    2711             : }
    2712             : 
    2713             : 
    2714       67977 : void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) {
    2715      135952 :   bool inserted = table_.insert(std::make_pair(data->thread_id_, data)).second;
    2716       67975 :   CHECK(inserted);
    2717       67975 : }
    2718             : 
    2719             : 
    2720           0 : void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) {
    2721         500 :   table_.erase(data->thread_id_);
    2722        1000 :   delete data;
    2723           0 : }
    2724             : 
    2725       62427 : void Isolate::ThreadDataTable::RemoveAllThreads() {
    2726      129889 :   for (auto& x : table_) {
    2727      134924 :     delete x.second;
    2728             :   }
    2729             :   table_.clear();
    2730       62427 : }
    2731             : 
    2732           0 : class VerboseAccountingAllocator : public AccountingAllocator {
    2733             :  public:
    2734             :   VerboseAccountingAllocator(Heap* heap, size_t allocation_sample_bytes)
    2735           0 :       : heap_(heap), allocation_sample_bytes_(allocation_sample_bytes) {}
    2736             : 
    2737           0 :   v8::internal::Segment* AllocateSegment(size_t size) override {
    2738           0 :     v8::internal::Segment* memory = AccountingAllocator::AllocateSegment(size);
    2739           0 :     if (!memory) return nullptr;
    2740             :     size_t malloced_current = GetCurrentMemoryUsage();
    2741             : 
    2742           0 :     if (last_memory_usage_ + allocation_sample_bytes_ < malloced_current) {
    2743           0 :       PrintMemoryJSON(malloced_current);
    2744             :       last_memory_usage_ = malloced_current;
    2745             :     }
    2746             :     return memory;
    2747             :   }
    2748             : 
    2749           0 :   void ReturnSegment(v8::internal::Segment* memory) override {
    2750           0 :     AccountingAllocator::ReturnSegment(memory);
    2751             :     size_t malloced_current = GetCurrentMemoryUsage();
    2752             : 
    2753           0 :     if (malloced_current + allocation_sample_bytes_ < last_memory_usage_) {
    2754           0 :       PrintMemoryJSON(malloced_current);
    2755             :       last_memory_usage_ = malloced_current;
    2756             :     }
    2757           0 :   }
    2758             : 
    2759           0 :   void ZoneCreation(const Zone* zone) override {
    2760           0 :     PrintZoneModificationSample(zone, "zonecreation");
    2761             :     nesting_deepth_++;
    2762           0 :   }
    2763             : 
    2764           0 :   void ZoneDestruction(const Zone* zone) override {
    2765             :     nesting_deepth_--;
    2766           0 :     PrintZoneModificationSample(zone, "zonedestruction");
    2767           0 :   }
    2768             : 
    2769             :  private:
    2770           0 :   void PrintZoneModificationSample(const Zone* zone, const char* type) {
    2771             :     PrintF(
    2772             :         "{"
    2773             :         "\"type\": \"%s\", "
    2774             :         "\"isolate\": \"%p\", "
    2775             :         "\"time\": %f, "
    2776             :         "\"ptr\": \"%p\", "
    2777             :         "\"name\": \"%s\", "
    2778             :         "\"size\": %" PRIuS
    2779             :         ","
    2780             :         "\"nesting\": %zu}\n",
    2781           0 :         type, reinterpret_cast<void*>(heap_->isolate()),
    2782           0 :         heap_->isolate()->time_millis_since_init(),
    2783             :         reinterpret_cast<const void*>(zone), zone->name(),
    2784           0 :         zone->allocation_size(), nesting_deepth_.load());
    2785           0 :   }
    2786             : 
    2787           0 :   void PrintMemoryJSON(size_t malloced) {
    2788             :     // Note: Neither isolate, nor heap is locked, so be careful with accesses
    2789             :     // as the allocator is potentially used on a concurrent thread.
    2790           0 :     double time = heap_->isolate()->time_millis_since_init();
    2791             :     PrintF(
    2792             :         "{"
    2793             :         "\"type\": \"zone\", "
    2794             :         "\"isolate\": \"%p\", "
    2795             :         "\"time\": %f, "
    2796             :         "\"allocated\": %" PRIuS "}\n",
    2797           0 :         reinterpret_cast<void*>(heap_->isolate()), time, malloced);
    2798           0 :   }
    2799             : 
    2800             :   Heap* heap_;
    2801             :   std::atomic<size_t> last_memory_usage_{0};
    2802             :   std::atomic<size_t> nesting_deepth_{0};
    2803             :   size_t allocation_sample_bytes_;
    2804             : };
    2805             : 
    2806             : #ifdef DEBUG
    2807             : std::atomic<size_t> Isolate::non_disposed_isolates_;
    2808             : #endif  // DEBUG
    2809             : 
    2810             : // static
    2811       62439 : Isolate* Isolate::New(IsolateAllocationMode mode) {
    2812             :   // IsolateAllocator allocates the memory for the Isolate object according to
    2813             :   // the given allocation mode.
    2814             :   std::unique_ptr<IsolateAllocator> isolate_allocator =
    2815       62441 :       base::make_unique<IsolateAllocator>(mode);
    2816             :   // Construct Isolate object in the allocated memory.
    2817             :   void* isolate_ptr = isolate_allocator->isolate_memory();
    2818       62441 :   Isolate* isolate = new (isolate_ptr) Isolate(std::move(isolate_allocator));
    2819             : #if V8_TARGET_ARCH_64_BIT
    2820             :   DCHECK_IMPLIES(
    2821             :       mode == IsolateAllocationMode::kInV8Heap,
    2822             :       IsAligned(isolate->isolate_root(), kPtrComprIsolateRootAlignment));
    2823             : #endif
    2824             : 
    2825             : #ifdef DEBUG
    2826             :   non_disposed_isolates_++;
    2827             : #endif  // DEBUG
    2828             : 
    2829       62441 :   return isolate;
    2830             : }
    2831             : 
    2832             : // static
    2833       62426 : void Isolate::Delete(Isolate* isolate) {
    2834             :   DCHECK_NOT_NULL(isolate);
    2835             :   // Temporarily set this isolate as current so that various parts of
    2836             :   // the isolate can access it in their destructors without having a
    2837             :   // direct pointer. We don't use Enter/Exit here to avoid
    2838             :   // initializing the thread data.
    2839             :   PerIsolateThreadData* saved_data = isolate->CurrentPerIsolateThreadData();
    2840             :   DCHECK_EQ(true, isolate_key_created_.load(std::memory_order_relaxed));
    2841             :   Isolate* saved_isolate = reinterpret_cast<Isolate*>(
    2842       62426 :       base::Thread::GetThreadLocal(isolate->isolate_key_));
    2843       62426 :   SetIsolateThreadLocals(isolate, nullptr);
    2844             : 
    2845       62426 :   isolate->Deinit();
    2846             : 
    2847             : #ifdef DEBUG
    2848             :   non_disposed_isolates_--;
    2849             : #endif  // DEBUG
    2850             : 
    2851             :   // Take ownership of the IsolateAllocator to ensure the Isolate memory will
    2852             :   // be available during Isolate descructor call.
    2853             :   std::unique_ptr<IsolateAllocator> isolate_allocator =
    2854       62427 :       std::move(isolate->isolate_allocator_);
    2855       62427 :   isolate->~Isolate();
    2856             :   // Now free the memory owned by the allocator.
    2857       62427 :   isolate_allocator.reset();
    2858             : 
    2859             :   // Restore the previous current isolate.
    2860       62427 :   SetIsolateThreadLocals(saved_isolate, saved_data);
    2861       62427 : }
    2862             : 
    2863       63457 : v8::PageAllocator* Isolate::page_allocator() {
    2864       63457 :   return isolate_allocator_->page_allocator();
    2865             : }
    2866             : 
    2867       62441 : Isolate::Isolate(std::unique_ptr<i::IsolateAllocator> isolate_allocator)
    2868             :     : isolate_allocator_(std::move(isolate_allocator)),
    2869             :       id_(isolate_counter.fetch_add(1, std::memory_order_relaxed)),
    2870             :       stack_guard_(this),
    2871             :       allocator_(FLAG_trace_zone_stats
    2872             :                      ? new VerboseAccountingAllocator(&heap_, 256 * KB)
    2873             :                      : new AccountingAllocator()),
    2874             :       builtins_(this),
    2875             :       rail_mode_(PERFORMANCE_ANIMATION),
    2876             :       code_event_dispatcher_(new CodeEventDispatcher()),
    2877     1123944 :       cancelable_task_manager_(new CancelableTaskManager()) {
    2878             :   TRACE_ISOLATE(constructor);
    2879             :   CheckIsolateLayout();
    2880             : 
    2881             :   // ThreadManager is initialized early to support locking an isolate
    2882             :   // before it is entered.
    2883       62440 :   thread_manager_ = new ThreadManager(this);
    2884             : 
    2885             :   handle_scope_data_.Initialize();
    2886             : 
    2887             : #define ISOLATE_INIT_EXECUTE(type, name, initial_value)                        \
    2888             :   name##_ = (initial_value);
    2889       62440 :   ISOLATE_INIT_LIST(ISOLATE_INIT_EXECUTE)
    2890             : #undef ISOLATE_INIT_EXECUTE
    2891             : 
    2892             : #define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length)                         \
    2893             :   memset(name##_, 0, sizeof(type) * length);
    2894      249760 :   ISOLATE_INIT_ARRAY_LIST(ISOLATE_INIT_ARRAY_EXECUTE)
    2895             : #undef ISOLATE_INIT_ARRAY_EXECUTE
    2896             : 
    2897       62440 :   InitializeLoggingAndCounters();
    2898       62442 :   debug_ = new Debug(this);
    2899             : 
    2900       62441 :   InitializeDefaultEmbeddedBlob();
    2901             : 
    2902       62441 :   MicrotaskQueue::SetUpDefaultMicrotaskQueue(this);
    2903       62442 : }
    2904             : 
    2905           0 : void Isolate::CheckIsolateLayout() {
    2906             :   CHECK_EQ(OFFSET_OF(Isolate, isolate_data_), 0);
    2907             :   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.embedder_data_)),
    2908             :            Internals::kIsolateEmbedderDataOffset);
    2909             :   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.roots_)),
    2910             :            Internals::kIsolateRootsOffset);
    2911             :   CHECK_EQ(Internals::kExternalMemoryOffset % 8, 0);
    2912             :   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, isolate_data_.external_memory_)),
    2913             :            Internals::kExternalMemoryOffset);
    2914             :   CHECK_EQ(Internals::kExternalMemoryLimitOffset % 8, 0);
    2915             :   CHECK_EQ(static_cast<int>(
    2916             :                OFFSET_OF(Isolate, isolate_data_.external_memory_limit_)),
    2917             :            Internals::kExternalMemoryLimitOffset);
    2918             :   CHECK_EQ(Internals::kExternalMemoryAtLastMarkCompactOffset % 8, 0);
    2919             :   CHECK_EQ(static_cast<int>(OFFSET_OF(
    2920             :                Isolate, isolate_data_.external_memory_at_last_mark_compact_)),
    2921             :            Internals::kExternalMemoryAtLastMarkCompactOffset);
    2922           0 : }
    2923             : 
    2924       63692 : void Isolate::ClearSerializerData() {
    2925       64206 :   delete external_reference_map_;
    2926       63692 :   external_reference_map_ = nullptr;
    2927       63692 : }
    2928             : 
    2929       83993 : bool Isolate::LogObjectRelocation() {
    2930      166825 :   return FLAG_verify_predictable || logger()->is_logging() || is_profiling() ||
    2931      165702 :          heap()->isolate()->logger()->is_listening_to_code_events() ||
    2932       82846 :          (heap_profiler() != nullptr &&
    2933      166699 :           heap_profiler()->is_tracking_object_moves()) ||
    2934       83993 :          heap()->has_heap_object_allocation_tracker();
    2935             : }
    2936             : 
    2937       62427 : void Isolate::Deinit() {
    2938             :   TRACE_ISOLATE(deinit);
    2939             : 
    2940             :   tracing_cpu_profiler_.reset();
    2941       62426 :   if (FLAG_stress_sampling_allocation_profiler > 0) {
    2942           0 :     heap_profiler()->StopSamplingHeapProfiler();
    2943             :   }
    2944             : 
    2945             : #if defined(V8_OS_WIN_X64)
    2946             :   if (win64_unwindinfo::CanRegisterUnwindInfoForNonABICompliantCodeRange() &&
    2947             :       heap()->memory_allocator()) {
    2948             :     const base::AddressRegion& code_range =
    2949             :         heap()->memory_allocator()->code_range();
    2950             :     void* start = reinterpret_cast<void*>(code_range.begin());
    2951             :     win64_unwindinfo::UnregisterNonABICompliantCodeRange(start);
    2952             :   }
    2953             : #endif
    2954             : 
    2955       62426 :   debug()->Unload();
    2956             : 
    2957       62426 :   wasm_engine()->DeleteCompileJobsOnIsolate(this);
    2958             : 
    2959       62427 :   if (concurrent_recompilation_enabled()) {
    2960       62323 :     optimizing_compile_dispatcher_->Stop();
    2961       62323 :     delete optimizing_compile_dispatcher_;
    2962       62323 :     optimizing_compile_dispatcher_ = nullptr;
    2963             :   }
    2964             : 
    2965       62427 :   wasm_engine()->memory_tracker()->DeleteSharedMemoryObjectsOnIsolate(this);
    2966             : 
    2967       62427 :   heap_.mark_compact_collector()->EnsureSweepingCompleted();
    2968       62427 :   heap_.memory_allocator()->unmapper()->EnsureUnmappingCompleted();
    2969             : 
    2970       62427 :   DumpAndResetStats();
    2971             : 
    2972       62427 :   if (FLAG_print_deopt_stress) {
    2973           0 :     PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_);
    2974             :   }
    2975             : 
    2976             :   // We must stop the logger before we tear down other components.
    2977       62427 :   sampler::Sampler* sampler = logger_->sampler();
    2978      124795 :   if (sampler && sampler->IsActive()) sampler->Stop();
    2979             : 
    2980             :   FreeThreadResources();
    2981       62427 :   logger_->StopProfilerThread();
    2982             : 
    2983             :   // We start with the heap tear down so that releasing managed objects does
    2984             :   // not cause a GC.
    2985       62427 :   heap_.StartTearDown();
    2986             : 
    2987       62427 :   ReleaseSharedPtrs();
    2988             : 
    2989       62427 :   delete deoptimizer_data_;
    2990       62427 :   deoptimizer_data_ = nullptr;
    2991       62427 :   builtins_.TearDown();
    2992       62427 :   bootstrapper_->TearDown();
    2993             : 
    2994       62427 :   if (runtime_profiler_ != nullptr) {
    2995       62427 :     delete runtime_profiler_;
    2996       62427 :     runtime_profiler_ = nullptr;
    2997             :   }
    2998             : 
    2999       62427 :   delete heap_profiler_;
    3000       62426 :   heap_profiler_ = nullptr;
    3001             : 
    3002       62426 :   compiler_dispatcher_->AbortAll();
    3003       62427 :   delete compiler_dispatcher_;
    3004       62427 :   compiler_dispatcher_ = nullptr;
    3005             : 
    3006             :   // This stops cancelable tasks (i.e. concurrent marking tasks)
    3007       62427 :   cancelable_task_manager()->CancelAndWait();
    3008             : 
    3009       62427 :   heap_.TearDown();
    3010       62427 :   logger_->TearDown();
    3011             : 
    3012       62427 :   if (wasm_engine_) {
    3013       62427 :     wasm_engine_->RemoveIsolate(this);
    3014             :     wasm_engine_.reset();
    3015             :   }
    3016             : 
    3017       62427 :   TearDownEmbeddedBlob();
    3018             : 
    3019       62427 :   delete interpreter_;
    3020       62427 :   interpreter_ = nullptr;
    3021             : 
    3022      124854 :   delete ast_string_constants_;
    3023       62427 :   ast_string_constants_ = nullptr;
    3024             : 
    3025             :   code_event_dispatcher_.reset();
    3026             : 
    3027       79651 :   delete root_index_map_;
    3028       62427 :   root_index_map_ = nullptr;
    3029             : 
    3030       62427 :   delete compiler_zone_;
    3031       62427 :   compiler_zone_ = nullptr;
    3032       62427 :   compiler_cache_ = nullptr;
    3033             : 
    3034       62427 :   ClearSerializerData();
    3035             : 
    3036             :   {
    3037       62427 :     base::MutexGuard lock_guard(&thread_data_table_mutex_);
    3038       62427 :     thread_data_table_.RemoveAllThreads();
    3039             :   }
    3040       62427 : }
    3041             : 
    3042             : 
    3043      552634 : void Isolate::SetIsolateThreadLocals(Isolate* isolate,
    3044             :                                      PerIsolateThreadData* data) {
    3045      552634 :   base::Thread::SetThreadLocal(isolate_key_, isolate);
    3046      552578 :   base::Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
    3047      552553 : }
    3048             : 
    3049             : 
    3050      374562 : Isolate::~Isolate() {
    3051             :   TRACE_ISOLATE(destructor);
    3052             : 
    3053             :   // The entry stack must be empty when we get here.
    3054             :   DCHECK(entry_stack_ == nullptr || entry_stack_->previous_item == nullptr);
    3055             : 
    3056       62427 :   delete entry_stack_;
    3057       62427 :   entry_stack_ = nullptr;
    3058             : 
    3059       62427 :   delete unicode_cache_;
    3060       62427 :   unicode_cache_ = nullptr;
    3061             : 
    3062       62427 :   delete date_cache_;
    3063       62427 :   date_cache_ = nullptr;
    3064             : 
    3065       62427 :   delete regexp_stack_;
    3066       62427 :   regexp_stack_ = nullptr;
    3067             : 
    3068       62427 :   delete descriptor_lookup_cache_;
    3069       62427 :   descriptor_lookup_cache_ = nullptr;
    3070             : 
    3071       62427 :   delete load_stub_cache_;
    3072       62427 :   load_stub_cache_ = nullptr;
    3073       62427 :   delete store_stub_cache_;
    3074       62427 :   store_stub_cache_ = nullptr;
    3075             : 
    3076      124854 :   delete materialized_object_store_;
    3077       62427 :   materialized_object_store_ = nullptr;
    3078             : 
    3079       62427 :   delete logger_;
    3080       62427 :   logger_ = nullptr;
    3081             : 
    3082       62427 :   delete handle_scope_implementer_;
    3083       62427 :   handle_scope_implementer_ = nullptr;
    3084             : 
    3085             :   delete code_tracer();
    3086             :   set_code_tracer(nullptr);
    3087             : 
    3088       62427 :   delete compilation_cache_;
    3089       62427 :   compilation_cache_ = nullptr;
    3090       62427 :   delete bootstrapper_;
    3091       62427 :   bootstrapper_ = nullptr;
    3092       62427 :   delete inner_pointer_to_code_cache_;
    3093       62427 :   inner_pointer_to_code_cache_ = nullptr;
    3094             : 
    3095       62427 :   delete thread_manager_;
    3096       62427 :   thread_manager_ = nullptr;
    3097             : 
    3098       62427 :   delete global_handles_;
    3099       62427 :   global_handles_ = nullptr;
    3100       62427 :   delete eternal_handles_;
    3101       62427 :   eternal_handles_ = nullptr;
    3102             : 
    3103       62442 :   delete string_stream_debug_object_cache_;
    3104       62427 :   string_stream_debug_object_cache_ = nullptr;
    3105             : 
    3106       62427 :   delete random_number_generator_;
    3107       62427 :   random_number_generator_ = nullptr;
    3108             : 
    3109       62427 :   delete fuzzer_rng_;
    3110       62427 :   fuzzer_rng_ = nullptr;
    3111             : 
    3112       62427 :   delete debug_;
    3113       62427 :   debug_ = nullptr;
    3114             : 
    3115       62427 :   delete cancelable_task_manager_;
    3116       62427 :   cancelable_task_manager_ = nullptr;
    3117             : 
    3118       62427 :   delete allocator_;
    3119       62427 :   allocator_ = nullptr;
    3120             : 
    3121             :   // Assert that |default_microtask_queue_| is the last MicrotaskQueue instance.
    3122             :   DCHECK_IMPLIES(default_microtask_queue_,
    3123             :                  default_microtask_queue_ == default_microtask_queue_->next());
    3124       62427 :   delete default_microtask_queue_;
    3125       62427 :   default_microtask_queue_ = nullptr;
    3126       62427 : }
    3127             : 
    3128       94866 : void Isolate::InitializeThreadLocal() { thread_local_top()->Initialize(this); }
    3129             : 
    3130          20 : void Isolate::SetTerminationOnExternalTryCatch() {
    3131        1826 :   if (try_catch_handler() == nullptr) return;
    3132        1816 :   try_catch_handler()->can_continue_ = false;
    3133        1816 :   try_catch_handler()->has_terminated_ = true;
    3134             :   try_catch_handler()->exception_ =
    3135        1816 :       reinterpret_cast<void*>(ReadOnlyRoots(heap()).null_value().ptr());
    3136             : }
    3137             : 
    3138      170094 : bool Isolate::PropagatePendingExceptionToExternalTryCatch() {
    3139             :   Object exception = pending_exception();
    3140             : 
    3141      170094 :   if (IsJavaScriptHandlerOnTop(exception)) {
    3142      138453 :     thread_local_top()->external_caught_exception_ = false;
    3143      138453 :     return false;
    3144             :   }
    3145             : 
    3146       31641 :   if (!IsExternalHandlerOnTop(exception)) {
    3147        4492 :     thread_local_top()->external_caught_exception_ = false;
    3148        4492 :     return true;
    3149             :   }
    3150             : 
    3151       27149 :   thread_local_top()->external_caught_exception_ = true;
    3152       27149 :   if (!is_catchable_by_javascript(exception)) {
    3153             :     SetTerminationOnExternalTryCatch();
    3154             :   } else {
    3155             :     v8::TryCatch* handler = try_catch_handler();
    3156             :     DCHECK(thread_local_top()->pending_message_obj_->IsJSMessageObject() ||
    3157             :            thread_local_top()->pending_message_obj_->IsTheHole(this));
    3158       25343 :     handler->can_continue_ = true;
    3159       25343 :     handler->has_terminated_ = false;
    3160       25343 :     handler->exception_ = reinterpret_cast<void*>(pending_exception().ptr());
    3161             :     // Propagate to the external try-catch only if we got an actual message.
    3162       25343 :     if (thread_local_top()->pending_message_obj_->IsTheHole(this)) return true;
    3163             : 
    3164             :     handler->message_obj_ =
    3165       11221 :         reinterpret_cast<void*>(thread_local_top()->pending_message_obj_.ptr());
    3166             :   }
    3167             :   return true;
    3168             : }
    3169             : 
    3170       63018 : bool Isolate::InitializeCounters() {
    3171       63018 :   if (async_counters_) return false;
    3172      124883 :   async_counters_ = std::make_shared<Counters>(this);
    3173       62442 :   return true;
    3174             : }
    3175             : 
    3176       63019 : void Isolate::InitializeLoggingAndCounters() {
    3177       63019 :   if (logger_ == nullptr) {
    3178       62440 :     logger_ = new Logger(this);
    3179             :   }
    3180       63017 :   InitializeCounters();
    3181       63021 : }
    3182             : 
    3183             : namespace {
    3184             : 
    3185          56 : void CreateOffHeapTrampolines(Isolate* isolate) {
    3186             :   DCHECK_NOT_NULL(isolate->embedded_blob());
    3187             :   DCHECK_NE(0, isolate->embedded_blob_size());
    3188             : 
    3189             :   HandleScope scope(isolate);
    3190             :   Builtins* builtins = isolate->builtins();
    3191             : 
    3192          56 :   EmbeddedData d = EmbeddedData::FromBlob();
    3193             : 
    3194      170520 :   for (int i = 0; i < Builtins::builtin_count; i++) {
    3195             :     if (!Builtins::IsIsolateIndependent(i)) continue;
    3196             : 
    3197       85232 :     Address instruction_start = d.InstructionStartOfBuiltin(i);
    3198             :     Handle<Code> trampoline = isolate->factory()->NewOffHeapTrampolineFor(
    3199       85232 :         builtins->builtin_handle(i), instruction_start);
    3200             : 
    3201             :     // From this point onwards, the old builtin code object is unreachable and
    3202             :     // will be collected by the next GC.
    3203       85232 :     builtins->set_builtin(i, *trampoline);
    3204             : 
    3205       85232 :     if (isolate->logger()->is_listening_to_code_events() ||
    3206             :         isolate->is_profiling()) {
    3207           0 :       isolate->logger()->LogCodeObject(*trampoline);
    3208             :     }
    3209             :   }
    3210          56 : }
    3211             : 
    3212             : #ifdef DEBUG
    3213             : bool IsolateIsCompatibleWithEmbeddedBlob(Isolate* isolate) {
    3214             :   if (!FLAG_embedded_builtins) return true;
    3215             :   EmbeddedData d = EmbeddedData::FromBlob(isolate);
    3216             :   return (d.IsolateHash() == isolate->HashIsolateForEmbeddedBlob());
    3217             : }
    3218             : #endif  // DEBUG
    3219             : 
    3220             : }  // namespace
    3221             : 
    3222       62441 : void Isolate::InitializeDefaultEmbeddedBlob() {
    3223             :   const uint8_t* blob = DefaultEmbeddedBlob();
    3224             :   uint32_t size = DefaultEmbeddedBlobSize();
    3225             : 
    3226             : #ifdef V8_MULTI_SNAPSHOTS
    3227             :   if (!FLAG_untrusted_code_mitigations) {
    3228             :     blob = TrustedEmbeddedBlob();
    3229             :     size = TrustedEmbeddedBlobSize();
    3230             :   }
    3231             : #endif
    3232             : 
    3233       62441 :   if (StickyEmbeddedBlob() != nullptr) {
    3234             :     base::MutexGuard guard(current_embedded_blob_refcount_mutex_.Pointer());
    3235             :     // Check again now that we hold the lock.
    3236          55 :     if (StickyEmbeddedBlob() != nullptr) {
    3237             :       blob = StickyEmbeddedBlob();
    3238             :       size = StickyEmbeddedBlobSize();
    3239          55 :       current_embedded_blob_refs_++;
    3240             :     }
    3241             :   }
    3242             : 
    3243       62441 :   if (blob == nullptr) {
    3244           1 :     CHECK_EQ(0, size);
    3245             :   } else {
    3246       62440 :     SetEmbeddedBlob(blob, size);
    3247             :   }
    3248       62441 : }
    3249             : 
    3250          56 : void Isolate::CreateAndSetEmbeddedBlob() {
    3251             :   base::MutexGuard guard(current_embedded_blob_refcount_mutex_.Pointer());
    3252             : 
    3253             :   PrepareBuiltinSourcePositionMap();
    3254             : 
    3255             :   // If a sticky blob has been set, we reuse it.
    3256          56 :   if (StickyEmbeddedBlob() != nullptr) {
    3257           0 :     CHECK_EQ(embedded_blob(), StickyEmbeddedBlob());
    3258           0 :     CHECK_EQ(CurrentEmbeddedBlob(), StickyEmbeddedBlob());
    3259             :   } else {
    3260             :     // Create and set a new embedded blob.
    3261             :     uint8_t* data;
    3262             :     uint32_t size;
    3263          56 :     InstructionStream::CreateOffHeapInstructionStream(this, &data, &size);
    3264             : 
    3265          56 :     CHECK_EQ(0, current_embedded_blob_refs_);
    3266          56 :     const uint8_t* const_data = const_cast<const uint8_t*>(data);
    3267          56 :     SetEmbeddedBlob(const_data, size);
    3268          56 :     current_embedded_blob_refs_++;
    3269             : 
    3270          56 :     SetStickyEmbeddedBlob(const_data, size);
    3271             :   }
    3272             : 
    3273          56 :   CreateOffHeapTrampolines(this);
    3274          56 : }
    3275             : 
    3276       62427 : void Isolate::TearDownEmbeddedBlob() {
    3277             :   // Nothing to do in case the blob is embedded into the binary or unset.
    3278       62427 :   if (StickyEmbeddedBlob() == nullptr) return;
    3279             : 
    3280         111 :   CHECK_EQ(embedded_blob(), StickyEmbeddedBlob());
    3281         111 :   CHECK_EQ(CurrentEmbeddedBlob(), StickyEmbeddedBlob());
    3282             : 
    3283             :   base::MutexGuard guard(current_embedded_blob_refcount_mutex_.Pointer());
    3284         111 :   current_embedded_blob_refs_--;
    3285         111 :   if (current_embedded_blob_refs_ == 0 && enable_embedded_blob_refcounting_) {
    3286             :     // We own the embedded blob and are the last holder. Free it.
    3287             :     InstructionStream::FreeOffHeapInstructionStream(
    3288           0 :         const_cast<uint8_t*>(embedded_blob()), embedded_blob_size());
    3289           0 :     ClearEmbeddedBlob();
    3290             :   }
    3291             : }
    3292             : 
    3293           1 : bool Isolate::InitWithoutSnapshot() { return Init(nullptr, nullptr); }
    3294             : 
    3295       62329 : bool Isolate::InitWithSnapshot(ReadOnlyDeserializer* read_only_deserializer,
    3296             :                                StartupDeserializer* startup_deserializer) {
    3297             :   DCHECK_NOT_NULL(read_only_deserializer);
    3298             :   DCHECK_NOT_NULL(startup_deserializer);
    3299       62329 :   return Init(read_only_deserializer, startup_deserializer);
    3300             : }
    3301             : 
    3302       62440 : bool Isolate::Init(ReadOnlyDeserializer* read_only_deserializer,
    3303             :                    StartupDeserializer* startup_deserializer) {
    3304             :   TRACE_ISOLATE(init);
    3305       62440 :   const bool create_heap_objects = (read_only_deserializer == nullptr);
    3306             :   // We either have both or neither.
    3307             :   DCHECK_EQ(create_heap_objects, startup_deserializer == nullptr);
    3308             : 
    3309             :   base::ElapsedTimer timer;
    3310       62440 :   if (create_heap_objects && FLAG_profile_deserialization) timer.Start();
    3311             : 
    3312       62440 :   time_millis_at_init_ = heap_.MonotonicallyIncreasingTimeInMs();
    3313             : 
    3314       62439 :   stress_deopt_count_ = FLAG_deopt_every_n_times;
    3315       62439 :   force_slow_path_ = FLAG_force_slow_path;
    3316             : 
    3317       62439 :   has_fatal_error_ = false;
    3318             : 
    3319             :   // The initialization process does not handle memory exhaustion.
    3320             :   AlwaysAllocateScope always_allocate(this);
    3321             : 
    3322             :   // Safe after setting Heap::isolate_, and initializing StackGuard
    3323       62439 :   heap_.SetStackLimits();
    3324             : 
    3325             : #define ASSIGN_ELEMENT(CamelName, hacker_name)                  \
    3326             :   isolate_addresses_[IsolateAddressId::k##CamelName##Address] = \
    3327             :       reinterpret_cast<Address>(hacker_name##_address());
    3328      749292 :   FOR_EACH_ISOLATE_ADDRESS_NAME(ASSIGN_ELEMENT)
    3329             : #undef ASSIGN_ELEMENT
    3330             : 
    3331       62441 :   compilation_cache_ = new CompilationCache(this);
    3332      124884 :   descriptor_lookup_cache_ = new DescriptorLookupCache();
    3333      124884 :   unicode_cache_ = new UnicodeCache();
    3334       62442 :   inner_pointer_to_code_cache_ = new InnerPointerToCodeCache(this);
    3335       62442 :   global_handles_ = new GlobalHandles(this);
    3336      124884 :   eternal_handles_ = new EternalHandles();
    3337       62442 :   bootstrapper_ = new Bootstrapper(this);
    3338      124884 :   handle_scope_implementer_ = new HandleScopeImplementer(this);
    3339       62442 :   load_stub_cache_ = new StubCache(this);
    3340       62441 :   store_stub_cache_ = new StubCache(this);
    3341      124884 :   materialized_object_store_ = new MaterializedObjectStore(this);
    3342       62442 :   regexp_stack_ = new RegExpStack();
    3343       62441 :   regexp_stack_->isolate_ = this;
    3344       62441 :   date_cache_ = new DateCache();
    3345       62442 :   heap_profiler_ = new HeapProfiler(heap());
    3346       62442 :   interpreter_ = new interpreter::Interpreter(this);
    3347             : 
    3348             :   compiler_dispatcher_ =
    3349       62442 :       new CompilerDispatcher(this, V8::GetCurrentPlatform(), FLAG_stack_size);
    3350             : 
    3351             :   // Enable logging before setting up the heap
    3352       62442 :   logger_->SetUp(this);
    3353             : 
    3354             :   { // NOLINT
    3355             :     // Ensure that the thread has a valid stack guard.  The v8::Locker object
    3356             :     // will ensure this too, but we don't have to use lockers if we are only
    3357             :     // using one thread.
    3358             :     ExecutionAccess lock(this);
    3359       62442 :     stack_guard_.InitThread(lock);
    3360             :   }
    3361             : 
    3362             :   // SetUp the object heap.
    3363             :   DCHECK(!heap_.HasBeenSetUp());
    3364       62442 :   heap_.SetUp();
    3365       62442 :   ReadOnlyHeap::SetUp(this, read_only_deserializer);
    3366       62442 :   heap_.SetUpSpaces();
    3367             : 
    3368       62442 :   isolate_data_.external_reference_table()->Init(this);
    3369             : 
    3370             :   // Setup the wasm engine.
    3371       62442 :   if (wasm_engine_ == nullptr) {
    3372      124716 :     SetWasmEngine(wasm::WasmEngine::GetWasmEngine());
    3373             :   }
    3374             :   DCHECK_NOT_NULL(wasm_engine_);
    3375             : 
    3376       62442 :   deoptimizer_data_ = new DeoptimizerData(heap());
    3377             : 
    3378       62442 :   if (setup_delegate_ == nullptr) {
    3379      124354 :     setup_delegate_ = new SetupIsolateDelegate(create_heap_objects);
    3380             :   }
    3381             : 
    3382       62442 :   if (!setup_delegate_->SetupHeap(&heap_)) {
    3383           0 :     V8::FatalProcessOutOfMemory(this, "heap object creation");
    3384             :     return false;
    3385             :   }
    3386             : 
    3387       62442 :   if (create_heap_objects) {
    3388             :     // Terminate the partial snapshot cache so we can iterate.
    3389         112 :     partial_snapshot_cache_.push_back(ReadOnlyRoots(this).undefined_value());
    3390             :   }
    3391             : 
    3392             :   InitializeThreadLocal();
    3393             : 
    3394             :   // Profiler has to be created after ThreadLocal is initialized
    3395             :   // because it makes use of interrupts.
    3396       62442 :   tracing_cpu_profiler_.reset(new TracingCpuProfilerImpl(this));
    3397             : 
    3398       62442 :   bootstrapper_->Initialize(create_heap_objects);
    3399             : 
    3400       62442 :   if (FLAG_embedded_builtins && create_heap_objects) {
    3401          56 :     builtins_constants_table_builder_ = new BuiltinsConstantsTableBuilder(this);
    3402             :   }
    3403       62442 :   setup_delegate_->SetupBuiltins(this);
    3404             : #ifndef V8_TARGET_ARCH_ARM
    3405       62442 :   if (create_heap_objects) {
    3406             :     // Store the interpreter entry trampoline on the root list. It is used as a
    3407             :     // template for further copies that may later be created to help profile
    3408             :     // interpreted code.
    3409             :     // We currently cannot do this on arm due to RELATIVE_CODE_TARGETs
    3410             :     // assuming that all possible Code targets may be addressed with an int24
    3411             :     // offset, effectively limiting code space size to 32MB. We can guarantee
    3412             :     // this at mksnapshot-time, but not at runtime.
    3413             :     // See also: https://crbug.com/v8/8713.
    3414          56 :     heap_.SetInterpreterEntryTrampolineForProfiling(
    3415          56 :         heap_.builtin(Builtins::kInterpreterEntryTrampoline));
    3416             :   }
    3417             : #endif
    3418       62442 :   if (FLAG_embedded_builtins && create_heap_objects) {
    3419          56 :     builtins_constants_table_builder_->Finalize();
    3420         112 :     delete builtins_constants_table_builder_;
    3421          56 :     builtins_constants_table_builder_ = nullptr;
    3422             : 
    3423          56 :     CreateAndSetEmbeddedBlob();
    3424             :   }
    3425             : 
    3426             :   // Initialize custom memcopy and memmove functions (must happen after
    3427             :   // embedded blob setup).
    3428       62442 :   init_memcopy_functions();
    3429             : 
    3430       62442 :   if (FLAG_log_internal_timer_events) {
    3431             :     set_event_logger(Logger::DefaultEventLoggerSentinel);
    3432             :   }
    3433             : 
    3434       62442 :   if (FLAG_trace_turbo || FLAG_trace_turbo_graph || FLAG_turbo_profiling) {
    3435           5 :     PrintF("Concurrent recompilation has been disabled for tracing.\n");
    3436       62437 :   } else if (OptimizingCompileDispatcher::Enabled()) {
    3437       62338 :     optimizing_compile_dispatcher_ = new OptimizingCompileDispatcher(this);
    3438             :   }
    3439             : 
    3440             :   // Initialize runtime profiler before deserialization, because collections may
    3441             :   // occur, clearing/updating ICs.
    3442       62442 :   runtime_profiler_ = new RuntimeProfiler(this);
    3443             : 
    3444             :   // If we are deserializing, read the state into the now-empty heap.
    3445             :   {
    3446             :     AlwaysAllocateScope always_allocate(this);
    3447      124884 :     CodeSpaceMemoryModificationScope modification_scope(&heap_);
    3448             : 
    3449       62442 :     if (!create_heap_objects) {
    3450       62386 :       startup_deserializer->DeserializeInto(this);
    3451             :     } else {
    3452          56 :       heap_.read_only_heap()->OnCreateHeapObjectsComplete();
    3453             :     }
    3454       62441 :     load_stub_cache_->Initialize();
    3455       62441 :     store_stub_cache_->Initialize();
    3456       62442 :     interpreter_->Initialize();
    3457       62442 :     heap_.NotifyDeserializationComplete();
    3458             :   }
    3459       62442 :   delete setup_delegate_;
    3460       62442 :   setup_delegate_ = nullptr;
    3461             : 
    3462             :   // Initialize the builtin entry table.
    3463       62442 :   Builtins::UpdateBuiltinEntryTable(this);
    3464             : 
    3465             : #ifdef DEBUG
    3466             :   // Verify that the current heap state (usually deserialized from the snapshot)
    3467             :   // is compatible with the embedded blob. If this DCHECK fails, we've likely
    3468             :   // loaded a snapshot generated by a different V8 version or build-time
    3469             :   // configuration.
    3470             :   if (!IsolateIsCompatibleWithEmbeddedBlob(this)) {
    3471             :     FATAL(
    3472             :         "The Isolate is incompatible with the embedded blob. This is usually "
    3473             :         "caused by incorrect usage of mksnapshot. When generating custom "
    3474             :         "snapshots, embedders must ensure they pass the same flags as during "
    3475             :         "the V8 build process (e.g.: --turbo-instruction-scheduling).");
    3476             :   }
    3477             :   DCHECK_IMPLIES(FLAG_jitless, FLAG_embedded_builtins);
    3478             : #endif  // DEBUG
    3479             : 
    3480             : #ifndef V8_TARGET_ARCH_ARM
    3481             :   // The IET for profiling should always be a full on-heap Code object.
    3482             :   DCHECK(!Code::cast(heap_.interpreter_entry_trampoline_for_profiling())
    3483             :               ->is_off_heap_trampoline());
    3484             : #endif  // V8_TARGET_ARCH_ARM
    3485             : 
    3486             :   if (FLAG_print_builtin_code) builtins()->PrintBuiltinCode();
    3487             :   if (FLAG_print_builtin_size) builtins()->PrintBuiltinSize();
    3488             : 
    3489             :   // Finish initialization of ThreadLocal after deserialization is done.
    3490             :   clear_pending_exception();
    3491             :   clear_pending_message();
    3492             :   clear_scheduled_exception();
    3493             : 
    3494             :   // Deserializing may put strange things in the root array's copy of the
    3495             :   // stack guard.
    3496       62442 :   heap_.SetStackLimits();
    3497             : 
    3498             :   // Quiet the heap NaN if needed on target platform.
    3499             :   if (!create_heap_objects)
    3500             :     Assembler::QuietNaN(ReadOnlyRoots(this).nan_value());
    3501             : 
    3502       62442 :   if (FLAG_trace_turbo) {
    3503             :     // Create an empty file.
    3504          10 :     std::ofstream(GetTurboCfgFileName(this).c_str(), std::ios_base::trunc);
    3505             :   }
    3506             : 
    3507             :   {
    3508             :     HandleScope scope(this);
    3509       62442 :     ast_string_constants_ = new AstStringConstants(this, HashSeed(this));
    3510             :   }
    3511             : 
    3512       62442 :   initialized_from_snapshot_ = !create_heap_objects;
    3513             : 
    3514       62442 :   if (!FLAG_inline_new) heap_.DisableInlineAllocation();
    3515             : 
    3516       62442 :   if (FLAG_stress_sampling_allocation_profiler > 0) {
    3517           0 :     uint64_t sample_interval = FLAG_stress_sampling_allocation_profiler;
    3518             :     int stack_depth = 128;
    3519             :     v8::HeapProfiler::SamplingFlags sampling_flags =
    3520             :         v8::HeapProfiler::SamplingFlags::kSamplingForceGC;
    3521             :     heap_profiler()->StartSamplingHeapProfiler(sample_interval, stack_depth,
    3522           0 :                                                sampling_flags);
    3523             :   }
    3524             : 
    3525             : #if defined(V8_OS_WIN_X64)
    3526             :   if (win64_unwindinfo::CanRegisterUnwindInfoForNonABICompliantCodeRange()) {
    3527             :     const base::AddressRegion& code_range =
    3528             :         heap()->memory_allocator()->code_range();
    3529             :     void* start = reinterpret_cast<void*>(code_range.begin());
    3530             :     size_t size_in_bytes = code_range.size();
    3531             :     win64_unwindinfo::RegisterNonABICompliantCodeRange(start, size_in_bytes);
    3532             :   }
    3533             : #endif
    3534             : 
    3535       62442 :   if (create_heap_objects && FLAG_profile_deserialization) {
    3536           0 :     double ms = timer.Elapsed().InMillisecondsF();
    3537           0 :     PrintF("[Initializing isolate from scratch took %0.3f ms]\n", ms);
    3538             :   }
    3539             : 
    3540             :   return true;
    3541             : }
    3542             : 
    3543      224153 : void Isolate::Enter() {
    3544             :   Isolate* current_isolate = nullptr;
    3545             :   PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
    3546      224149 :   if (current_data != nullptr) {
    3547       11395 :     current_isolate = current_data->isolate_;
    3548             :     DCHECK_NOT_NULL(current_isolate);
    3549       11395 :     if (current_isolate == this) {
    3550             :       DCHECK(Current() == this);
    3551             :       DCHECK_NOT_NULL(entry_stack_);
    3552             :       DCHECK(entry_stack_->previous_thread_data == nullptr ||
    3553             :              entry_stack_->previous_thread_data->thread_id() ==
    3554             :                  ThreadId::Current());
    3555             :       // Same thread re-enters the isolate, no need to re-init anything.
    3556       10241 :       entry_stack_->entry_count++;
    3557       10241 :       return;
    3558             :     }
    3559             :   }
    3560             : 
    3561      213908 :   PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread();
    3562             :   DCHECK_NOT_NULL(data);
    3563             :   DCHECK(data->isolate_ == this);
    3564             : 
    3565             :   EntryStackItem* item = new EntryStackItem(current_data,
    3566             :                                             current_isolate,
    3567      213915 :                                             entry_stack_);
    3568      213917 :   entry_stack_ = item;
    3569             : 
    3570      213917 :   SetIsolateThreadLocals(this, data);
    3571             : 
    3572             :   // In case it's the first time some thread enters the isolate.
    3573             :   set_thread_id(data->thread_id());
    3574             : }
    3575             : 
    3576             : 
    3577      224149 : void Isolate::Exit() {
    3578             :   DCHECK_NOT_NULL(entry_stack_);
    3579             :   DCHECK(entry_stack_->previous_thread_data == nullptr ||
    3580             :          entry_stack_->previous_thread_data->thread_id() ==
    3581             :              ThreadId::Current());
    3582             : 
    3583      224149 :   if (--entry_stack_->entry_count > 0) return;
    3584             : 
    3585             :   DCHECK_NOT_NULL(CurrentPerIsolateThreadData());
    3586             :   DCHECK(CurrentPerIsolateThreadData()->isolate_ == this);
    3587             : 
    3588             :   // Pop the stack.
    3589      213909 :   EntryStackItem* item = entry_stack_;
    3590      213909 :   entry_stack_ = item->previous_item;
    3591             : 
    3592      213909 :   PerIsolateThreadData* previous_thread_data = item->previous_thread_data;
    3593      213909 :   Isolate* previous_isolate = item->previous_isolate;
    3594             : 
    3595      213909 :   delete item;
    3596             : 
    3597             :   // Reinit the current thread for the isolate it was running before this one.
    3598      213912 :   SetIsolateThreadLocals(previous_isolate, previous_thread_data);
    3599             : }
    3600             : 
    3601             : 
    3602        6884 : void Isolate::LinkDeferredHandles(DeferredHandles* deferred) {
    3603        6884 :   deferred->next_ = deferred_handles_head_;
    3604        6884 :   if (deferred_handles_head_ != nullptr) {
    3605        2039 :     deferred_handles_head_->previous_ = deferred;
    3606             :   }
    3607        6884 :   deferred_handles_head_ = deferred;
    3608        6884 : }
    3609             : 
    3610             : 
    3611        6884 : void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) {
    3612             : #ifdef DEBUG
    3613             :   // In debug mode assert that the linked list is well-formed.
    3614             :   DeferredHandles* deferred_iterator = deferred;
    3615             :   while (deferred_iterator->previous_ != nullptr) {
    3616             :     deferred_iterator = deferred_iterator->previous_;
    3617             :   }
    3618             :   DCHECK(deferred_handles_head_ == deferred_iterator);
    3619             : #endif
    3620        6884 :   if (deferred_handles_head_ == deferred) {
    3621        5153 :     deferred_handles_head_ = deferred_handles_head_->next_;
    3622             :   }
    3623        6884 :   if (deferred->next_ != nullptr) {
    3624         817 :     deferred->next_->previous_ = deferred->previous_;
    3625             :   }
    3626        6884 :   if (deferred->previous_ != nullptr) {
    3627        1731 :     deferred->previous_->next_ = deferred->next_;
    3628             :   }
    3629        6884 : }
    3630             : 
    3631       62427 : void Isolate::DumpAndResetStats() {
    3632       62427 :   if (turbo_statistics() != nullptr) {
    3633             :     DCHECK(FLAG_turbo_stats || FLAG_turbo_stats_nvp);
    3634           0 :     StdoutStream os;
    3635           0 :     if (FLAG_turbo_stats) {
    3636           0 :       AsPrintableStatistics ps = {*turbo_statistics(), false};
    3637           0 :       os << ps << std::endl;
    3638             :     }
    3639           0 :     if (FLAG_turbo_stats_nvp) {
    3640           0 :       AsPrintableStatistics ps = {*turbo_statistics(), true};
    3641           0 :       os << ps << std::endl;
    3642             :     }
    3643           0 :     delete turbo_statistics_;
    3644           0 :     turbo_statistics_ = nullptr;
    3645             :   }
    3646             :   // TODO(7424): There is no public API for the {WasmEngine} yet. So for now we
    3647             :   // just dump and reset the engines statistics together with the Isolate.
    3648       62427 :   if (FLAG_turbo_stats_wasm) {
    3649           0 :     wasm_engine()->DumpAndResetTurboStatistics();
    3650             :   }
    3651       62427 :   if (V8_UNLIKELY(TracingFlags::runtime_stats.load(std::memory_order_relaxed) ==
    3652             :                   v8::tracing::TracingCategoryObserver::ENABLED_BY_NATIVE)) {
    3653             :     counters()->worker_thread_runtime_call_stats()->AddToMainTable(
    3654           0 :         counters()->runtime_call_stats());
    3655           0 :     counters()->runtime_call_stats()->Print();
    3656           0 :     counters()->runtime_call_stats()->Reset();
    3657             :   }
    3658       62427 : }
    3659             : 
    3660       23758 : void Isolate::AbortConcurrentOptimization(BlockingBehavior behavior) {
    3661       23758 :   if (concurrent_recompilation_enabled()) {
    3662             :     DisallowHeapAllocation no_recursive_gc;
    3663       23702 :     optimizing_compile_dispatcher()->Flush(behavior);
    3664             :   }
    3665       23758 : }
    3666             : 
    3667           0 : CompilationStatistics* Isolate::GetTurboStatistics() {
    3668           0 :   if (turbo_statistics() == nullptr)
    3669           0 :     set_turbo_statistics(new CompilationStatistics());
    3670           0 :   return turbo_statistics();
    3671             : }
    3672             : 
    3673             : 
    3674         264 : CodeTracer* Isolate::GetCodeTracer() {
    3675         269 :   if (code_tracer() == nullptr) set_code_tracer(new CodeTracer(id()));
    3676         264 :   return code_tracer();
    3677             : }
    3678             : 
    3679     1630650 : bool Isolate::use_optimizer() {
    3680     1809016 :   return FLAG_opt && !serializer_enabled_ && CpuFeatures::SupportsOptimizer() &&
    3681     1630650 :          !is_count_code_coverage();
    3682             : }
    3683             : 
    3684      483599 : bool Isolate::NeedsDetailedOptimizedCodeLineInfo() const {
    3685      483599 :   return NeedsSourcePositionsForProfiling() ||
    3686      483601 :          detailed_source_positions_for_profiling();
    3687             : }
    3688             : 
    3689     1604795 : bool Isolate::NeedsSourcePositionsForProfiling() const {
    3690     1603662 :   return FLAG_trace_deopt || FLAG_trace_turbo || FLAG_trace_turbo_graph ||
    3691     3206796 :          FLAG_turbo_profiling || FLAG_perf_prof || is_profiling() ||
    3692     4774143 :          debug_->is_active() || logger_->is_logging() || FLAG_trace_maps;
    3693             : }
    3694             : 
    3695        1498 : void Isolate::SetFeedbackVectorsForProfilingTools(Object value) {
    3696             :   DCHECK(value->IsUndefined(this) || value->IsArrayList());
    3697             :   heap()->set_feedback_vectors_for_profiling_tools(value);
    3698        1498 : }
    3699             : 
    3700         164 : void Isolate::MaybeInitializeVectorListFromHeap() {
    3701         164 :   if (!heap()->feedback_vectors_for_profiling_tools()->IsUndefined(this)) {
    3702             :     // Already initialized, return early.
    3703             :     DCHECK(heap()->feedback_vectors_for_profiling_tools()->IsArrayList());
    3704           8 :     return;
    3705             :   }
    3706             : 
    3707             :   // Collect existing feedback vectors.
    3708             :   std::vector<Handle<FeedbackVector>> vectors;
    3709             : 
    3710             :   {
    3711         312 :     HeapIterator heap_iterator(heap());
    3712     1187999 :     for (HeapObject current_obj = heap_iterator.next(); !current_obj.is_null();
    3713             :          current_obj = heap_iterator.next()) {
    3714     2375254 :       if (!current_obj->IsFeedbackVector()) continue;
    3715             : 
    3716         432 :       FeedbackVector vector = FeedbackVector::cast(current_obj);
    3717         432 :       SharedFunctionInfo shared = vector->shared_function_info();
    3718             : 
    3719             :       // No need to preserve the feedback vector for non-user-visible functions.
    3720         432 :       if (!shared->IsSubjectToDebugging()) continue;
    3721             : 
    3722         432 :       vectors.emplace_back(vector, this);
    3723             :     }
    3724             :   }
    3725             : 
    3726             :   // Add collected feedback vectors to the root list lest we lose them to GC.
    3727             :   Handle<ArrayList> list =
    3728         156 :       ArrayList::New(this, static_cast<int>(vectors.size()));
    3729        1020 :   for (const auto& vector : vectors) list = ArrayList::Add(this, list, vector);
    3730             :   SetFeedbackVectorsForProfilingTools(*list);
    3731             : }
    3732             : 
    3733           5 : void Isolate::set_date_cache(DateCache* date_cache) {
    3734           5 :   if (date_cache != date_cache_) {
    3735           5 :     delete date_cache_;
    3736             :   }
    3737           5 :   date_cache_ = date_cache;
    3738           5 : }
    3739             : 
    3740       15319 : bool Isolate::IsArrayOrObjectOrStringPrototype(Object object) {
    3741             :   Object context = heap()->native_contexts_list();
    3742       59927 :   while (!context->IsUndefined(this)) {
    3743       23157 :     Context current_context = Context::cast(context);
    3744       69326 :     if (current_context->initial_object_prototype() == object ||
    3745       45519 :         current_context->initial_array_prototype() == object ||
    3746       22362 :         current_context->initial_string_prototype() == object) {
    3747         853 :       return true;
    3748             :     }
    3749       22304 :     context = current_context->next_context_link();
    3750             :   }
    3751             :   return false;
    3752             : }
    3753             : 
    3754     6732286 : bool Isolate::IsInAnyContext(Object object, uint32_t index) {
    3755             :   DisallowHeapAllocation no_gc;
    3756             :   Object context = heap()->native_contexts_list();
    3757    11608514 :   while (!context->IsUndefined(this)) {
    3758     8046849 :     Context current_context = Context::cast(context);
    3759    16093699 :     if (current_context->get(index) == object) {
    3760     5608736 :       return true;
    3761             :     }
    3762     2438114 :     context = current_context->next_context_link();
    3763             :   }
    3764             :   return false;
    3765             : }
    3766             : 
    3767      100545 : bool Isolate::IsNoElementsProtectorIntact(Context context) {
    3768             :   PropertyCell no_elements_cell = heap()->no_elements_protector();
    3769             :   bool cell_reports_intact =
    3770    11705530 :       no_elements_cell->value()->IsSmi() &&
    3771             :       Smi::ToInt(no_elements_cell->value()) == kProtectorValid;
    3772             : 
    3773             : #ifdef DEBUG
    3774             :   Context native_context = context->native_context();
    3775             : 
    3776             :   Map root_array_map =
    3777             :       native_context->GetInitialJSArrayMap(GetInitialFastElementsKind());
    3778             :   JSObject initial_array_proto = JSObject::cast(
    3779             :       native_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
    3780             :   JSObject initial_object_proto = JSObject::cast(
    3781             :       native_context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX));
    3782             :   JSObject initial_string_proto = JSObject::cast(
    3783             :       native_context->get(Context::INITIAL_STRING_PROTOTYPE_INDEX));
    3784             : 
    3785             :   if (root_array_map.is_null() || initial_array_proto == initial_object_proto) {
    3786             :     // We are in the bootstrapping process, and the entire check sequence
    3787             :     // shouldn't be performed.
    3788             :     return cell_reports_intact;
    3789             :   }
    3790             : 
    3791             :   // Check that the array prototype hasn't been altered WRT empty elements.
    3792             :   if (root_array_map->prototype() != initial_array_proto) {
    3793             :     DCHECK_EQ(false, cell_reports_intact);
    3794             :     return cell_reports_intact;
    3795             :   }
    3796             : 
    3797             :   FixedArrayBase elements = initial_array_proto->elements();
    3798             :   ReadOnlyRoots roots(heap());
    3799             :   if (elements != roots.empty_fixed_array() &&
    3800             :       elements != roots.empty_slow_element_dictionary()) {
    3801             :     DCHECK_EQ(false, cell_reports_intact);
    3802             :     return cell_reports_intact;
    3803             :   }
    3804             : 
    3805             :   // Check that the Object.prototype hasn't been altered WRT empty elements.
    3806             :   elements = initial_object_proto->elements();
    3807             :   if (elements != roots.empty_fixed_array() &&
    3808             :       elements != roots.empty_slow_element_dictionary()) {
    3809             :     DCHECK_EQ(false, cell_reports_intact);
    3810             :     return cell_reports_intact;
    3811             :   }
    3812             : 
    3813             :   // Check that the Array.prototype has the Object.prototype as its
    3814             :   // [[Prototype]] and that the Object.prototype has a null [[Prototype]].
    3815             :   PrototypeIterator iter(this, initial_array_proto);
    3816             :   if (iter.IsAtEnd() || iter.GetCurrent() != initial_object_proto) {
    3817             :     DCHECK_EQ(false, cell_reports_intact);
    3818             :     DCHECK(!has_pending_exception());
    3819             :     return cell_reports_intact;
    3820             :   }
    3821             :   iter.Advance();
    3822             :   if (!iter.IsAtEnd()) {
    3823             :     DCHECK_EQ(false, cell_reports_intact);
    3824             :     DCHECK(!has_pending_exception());
    3825             :     return cell_reports_intact;
    3826             :   }
    3827             :   DCHECK(!has_pending_exception());
    3828             : 
    3829             :   // Check that the String.prototype hasn't been altered WRT empty elements.
    3830             :   elements = initial_string_proto->elements();
    3831             :   if (elements != roots.empty_fixed_array() &&
    3832             :       elements != roots.empty_slow_element_dictionary()) {
    3833             :     DCHECK_EQ(false, cell_reports_intact);
    3834             :     return cell_reports_intact;
    3835             :   }
    3836             : 
    3837             :   // Check that the String.prototype has the Object.prototype
    3838             :   // as its [[Prototype]] still.
    3839             :   if (initial_string_proto->map()->prototype() != initial_object_proto) {
    3840             :     DCHECK_EQ(false, cell_reports_intact);
    3841             :     return cell_reports_intact;
    3842             :   }
    3843             : #endif
    3844             : 
    3845      100545 :   return cell_reports_intact;
    3846             : }
    3847             : 
    3848     5735464 : bool Isolate::IsNoElementsProtectorIntact() {
    3849     5735464 :   return Isolate::IsNoElementsProtectorIntact(context());
    3850             : }
    3851             : 
    3852      301064 : bool Isolate::IsIsConcatSpreadableLookupChainIntact() {
    3853             :   Cell is_concat_spreadable_cell = heap()->is_concat_spreadable_protector();
    3854             :   bool is_is_concat_spreadable_set =
    3855             :       Smi::ToInt(is_concat_spreadable_cell->value()) == kProtectorInvalid;
    3856             : #ifdef DEBUG
    3857             :   Map root_array_map =
    3858             :       raw_native_context()->GetInitialJSArrayMap(GetInitialFastElementsKind());
    3859             :   if (root_array_map.is_null()) {
    3860             :     // Ignore the value of is_concat_spreadable during bootstrap.
    3861             :     return !is_is_concat_spreadable_set;
    3862             :   }
    3863             :   Handle<Object> array_prototype(array_function()->prototype(), this);
    3864             :   Handle<Symbol> key = factory()->is_concat_spreadable_symbol();
    3865             :   Handle<Object> value;
    3866             :   LookupIterator it(this, array_prototype, key);
    3867             :   if (it.IsFound() && !JSReceiver::GetDataProperty(&it)->IsUndefined(this)) {
    3868             :     // TODO(cbruni): Currently we do not revert if we unset the
    3869             :     // @@isConcatSpreadable property on Array.prototype or Object.prototype
    3870             :     // hence the reverse implication doesn't hold.
    3871             :     DCHECK(is_is_concat_spreadable_set);
    3872             :     return false;
    3873             :   }
    3874             : #endif  // DEBUG
    3875             : 
    3876      301064 :   return !is_is_concat_spreadable_set;
    3877             : }
    3878             : 
    3879       10387 : bool Isolate::IsIsConcatSpreadableLookupChainIntact(JSReceiver receiver) {
    3880       10387 :   if (!IsIsConcatSpreadableLookupChainIntact()) return false;
    3881        4282 :   return !receiver->HasProxyInPrototype(this);
    3882             : }
    3883             : 
    3884           0 : bool Isolate::IsPromiseHookProtectorIntact() {
    3885             :   PropertyCell promise_hook_cell = heap()->promise_hook_protector();
    3886             :   bool is_promise_hook_protector_intact =
    3887           0 :       Smi::ToInt(promise_hook_cell->value()) == kProtectorValid;
    3888             :   DCHECK_IMPLIES(is_promise_hook_protector_intact,
    3889             :                  !promise_hook_or_async_event_delegate_);
    3890             :   DCHECK_IMPLIES(is_promise_hook_protector_intact,
    3891             :                  !promise_hook_or_debug_is_active_or_async_event_delegate_);
    3892           0 :   return is_promise_hook_protector_intact;
    3893             : }
    3894             : 
    3895        1728 : bool Isolate::IsPromiseResolveLookupChainIntact() {
    3896             :   Cell promise_resolve_cell = heap()->promise_resolve_protector();
    3897             :   bool is_promise_resolve_protector_intact =
    3898        1728 :       Smi::ToInt(promise_resolve_cell->value()) == kProtectorValid;
    3899        1728 :   return is_promise_resolve_protector_intact;
    3900             : }
    3901             : 
    3902        1686 : bool Isolate::IsPromiseThenLookupChainIntact() {
    3903             :   PropertyCell promise_then_cell = heap()->promise_then_protector();
    3904             :   bool is_promise_then_protector_intact =
    3905        3296 :       Smi::ToInt(promise_then_cell->value()) == kProtectorValid;
    3906        1686 :   return is_promise_then_protector_intact;
    3907             : }
    3908             : 
    3909        3750 : bool Isolate::IsPromiseThenLookupChainIntact(Handle<JSReceiver> receiver) {
    3910             :   DisallowHeapAllocation no_gc;
    3911        3750 :   if (!receiver->IsJSPromise()) return false;
    3912        1610 :   if (!IsInAnyContext(receiver->map()->prototype(),
    3913             :                       Context::PROMISE_PROTOTYPE_INDEX)) {
    3914             :     return false;
    3915             :   }
    3916        1610 :   return IsPromiseThenLookupChainIntact();
    3917             : }
    3918             : 
    3919     1205980 : void Isolate::UpdateNoElementsProtectorOnSetElement(Handle<JSObject> object) {
    3920             :   DisallowHeapAllocation no_gc;
    3921     1205980 :   if (!object->map()->is_prototype_map()) return;
    3922       16755 :   if (!IsNoElementsProtectorIntact()) return;
    3923       15319 :   if (!IsArrayOrObjectOrStringPrototype(*object)) return;
    3924         853 :   PropertyCell::SetValueWithInvalidation(
    3925             :       this, factory()->no_elements_protector(),
    3926         853 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3927             : }
    3928             : 
    3929          65 : void Isolate::InvalidateIsConcatSpreadableProtector() {
    3930             :   DCHECK(factory()->is_concat_spreadable_protector()->value()->IsSmi());
    3931             :   DCHECK(IsIsConcatSpreadableLookupChainIntact());
    3932         130 :   factory()->is_concat_spreadable_protector()->set_value(
    3933         195 :       Smi::FromInt(kProtectorInvalid));
    3934             :   DCHECK(!IsIsConcatSpreadableLookupChainIntact());
    3935          65 : }
    3936             : 
    3937         230 : void Isolate::InvalidateArrayConstructorProtector() {
    3938             :   DCHECK(factory()->array_constructor_protector()->value()->IsSmi());
    3939             :   DCHECK(IsArrayConstructorIntact());
    3940         460 :   factory()->array_constructor_protector()->set_value(
    3941         690 :       Smi::FromInt(kProtectorInvalid));
    3942             :   DCHECK(!IsArrayConstructorIntact());
    3943         230 : }
    3944             : 
    3945         123 : void Isolate::InvalidateArraySpeciesProtector() {
    3946             :   DCHECK(factory()->array_species_protector()->value()->IsSmi());
    3947             :   DCHECK(IsArraySpeciesLookupChainIntact());
    3948         123 :   PropertyCell::SetValueWithInvalidation(
    3949             :       this, factory()->array_species_protector(),
    3950         123 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3951             :   DCHECK(!IsArraySpeciesLookupChainIntact());
    3952         123 : }
    3953             : 
    3954         245 : void Isolate::InvalidateTypedArraySpeciesProtector() {
    3955             :   DCHECK(factory()->typed_array_species_protector()->value()->IsSmi());
    3956             :   DCHECK(IsTypedArraySpeciesLookupChainIntact());
    3957         245 :   PropertyCell::SetValueWithInvalidation(
    3958             :       this, factory()->typed_array_species_protector(),
    3959         245 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3960             :   DCHECK(!IsTypedArraySpeciesLookupChainIntact());
    3961         245 : }
    3962             : 
    3963          25 : void Isolate::InvalidateRegExpSpeciesProtector() {
    3964             :   DCHECK(factory()->regexp_species_protector()->value()->IsSmi());
    3965             :   DCHECK(IsRegExpSpeciesLookupChainIntact());
    3966          25 :   PropertyCell::SetValueWithInvalidation(
    3967             :       this, factory()->regexp_species_protector(),
    3968          25 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3969             :   DCHECK(!IsRegExpSpeciesLookupChainIntact());
    3970          25 : }
    3971             : 
    3972          59 : void Isolate::InvalidatePromiseSpeciesProtector() {
    3973             :   DCHECK(factory()->promise_species_protector()->value()->IsSmi());
    3974             :   DCHECK(IsPromiseSpeciesLookupChainIntact());
    3975          59 :   PropertyCell::SetValueWithInvalidation(
    3976             :       this, factory()->promise_species_protector(),
    3977          59 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3978             :   DCHECK(!IsPromiseSpeciesLookupChainIntact());
    3979          59 : }
    3980             : 
    3981         143 : void Isolate::InvalidateStringLengthOverflowProtector() {
    3982             :   DCHECK(factory()->string_length_protector()->value()->IsSmi());
    3983             :   DCHECK(IsStringLengthOverflowIntact());
    3984         286 :   factory()->string_length_protector()->set_value(
    3985         429 :       Smi::FromInt(kProtectorInvalid));
    3986             :   DCHECK(!IsStringLengthOverflowIntact());
    3987         143 : }
    3988             : 
    3989         107 : void Isolate::InvalidateArrayIteratorProtector() {
    3990             :   DCHECK(factory()->array_iterator_protector()->value()->IsSmi());
    3991             :   DCHECK(IsArrayIteratorLookupChainIntact());
    3992         107 :   PropertyCell::SetValueWithInvalidation(
    3993             :       this, factory()->array_iterator_protector(),
    3994         107 :       handle(Smi::FromInt(kProtectorInvalid), this));
    3995             :   DCHECK(!IsArrayIteratorLookupChainIntact());
    3996         107 : }
    3997             : 
    3998          55 : void Isolate::InvalidateMapIteratorProtector() {
    3999             :   DCHECK(factory()->map_iterator_protector()->value()->IsSmi());
    4000             :   DCHECK(IsMapIteratorLookupChainIntact());
    4001          55 :   PropertyCell::SetValueWithInvalidation(
    4002             :       this, factory()->map_iterator_protector(),
    4003          55 :       handle(Smi::FromInt(kProtectorInvalid), this));
    4004             :   DCHECK(!IsMapIteratorLookupChainIntact());
    4005          55 : }
    4006             : 
    4007          65 : void Isolate::InvalidateSetIteratorProtector() {
    4008             :   DCHECK(factory()->set_iterator_protector()->value()->IsSmi());
    4009             :   DCHECK(IsSetIteratorLookupChainIntact());
    4010          65 :   PropertyCell::SetValueWithInvalidation(
    4011             :       this, factory()->set_iterator_protector(),
    4012          65 :       handle(Smi::FromInt(kProtectorInvalid), this));
    4013             :   DCHECK(!IsSetIteratorLookupChainIntact());
    4014          65 : }
    4015             : 
    4016          25 : void Isolate::InvalidateStringIteratorProtector() {
    4017             :   DCHECK(factory()->string_iterator_protector()->value()->IsSmi());
    4018             :   DCHECK(IsStringIteratorLookupChainIntact());
    4019          25 :   PropertyCell::SetValueWithInvalidation(
    4020             :       this, factory()->string_iterator_protector(),
    4021          25 :       handle(Smi::FromInt(kProtectorInvalid), this));
    4022             :   DCHECK(!IsStringIteratorLookupChainIntact());
    4023          25 : }
    4024             : 
    4025         426 : void Isolate::InvalidateArrayBufferDetachingProtector() {
    4026             :   DCHECK(factory()->array_buffer_detaching_protector()->value()->IsSmi());
    4027             :   DCHECK(IsArrayBufferDetachingIntact());
    4028         426 :   PropertyCell::SetValueWithInvalidation(
    4029             :       this, factory()->array_buffer_detaching_protector(),
    4030         426 :       handle(Smi::FromInt(kProtectorInvalid), this));
    4031             :   DCHECK(!IsArrayBufferDetachingIntact());
    4032         426 : }
    4033             : 
    4034        2786 : void Isolate::InvalidatePromiseHookProtector() {
    4035             :   DCHECK(factory()->promise_hook_protector()->value()->IsSmi());
    4036             :   DCHECK(IsPromiseHookProtectorIntact());
    4037        2786 :   PropertyCell::SetValueWithInvalidation(
    4038             :       this, factory()->promise_hook_protector(),
    4039        2786 :       handle(Smi::FromInt(kProtectorInvalid), this));
    4040             :   DCHECK(!IsPromiseHookProtectorIntact());
    4041        2786 : }
    4042             : 
    4043           0 : void Isolate::InvalidatePromiseResolveProtector() {
    4044             :   DCHECK(factory()->promise_resolve_protector()->value()->IsSmi());
    4045             :   DCHECK(IsPromiseResolveLookupChainIntact());
    4046           0 :   factory()->promise_resolve_protector()->set_value(
    4047           0 :       Smi::FromInt(kProtectorInvalid));
    4048             :   DCHECK(!IsPromiseResolveLookupChainIntact());
    4049           0 : }
    4050             : 
    4051         103 : void Isolate::InvalidatePromiseThenProtector() {
    4052             :   DCHECK(factory()->promise_then_protector()->value()->IsSmi());
    4053             :   DCHECK(IsPromiseThenLookupChainIntact());
    4054         103 :   PropertyCell::SetValueWithInvalidation(
    4055             :       this, factory()->promise_then_protector(),
    4056         103 :       handle(Smi::FromInt(kProtectorInvalid), this));
    4057             :   DCHECK(!IsPromiseThenLookupChainIntact());
    4058         103 : }
    4059             : 
    4060     6497347 : bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
    4061             :   DisallowHeapAllocation no_gc;
    4062     6497347 :   return IsInAnyContext(*array, Context::INITIAL_ARRAY_PROTOTYPE_INDEX);
    4063             : }
    4064             : 
    4065      128239 : static base::RandomNumberGenerator* ensure_rng_exists(
    4066             :     base::RandomNumberGenerator** rng, int seed) {
    4067      128239 :   if (*rng == nullptr) {
    4068       62324 :     if (seed != 0) {
    4069      121688 :       *rng = new base::RandomNumberGenerator(seed);
    4070             :     } else {
    4071        1480 :       *rng = new base::RandomNumberGenerator();
    4072             :     }
    4073             :   }
    4074      128239 :   return *rng;
    4075             : }
    4076             : 
    4077       74348 : base::RandomNumberGenerator* Isolate::random_number_generator() {
    4078             :   // TODO(bmeurer) Initialized lazily because it depends on flags; can
    4079             :   // be fixed once the default isolate cleanup is done.
    4080      128239 :   return ensure_rng_exists(&random_number_generator_, FLAG_random_seed);
    4081             : }
    4082             : 
    4083           0 : base::RandomNumberGenerator* Isolate::fuzzer_rng() {
    4084           0 :   if (fuzzer_rng_ == nullptr) {
    4085           0 :     int64_t seed = FLAG_fuzzer_random_seed;
    4086           0 :     if (seed == 0) {
    4087             :       seed = random_number_generator()->initial_seed();
    4088             :     }
    4089             : 
    4090           0 :     fuzzer_rng_ = new base::RandomNumberGenerator(seed);
    4091             :   }
    4092             : 
    4093           0 :   return fuzzer_rng_;
    4094             : }
    4095             : 
    4096       53891 : int Isolate::GenerateIdentityHash(uint32_t mask) {
    4097             :   int hash;
    4098             :   int attempts = 0;
    4099       53890 :   do {
    4100       53890 :     hash = random_number_generator()->NextInt() & mask;
    4101       53890 :   } while (hash == 0 && attempts++ < 30);
    4102       53890 :   return hash != 0 ? hash : 1;
    4103             : }
    4104             : 
    4105       20971 : Code Isolate::FindCodeObject(Address a) {
    4106       20971 :   return heap()->GcSafeFindCodeForInnerPointer(a);
    4107             : }
    4108             : 
    4109             : 
    4110             : #ifdef DEBUG
    4111             : #define ISOLATE_FIELD_OFFSET(type, name, ignored)                       \
    4112             : const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
    4113             : ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
    4114             : ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
    4115             : #undef ISOLATE_FIELD_OFFSET
    4116             : #endif
    4117             : 
    4118      255007 : Handle<Symbol> Isolate::SymbolFor(RootIndex dictionary_index,
    4119             :                                   Handle<String> name, bool private_symbol) {
    4120      255007 :   Handle<String> key = factory()->InternalizeString(name);
    4121             :   Handle<NameDictionary> dictionary =
    4122             :       Handle<NameDictionary>::cast(root_handle(dictionary_index));
    4123      255007 :   int entry = dictionary->FindEntry(this, key);
    4124             :   Handle<Symbol> symbol;
    4125      255007 :   if (entry == NameDictionary::kNotFound) {
    4126             :     symbol =
    4127        2723 :         private_symbol ? factory()->NewPrivateSymbol() : factory()->NewSymbol();
    4128        5446 :     symbol->set_name(*key);
    4129             :     dictionary = NameDictionary::Add(this, dictionary, key, symbol,
    4130        2723 :                                      PropertyDetails::Empty(), &entry);
    4131        2723 :     switch (dictionary_index) {
    4132             :       case RootIndex::kPublicSymbolTable:
    4133             :         symbol->set_is_public(true);
    4134             :         heap()->set_public_symbol_table(*dictionary);
    4135             :         break;
    4136             :       case RootIndex::kApiSymbolTable:
    4137             :         heap()->set_api_symbol_table(*dictionary);
    4138             :         break;
    4139             :       case RootIndex::kApiPrivateSymbolTable:
    4140             :         heap()->set_api_private_symbol_table(*dictionary);
    4141             :         break;
    4142             :       default:
    4143           0 :         UNREACHABLE();
    4144             :     }
    4145             :   } else {
    4146             :     symbol = Handle<Symbol>(Symbol::cast(dictionary->ValueAt(entry)), this);
    4147             :   }
    4148      255007 :   return symbol;
    4149             : }
    4150             : 
    4151          15 : void Isolate::AddBeforeCallEnteredCallback(BeforeCallEnteredCallback callback) {
    4152             :   auto pos = std::find(before_call_entered_callbacks_.begin(),
    4153          15 :                        before_call_entered_callbacks_.end(), callback);
    4154          20 :   if (pos != before_call_entered_callbacks_.end()) return;
    4155          10 :   before_call_entered_callbacks_.push_back(callback);
    4156             : }
    4157             : 
    4158           5 : void Isolate::RemoveBeforeCallEnteredCallback(
    4159             :     BeforeCallEnteredCallback callback) {
    4160             :   auto pos = std::find(before_call_entered_callbacks_.begin(),
    4161           5 :                        before_call_entered_callbacks_.end(), callback);
    4162           5 :   if (pos == before_call_entered_callbacks_.end()) return;
    4163           5 :   before_call_entered_callbacks_.erase(pos);
    4164             : }
    4165             : 
    4166          65 : void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
    4167             :   auto pos = std::find(call_completed_callbacks_.begin(),
    4168          65 :                        call_completed_callbacks_.end(), callback);
    4169          70 :   if (pos != call_completed_callbacks_.end()) return;
    4170          60 :   call_completed_callbacks_.push_back(callback);
    4171             : }
    4172             : 
    4173        3730 : void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
    4174             :   auto pos = std::find(call_completed_callbacks_.begin(),
    4175        3730 :                        call_completed_callbacks_.end(), callback);
    4176        3730 :   if (pos == call_completed_callbacks_.end()) return;
    4177          45 :   call_completed_callbacks_.erase(pos);
    4178             : }
    4179             : 
    4180     5427901 : void Isolate::FireCallCompletedCallback(MicrotaskQueue* microtask_queue) {
    4181    10855773 :   if (!handle_scope_implementer()->CallDepthIsZero()) return;
    4182             : 
    4183             :   bool run_microtasks =
    4184      547508 :       microtask_queue && microtask_queue->size() &&
    4185      574666 :       !microtask_queue->HasMicrotasksSuppressions() &&
    4186             :       microtask_queue->microtasks_policy() == v8::MicrotasksPolicy::kAuto;
    4187             : 
    4188      547510 :   if (run_microtasks) {
    4189        1988 :     microtask_queue->RunMicrotasks(this);
    4190             :   } else {
    4191             :     // TODO(marja): (spec) The discussion about when to clear the KeepDuringJob
    4192             :     // set is still open (whether to clear it after every microtask or once
    4193             :     // during a microtask checkpoint). See also
    4194             :     // https://github.com/tc39/proposal-weakrefs/issues/39 .
    4195      545522 :     heap()->ClearKeepDuringJobSet();
    4196             :   }
    4197             : 
    4198      547511 :   if (call_completed_callbacks_.empty()) return;
    4199             :   // Fire callbacks.  Increase call depth to prevent recursive callbacks.
    4200             :   v8::Isolate* isolate = reinterpret_cast<v8::Isolate*>(this);
    4201          60 :   v8::Isolate::SuppressMicrotaskExecutionScope suppress(isolate);
    4202          30 :   std::vector<CallCompletedCallback> callbacks(call_completed_callbacks_);
    4203          65 :   for (auto& callback : callbacks) {
    4204          35 :     callback(reinterpret_cast<v8::Isolate*>(this));
    4205             :   }
    4206             : }
    4207             : 
    4208        8483 : void Isolate::PromiseHookStateUpdated() {
    4209             :   bool promise_hook_or_async_event_delegate =
    4210        8483 :       promise_hook_ || async_event_delegate_;
    4211             :   bool promise_hook_or_debug_is_active_or_async_event_delegate =
    4212        8483 :       promise_hook_or_async_event_delegate || debug()->is_active();
    4213       12975 :   if (promise_hook_or_debug_is_active_or_async_event_delegate &&
    4214             :       IsPromiseHookProtectorIntact()) {
    4215             :     HandleScope scope(this);
    4216        2785 :     InvalidatePromiseHookProtector();
    4217             :   }
    4218        8483 :   promise_hook_or_async_event_delegate_ = promise_hook_or_async_event_delegate;
    4219             :   promise_hook_or_debug_is_active_or_async_event_delegate_ =
    4220        8483 :       promise_hook_or_debug_is_active_or_async_event_delegate;
    4221        8483 : }
    4222             : 
    4223             : namespace {
    4224             : 
    4225          72 : MaybeHandle<JSPromise> NewRejectedPromise(Isolate* isolate,
    4226             :                                           v8::Local<v8::Context> api_context,
    4227             :                                           Handle<Object> exception) {
    4228             :   v8::Local<v8::Promise::Resolver> resolver;
    4229         144 :   ASSIGN_RETURN_ON_SCHEDULED_EXCEPTION_VALUE(
    4230             :       isolate, resolver, v8::Promise::Resolver::New(api_context),
    4231             :       MaybeHandle<JSPromise>());
    4232             : 
    4233         144 :   RETURN_ON_SCHEDULED_EXCEPTION_VALUE(
    4234             :       isolate, resolver->Reject(api_context, v8::Utils::ToLocal(exception)),
    4235             :       MaybeHandle<JSPromise>());
    4236             : 
    4237          72 :   v8::Local<v8::Promise> promise = resolver->GetPromise();
    4238          72 :   return v8::Utils::OpenHandle(*promise);
    4239             : }
    4240             : 
    4241             : }  // namespace
    4242             : 
    4243         482 : MaybeHandle<JSPromise> Isolate::RunHostImportModuleDynamicallyCallback(
    4244             :     Handle<Script> referrer, Handle<Object> specifier) {
    4245             :   v8::Local<v8::Context> api_context =
    4246         482 :       v8::Utils::ToLocal(Handle<Context>(native_context()));
    4247             : 
    4248         482 :   if (host_import_module_dynamically_callback_ == nullptr) {
    4249             :     Handle<Object> exception =
    4250           0 :         factory()->NewError(error_function(), MessageTemplate::kUnsupported);
    4251           0 :     return NewRejectedPromise(this, api_context, exception);
    4252             :   }
    4253             : 
    4254             :   Handle<String> specifier_str;
    4255         482 :   MaybeHandle<String> maybe_specifier = Object::ToString(this, specifier);
    4256         482 :   if (!maybe_specifier.ToHandle(&specifier_str)) {
    4257             :     Handle<Object> exception(pending_exception(), this);
    4258             :     clear_pending_exception();
    4259             : 
    4260          72 :     return NewRejectedPromise(this, api_context, exception);
    4261             :   }
    4262             :   DCHECK(!has_pending_exception());
    4263             : 
    4264             :   v8::Local<v8::Promise> promise;
    4265         820 :   ASSIGN_RETURN_ON_SCHEDULED_EXCEPTION_VALUE(
    4266             :       this, promise,
    4267             :       host_import_module_dynamically_callback_(
    4268             :           api_context, v8::Utils::ScriptOrModuleToLocal(referrer),
    4269             :           v8::Utils::ToLocal(specifier_str)),
    4270             :       MaybeHandle<JSPromise>());
    4271         410 :   return v8::Utils::OpenHandle(*promise);
    4272             : }
    4273             : 
    4274       30797 : void Isolate::SetHostImportModuleDynamicallyCallback(
    4275             :     HostImportModuleDynamicallyCallback callback) {
    4276       30797 :   host_import_module_dynamically_callback_ = callback;
    4277       30797 : }
    4278             : 
    4279          39 : Handle<JSObject> Isolate::RunHostInitializeImportMetaObjectCallback(
    4280             :     Handle<Module> module) {
    4281             :   Handle<Object> host_meta(module->import_meta(), this);
    4282          39 :   if (host_meta->IsTheHole(this)) {
    4283          23 :     host_meta = factory()->NewJSObjectWithNullProto();
    4284          23 :     if (host_initialize_import_meta_object_callback_ != nullptr) {
    4285             :       v8::Local<v8::Context> api_context =
    4286          23 :           v8::Utils::ToLocal(Handle<Context>(native_context()));
    4287          23 :       host_initialize_import_meta_object_callback_(
    4288             :           api_context, Utils::ToLocal(module),
    4289          23 :           v8::Local<v8::Object>::Cast(v8::Utils::ToLocal(host_meta)));
    4290             :     }
    4291          23 :     module->set_import_meta(*host_meta);
    4292             :   }
    4293          39 :   return Handle<JSObject>::cast(host_meta);
    4294             : }
    4295             : 
    4296       30797 : void Isolate::SetHostInitializeImportMetaObjectCallback(
    4297             :     HostInitializeImportMetaObjectCallback callback) {
    4298       30797 :   host_initialize_import_meta_object_callback_ = callback;
    4299       30797 : }
    4300             : 
    4301          12 : MaybeHandle<Object> Isolate::RunPrepareStackTraceCallback(
    4302             :     Handle<Context> context, Handle<JSObject> error, Handle<JSArray> sites) {
    4303          12 :   v8::Local<v8::Context> api_context = Utils::ToLocal(context);
    4304             : 
    4305             :   v8::Local<v8::Value> stack;
    4306          42 :   ASSIGN_RETURN_ON_SCHEDULED_EXCEPTION_VALUE(
    4307             :       this, stack,
    4308             :       prepare_stack_trace_callback_(api_context, Utils::ToLocal(error),
    4309             :                                     Utils::ToLocal(sites)),
    4310             :       MaybeHandle<Object>());
    4311           6 :   return Utils::OpenHandle(*stack);
    4312             : }
    4313             : 
    4314      859504 : int Isolate::LookupOrAddExternallyCompiledFilename(const char* filename) {
    4315      859504 :   if (embedded_file_writer_ != nullptr) {
    4316             :     return embedded_file_writer_->LookupOrAddExternallyCompiledFilename(
    4317       15214 :         filename);
    4318             :   }
    4319             :   return 0;
    4320             : }
    4321             : 
    4322           0 : const char* Isolate::GetExternallyCompiledFilename(int index) const {
    4323           0 :   if (embedded_file_writer_ != nullptr) {
    4324           0 :     return embedded_file_writer_->GetExternallyCompiledFilename(index);
    4325             :   }
    4326             :   return "";
    4327             : }
    4328             : 
    4329           0 : int Isolate::GetExternallyCompiledFilenameCount() const {
    4330           0 :   if (embedded_file_writer_ != nullptr) {
    4331           0 :     return embedded_file_writer_->GetExternallyCompiledFilenameCount();
    4332             :   }
    4333             :   return 0;
    4334             : }
    4335             : 
    4336           0 : void Isolate::PrepareBuiltinSourcePositionMap() {
    4337          56 :   if (embedded_file_writer_ != nullptr) {
    4338             :     return embedded_file_writer_->PrepareBuiltinSourcePositionMap(
    4339           2 :         this->builtins());
    4340             :   }
    4341             : }
    4342             : 
    4343             : #if defined(V8_OS_WIN_X64)
    4344             : void Isolate::SetBuiltinUnwindData(
    4345             :     int builtin_index,
    4346             :     const win64_unwindinfo::BuiltinUnwindInfo& unwinding_info) {
    4347             :   if (embedded_file_writer_ != nullptr) {
    4348             :     embedded_file_writer_->SetBuiltinUnwindData(builtin_index, unwinding_info);
    4349             :   }
    4350             : }
    4351             : #endif
    4352             : 
    4353          12 : void Isolate::SetPrepareStackTraceCallback(PrepareStackTraceCallback callback) {
    4354          12 :   prepare_stack_trace_callback_ = callback;
    4355          12 : }
    4356             : 
    4357       15311 : bool Isolate::HasPrepareStackTraceCallback() const {
    4358       15311 :   return prepare_stack_trace_callback_ != nullptr;
    4359             : }
    4360             : 
    4361          13 : void Isolate::SetAtomicsWaitCallback(v8::Isolate::AtomicsWaitCallback callback,
    4362             :                                      void* data) {
    4363          13 :   atomics_wait_callback_ = callback;
    4364          13 :   atomics_wait_callback_data_ = data;
    4365          13 : }
    4366             : 
    4367        1838 : void Isolate::RunAtomicsWaitCallback(v8::Isolate::AtomicsWaitEvent event,
    4368             :                                      Handle<JSArrayBuffer> array_buffer,
    4369             :                                      size_t offset_in_bytes, int64_t value,
    4370             :                                      double timeout_in_ms,
    4371             :                                      AtomicsWaitWakeHandle* stop_handle) {
    4372             :   DCHECK(array_buffer->is_shared());
    4373        1838 :   if (atomics_wait_callback_ == nullptr) return;
    4374             :   HandleScope handle_scope(this);
    4375         169 :   atomics_wait_callback_(
    4376             :       event, v8::Utils::ToLocalShared(array_buffer), offset_in_bytes, value,
    4377             :       timeout_in_ms,
    4378             :       reinterpret_cast<v8::Isolate::AtomicsWaitWakeHandle*>(stop_handle),
    4379         169 :       atomics_wait_callback_data_);
    4380             : }
    4381             : 
    4382         119 : void Isolate::SetPromiseHook(PromiseHook hook) {
    4383         119 :   promise_hook_ = hook;
    4384         119 :   PromiseHookStateUpdated();
    4385         119 : }
    4386             : 
    4387       99547 : void Isolate::RunPromiseHook(PromiseHookType type, Handle<JSPromise> promise,
    4388             :                              Handle<Object> parent) {
    4389       99547 :   RunPromiseHookForAsyncEventDelegate(type, promise);
    4390       99547 :   if (promise_hook_ == nullptr) return;
    4391             :   promise_hook_(type, v8::Utils::PromiseToLocal(promise),
    4392        1145 :                 v8::Utils::ToLocal(parent));
    4393             : }
    4394             : 
    4395       99547 : void Isolate::RunPromiseHookForAsyncEventDelegate(PromiseHookType type,
    4396             :                                                   Handle<JSPromise> promise) {
    4397       99547 :   if (!async_event_delegate_) return;
    4398       37191 :   if (type == PromiseHookType::kResolve) return;
    4399             : 
    4400       21848 :   if (type == PromiseHookType::kBefore) {
    4401        3655 :     if (!promise->async_task_id()) return;
    4402        6345 :     async_event_delegate_->AsyncEventOccurred(debug::kDebugWillHandle,
    4403        4230 :                                               promise->async_task_id(), false);
    4404       18193 :   } else if (type == PromiseHookType::kAfter) {
    4405        3650 :     if (!promise->async_task_id()) return;
    4406        6300 :     async_event_delegate_->AsyncEventOccurred(debug::kDebugDidHandle,
    4407        4200 :                                               promise->async_task_id(), false);
    4408             :   } else {
    4409             :     DCHECK(type == PromiseHookType::kInit);
    4410             :     debug::DebugAsyncActionType type = debug::kDebugPromiseThen;
    4411             :     bool last_frame_was_promise_builtin = false;
    4412       14543 :     JavaScriptFrameIterator it(this);
    4413       28701 :     while (!it.done()) {
    4414             :       std::vector<Handle<SharedFunctionInfo>> infos;
    4415       26526 :       it.frame()->GetFunctions(&infos);
    4416       54842 :       for (size_t i = 1; i <= infos.size(); ++i) {
    4417       53052 :         Handle<SharedFunctionInfo> info = infos[infos.size() - i];
    4418       26526 :         if (info->IsUserJavaScript()) {
    4419             :           // We should not report PromiseThen and PromiseCatch which is called
    4420             :           // indirectly, e.g. Promise.all calls Promise.then internally.
    4421       12368 :           if (last_frame_was_promise_builtin) {
    4422        1855 :             if (!promise->async_task_id()) {
    4423        3710 :               promise->set_async_task_id(++async_task_count_);
    4424             :             }
    4425        7420 :             async_event_delegate_->AsyncEventOccurred(
    4426        3710 :                 type, promise->async_task_id(), debug()->IsBlackboxed(info));
    4427             :           }
    4428             :           return;
    4429             :         }
    4430             :         last_frame_was_promise_builtin = false;
    4431       14158 :         if (info->HasBuiltinId()) {
    4432       14158 :           if (info->builtin_id() == Builtins::kPromisePrototypeThen) {
    4433             :             type = debug::kDebugPromiseThen;
    4434             :             last_frame_was_promise_builtin = true;
    4435       10808 :           } else if (info->builtin_id() == Builtins::kPromisePrototypeCatch) {
    4436             :             type = debug::kDebugPromiseCatch;
    4437             :             last_frame_was_promise_builtin = true;
    4438       10508 :           } else if (info->builtin_id() == Builtins::kPromisePrototypeFinally) {
    4439             :             type = debug::kDebugPromiseFinally;
    4440             :             last_frame_was_promise_builtin = true;
    4441             :           }
    4442             :         }
    4443             :       }
    4444       14158 :       it.Advance();
    4445             :     }
    4446             :   }
    4447             : }
    4448             : 
    4449        3692 : void Isolate::OnAsyncFunctionStateChanged(Handle<JSPromise> promise,
    4450             :                                           debug::DebugAsyncActionType event) {
    4451        3692 :   if (!async_event_delegate_) return;
    4452         440 :   if (!promise->async_task_id()) {
    4453         370 :     promise->set_async_task_id(++async_task_count_);
    4454             :   }
    4455        1320 :   async_event_delegate_->AsyncEventOccurred(event, promise->async_task_id(),
    4456         880 :                                             false);
    4457             : }
    4458             : 
    4459        1154 : void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
    4460        1154 :   promise_reject_callback_ = callback;
    4461        1154 : }
    4462             : 
    4463       15707 : void Isolate::ReportPromiseReject(Handle<JSPromise> promise,
    4464             :                                   Handle<Object> value,
    4465             :                                   v8::PromiseRejectEvent event) {
    4466       15707 :   if (promise_reject_callback_ == nullptr) return;
    4467         490 :   promise_reject_callback_(v8::PromiseRejectMessage(
    4468         490 :       v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value)));
    4469             : }
    4470             : 
    4471          60 : void Isolate::SetUseCounterCallback(v8::Isolate::UseCounterCallback callback) {
    4472             :   DCHECK(!use_counter_callback_);
    4473          60 :   use_counter_callback_ = callback;
    4474          60 : }
    4475             : 
    4476             : 
    4477     2341742 : void Isolate::CountUsage(v8::Isolate::UseCounterFeature feature) {
    4478             :   // The counter callback may cause the embedder to call into V8, which is not
    4479             :   // generally possible during GC.
    4480     2341742 :   if (heap_.gc_state() == Heap::NOT_IN_GC) {
    4481     2341742 :     if (use_counter_callback_) {
    4482             :       HandleScope handle_scope(this);
    4483         199 :       use_counter_callback_(reinterpret_cast<v8::Isolate*>(this), feature);
    4484             :     }
    4485             :   } else {
    4486           0 :     heap_.IncrementDeferredCount(feature);
    4487             :   }
    4488     2341742 : }
    4489             : 
    4490             : // static
    4491          55 : std::string Isolate::GetTurboCfgFileName(Isolate* isolate) {
    4492          55 :   if (FLAG_trace_turbo_cfg_file == nullptr) {
    4493           0 :     std::ostringstream os;
    4494           0 :     os << "turbo-" << base::OS::GetCurrentProcessId() << "-";
    4495           0 :     if (isolate != nullptr) {
    4496           0 :       os << isolate->id();
    4497             :     } else {
    4498           0 :       os << "any";
    4499             :     }
    4500           0 :     os << ".cfg";
    4501             :     return os.str();
    4502             :   } else {
    4503          55 :     return FLAG_trace_turbo_cfg_file;
    4504             :   }
    4505             : }
    4506             : 
    4507             : // Heap::detached_contexts tracks detached contexts as pairs
    4508             : // (number of GC since the context was detached, the context).
    4509         126 : void Isolate::AddDetachedContext(Handle<Context> context) {
    4510             :   HandleScope scope(this);
    4511             :   Handle<WeakArrayList> detached_contexts = factory()->detached_contexts();
    4512             :   detached_contexts = WeakArrayList::AddToEnd(
    4513         126 :       this, detached_contexts, MaybeObjectHandle(Smi::kZero, this));
    4514             :   detached_contexts = WeakArrayList::AddToEnd(this, detached_contexts,
    4515         126 :                                               MaybeObjectHandle::Weak(context));
    4516             :   heap()->set_detached_contexts(*detached_contexts);
    4517         126 : }
    4518             : 
    4519             : 
    4520       68846 : void Isolate::CheckDetachedContextsAfterGC() {
    4521             :   HandleScope scope(this);
    4522             :   Handle<WeakArrayList> detached_contexts = factory()->detached_contexts();
    4523             :   int length = detached_contexts->length();
    4524       68846 :   if (length == 0) return;
    4525             :   int new_length = 0;
    4526         655 :   for (int i = 0; i < length; i += 2) {
    4527             :     int mark_sweeps = detached_contexts->Get(i).ToSmi().value();
    4528             :     MaybeObject context = detached_contexts->Get(i + 1);
    4529             :     DCHECK(context->IsWeakOrCleared());
    4530         297 :     if (!context->IsCleared()) {
    4531         729 :       detached_contexts->Set(
    4532         243 :           new_length, MaybeObject::FromSmi(Smi::FromInt(mark_sweeps + 1)));
    4533         486 :       detached_contexts->Set(new_length + 1, context);
    4534         243 :       new_length += 2;
    4535             :     }
    4536             :   }
    4537             :   detached_contexts->set_length(new_length);
    4538         277 :   while (new_length < length) {
    4539         108 :     detached_contexts->Set(new_length, MaybeObject::FromSmi(Smi::zero()));
    4540         108 :     ++new_length;
    4541             :   }
    4542             : 
    4543          61 :   if (FLAG_trace_detached_contexts) {
    4544           0 :     PrintF("%d detached contexts are collected out of %d\n",
    4545           0 :            length - new_length, length);
    4546           0 :     for (int i = 0; i < new_length; i += 2) {
    4547             :       int mark_sweeps = detached_contexts->Get(i).ToSmi().value();
    4548             :       MaybeObject context = detached_contexts->Get(i + 1);
    4549             :       DCHECK(context->IsWeakOrCleared());
    4550           0 :       if (mark_sweeps > 3) {
    4551           0 :         PrintF("detached context %p\n survived %d GCs (leak?)\n",
    4552           0 :                reinterpret_cast<void*>(context.ptr()), mark_sweeps);
    4553             :       }
    4554             :     }
    4555             :   }
    4556             : }
    4557             : 
    4558           0 : double Isolate::LoadStartTimeMs() {
    4559           0 :   base::MutexGuard guard(&rail_mutex_);
    4560           0 :   return load_start_time_ms_;
    4561             : }
    4562             : 
    4563           0 : void Isolate::SetRAILMode(RAILMode rail_mode) {
    4564             :   RAILMode old_rail_mode = rail_mode_.load();
    4565           0 :   if (old_rail_mode != PERFORMANCE_LOAD && rail_mode == PERFORMANCE_LOAD) {
    4566           0 :     base::MutexGuard guard(&rail_mutex_);
    4567           0 :     load_start_time_ms_ = heap()->MonotonicallyIncreasingTimeInMs();
    4568             :   }
    4569             :   rail_mode_.store(rail_mode);
    4570           0 :   if (old_rail_mode == PERFORMANCE_LOAD && rail_mode != PERFORMANCE_LOAD) {
    4571             :     heap()->incremental_marking()->incremental_marking_job()->ScheduleTask(
    4572           0 :         heap());
    4573             :   }
    4574           0 :   if (FLAG_trace_rail) {
    4575           0 :     PrintIsolate(this, "RAIL mode: %s\n", RAILModeName(rail_mode));
    4576             :   }
    4577           0 : }
    4578             : 
    4579           0 : void Isolate::IsolateInBackgroundNotification() {
    4580           0 :   is_isolate_in_background_ = true;
    4581           0 :   heap()->ActivateMemoryReducerIfNeeded();
    4582           0 : }
    4583             : 
    4584           0 : void Isolate::IsolateInForegroundNotification() {
    4585           0 :   is_isolate_in_background_ = false;
    4586           0 : }
    4587             : 
    4588         104 : void Isolate::PrintWithTimestamp(const char* format, ...) {
    4589         104 :   base::OS::Print("[%d:%p] %8.0f ms: ", base::OS::GetCurrentProcessId(),
    4590         104 :                   static_cast<void*>(this), time_millis_since_init());
    4591             :   va_list arguments;
    4592         104 :   va_start(arguments, format);
    4593         104 :   base::OS::VPrint(format, arguments);
    4594         104 :   va_end(arguments);
    4595         104 : }
    4596             : 
    4597          10 : void Isolate::SetIdle(bool is_idle) {
    4598          10 :   if (!is_profiling()) return;
    4599             :   StateTag state = current_vm_state();
    4600             :   DCHECK(state == EXTERNAL || state == IDLE);
    4601          10 :   if (js_entry_sp() != kNullAddress) return;
    4602          10 :   if (is_idle) {
    4603             :     set_current_vm_state(IDLE);
    4604           5 :   } else if (state == IDLE) {
    4605             :     set_current_vm_state(EXTERNAL);
    4606             :   }
    4607             : }
    4608             : 
    4609             : #ifdef V8_INTL_SUPPORT
    4610       64958 : icu::UObject* Isolate::get_cached_icu_object(ICUObjectCacheType cache_type) {
    4611       64958 :   return icu_object_cache_[cache_type].get();
    4612             : }
    4613             : 
    4614         149 : void Isolate::set_icu_object_in_cache(ICUObjectCacheType cache_type,
    4615             :                                       std::shared_ptr<icu::UObject> obj) {
    4616             :   icu_object_cache_[cache_type] = obj;
    4617         149 : }
    4618             : 
    4619           0 : void Isolate::clear_cached_icu_object(ICUObjectCacheType cache_type) {
    4620             :   icu_object_cache_.erase(cache_type);
    4621           0 : }
    4622             : #endif  // V8_INTL_SUPPORT
    4623             : 
    4624     2580007 : bool StackLimitCheck::JsHasOverflowed(uintptr_t gap) const {
    4625     2580007 :   StackGuard* stack_guard = isolate_->stack_guard();
    4626             : #ifdef USE_SIMULATOR
    4627             :   // The simulator uses a separate JS stack.
    4628             :   Address jssp_address = Simulator::current(isolate_)->get_sp();
    4629             :   uintptr_t jssp = static_cast<uintptr_t>(jssp_address);
    4630             :   if (jssp - gap < stack_guard->real_jslimit()) return true;
    4631             : #endif  // USE_SIMULATOR
    4632     2580007 :   return GetCurrentStackPosition() - gap < stack_guard->real_climit();
    4633             : }
    4634             : 
    4635    20603103 : SaveContext::SaveContext(Isolate* isolate) : isolate_(isolate) {
    4636    20603103 :   if (!isolate->context().is_null()) {
    4637    20395964 :     context_ = Handle<Context>(isolate->context(), isolate);
    4638             :   }
    4639             : 
    4640    20603103 :   c_entry_fp_ = isolate->c_entry_fp(isolate->thread_local_top());
    4641    20603103 : }
    4642             : 
    4643    41206260 : SaveContext::~SaveContext() {
    4644    41206260 :   isolate_->set_context(context_.is_null() ? Context() : *context_);
    4645    20603130 : }
    4646             : 
    4647           0 : bool SaveContext::IsBelowFrame(StandardFrame* frame) {
    4648           0 :   return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp());
    4649             : }
    4650             : 
    4651      382005 : SaveAndSwitchContext::SaveAndSwitchContext(Isolate* isolate,
    4652             :                                            Context new_context)
    4653      382005 :     : SaveContext(isolate) {
    4654             :   isolate->set_context(new_context);
    4655      382005 : }
    4656             : 
    4657             : #ifdef DEBUG
    4658             : AssertNoContextChange::AssertNoContextChange(Isolate* isolate)
    4659             :     : isolate_(isolate), context_(isolate->context(), isolate) {}
    4660             : #endif  // DEBUG
    4661             : 
    4662       76634 : bool InterruptsScope::Intercept(StackGuard::InterruptFlag flag) {
    4663             :   InterruptsScope* last_postpone_scope = nullptr;
    4664      230258 :   for (InterruptsScope* current = this; current; current = current->prev_) {
    4665             :     // We only consider scopes related to passed flag.
    4666       77013 :     if (!(current->intercept_mask_ & flag)) continue;
    4667       76350 :     if (current->mode_ == kRunInterrupts) {
    4668             :       // If innermost scope is kRunInterrupts scope, prevent interrupt from
    4669             :       // being intercepted.
    4670             :       break;
    4671             :     } else {
    4672             :       DCHECK_EQ(current->mode_, kPostponeInterrupts);
    4673             :       last_postpone_scope = current;
    4674             :     }
    4675             :   }
    4676             :   // If there is no postpone scope for passed flag then we should not intercept.
    4677       76634 :   if (!last_postpone_scope) return false;
    4678       75911 :   last_postpone_scope->intercepted_flags_ |= flag;
    4679       75911 :   return true;
    4680             : }
    4681             : 
    4682             : #undef TRACE_ISOLATE
    4683             : 
    4684             : }  // namespace internal
    4685      122036 : }  // namespace v8

Generated by: LCOV version 1.10