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