LCOV - code coverage report
Current view: top level - src - isolate.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1548 1807 85.7 %
Date: 2019-02-19 Functions: 204 238 85.7 %

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

Generated by: LCOV version 1.10