LCOV - code coverage report
Current view: top level - src - isolate.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 1163 1375 84.6 %
Date: 2017-04-26 Functions: 146 177 82.5 %

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

Generated by: LCOV version 1.10