LCOV - code coverage report
Current view: top level - src - isolate.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1547 1797 86.1 %
Date: 2019-01-20 Functions: 203 234 86.8 %

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

Generated by: LCOV version 1.10