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