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