LCOV - code coverage report
Current view: top level - src - isolate.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1197 1404 85.3 %
Date: 2017-10-20 Functions: 153 184 83.2 %

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

Generated by: LCOV version 1.10