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/ast.h"
     13 #include "src/ast/scopeinfo.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/codegen.h"
     20 #include "src/compilation-cache.h"
     21 #include "src/compilation-statistics.h"
     22 #include "src/crankshaft/hydrogen.h"
     23 #include "src/debug/debug.h"
     24 #include "src/deoptimizer.h"
     25 #include "src/frames-inl.h"
     26 #include "src/ic/stub-cache.h"
     27 #include "src/interpreter/interpreter.h"
     28 #include "src/isolate-inl.h"
     29 #include "src/log.h"
     30 #include "src/messages.h"
     31 #include "src/profiler/cpu-profiler.h"
     32 #include "src/profiler/sampler.h"
     33 #include "src/prototype.h"
     34 #include "src/regexp/regexp-stack.h"
     35 #include "src/runtime-profiler.h"
     36 #include "src/simulator.h"
     37 #include "src/snapshot/serialize.h"
     38 #include "src/v8.h"
     39 #include "src/version.h"
     40 #include "src/vm-state-inl.h"
     41 
     42 
     43 namespace v8 {
     44 namespace internal {
     45 
     46 base::Atomic32 ThreadId::highest_thread_id_ = 0;
     47 
     48 int ThreadId::AllocateThreadId() {
     49   int new_id = base::NoBarrier_AtomicIncrement(&highest_thread_id_, 1);
     50   return new_id;
     51 }
     52 
     53 
     54 int ThreadId::GetCurrentThreadId() {
     55   int thread_id = base::Thread::GetThreadLocalInt(Isolate::thread_id_key_);
     56   if (thread_id == 0) {
     57     thread_id = AllocateThreadId();
     58     base::Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id);
     59   }
     60   return thread_id;
     61 }
     62 
     63 
     64 ThreadLocalTop::ThreadLocalTop() {
     65   InitializeInternal();
     66 }
     67 
     68 
     69 void ThreadLocalTop::InitializeInternal() {
     70   c_entry_fp_ = 0;
     71   c_function_ = 0;
     72   handler_ = 0;
     73 #ifdef USE_SIMULATOR
     74   simulator_ = NULL;
     75 #endif
     76   js_entry_sp_ = NULL;
     77   external_callback_scope_ = NULL;
     78   current_vm_state_ = EXTERNAL;
     79   try_catch_handler_ = NULL;
     80   context_ = NULL;
     81   thread_id_ = ThreadId::Invalid();
     82   external_caught_exception_ = false;
     83   failed_access_check_callback_ = NULL;
     84   save_context_ = NULL;
     85   promise_on_stack_ = NULL;
     86 
     87   // These members are re-initialized later after deserialization
     88   // is complete.
     89   pending_exception_ = NULL;
     90   rethrowing_message_ = false;
     91   pending_message_obj_ = NULL;
     92   scheduled_exception_ = NULL;
     93 }
     94 
     95 
     96 void ThreadLocalTop::Initialize() {
     97   InitializeInternal();
     98 #ifdef USE_SIMULATOR
     99   simulator_ = Simulator::current(isolate_);
    100 #endif
    101   thread_id_ = ThreadId::Current();
    102 }
    103 
    104 
    105 void ThreadLocalTop::Free() {
    106   // Match unmatched PopPromise calls.
    107   while (promise_on_stack_) isolate_->PopPromise();
    108 }
    109 
    110 
    111 base::Thread::LocalStorageKey Isolate::isolate_key_;
    112 base::Thread::LocalStorageKey Isolate::thread_id_key_;
    113 base::Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
    114 base::LazyMutex Isolate::thread_data_table_mutex_ = LAZY_MUTEX_INITIALIZER;
    115 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
    116 base::Atomic32 Isolate::isolate_counter_ = 0;
    117 #if DEBUG
    118 base::Atomic32 Isolate::isolate_key_created_ = 0;
    119 #endif
    120 
    121 Isolate::PerIsolateThreadData*
    122     Isolate::FindOrAllocatePerThreadDataForThisThread() {
    123   ThreadId thread_id = ThreadId::Current();
    124   PerIsolateThreadData* per_thread = NULL;
    125   {
    126     base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
    127     per_thread = thread_data_table_->Lookup(this, thread_id);
    128     if (per_thread == NULL) {
    129       per_thread = new PerIsolateThreadData(this, thread_id);
    130       thread_data_table_->Insert(per_thread);
    131     }
    132     DCHECK(thread_data_table_->Lookup(this, thread_id) == per_thread);
    133   }
    134   return per_thread;
    135 }
    136 
    137 
    138 void Isolate::DiscardPerThreadDataForThisThread() {
    139   int thread_id_int = base::Thread::GetThreadLocalInt(Isolate::thread_id_key_);
    140   if (thread_id_int) {
    141     ThreadId thread_id = ThreadId(thread_id_int);
    142     DCHECK(!thread_manager_->mutex_owner_.Equals(thread_id));
    143     base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
    144     PerIsolateThreadData* per_thread =
    145         thread_data_table_->Lookup(this, thread_id);
    146     if (per_thread) {
    147       DCHECK(!per_thread->thread_state_);
    148       thread_data_table_->Remove(per_thread);
    149     }
    150   }
    151 }
    152 
    153 
    154 Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() {
    155   ThreadId thread_id = ThreadId::Current();
    156   return FindPerThreadDataForThread(thread_id);
    157 }
    158 
    159 
    160 Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThread(
    161     ThreadId thread_id) {
    162   PerIsolateThreadData* per_thread = NULL;
    163   {
    164     base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
    165     per_thread = thread_data_table_->Lookup(this, thread_id);
    166   }
    167   return per_thread;
    168 }
    169 
    170 
    171 void Isolate::InitializeOncePerProcess() {
    172   base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
    173   CHECK(thread_data_table_ == NULL);
    174   isolate_key_ = base::Thread::CreateThreadLocalKey();
    175 #if DEBUG
    176   base::NoBarrier_Store(&isolate_key_created_, 1);
    177 #endif
    178   thread_id_key_ = base::Thread::CreateThreadLocalKey();
    179   per_isolate_thread_data_key_ = base::Thread::CreateThreadLocalKey();
    180   thread_data_table_ = new Isolate::ThreadDataTable();
    181 }
    182 
    183 
    184 Address Isolate::get_address_from_id(Isolate::AddressId id) {
    185   return isolate_addresses_[id];
    186 }
    187 
    188 
    189 char* Isolate::Iterate(ObjectVisitor* v, char* thread_storage) {
    190   ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage);
    191   Iterate(v, thread);
    192   return thread_storage + sizeof(ThreadLocalTop);
    193 }
    194 
    195 
    196 void Isolate::IterateThread(ThreadVisitor* v, char* t) {
    197   ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t);
    198   v->VisitThread(this, thread);
    199 }
    200 
    201 
    202 void Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
    203   // Visit the roots from the top for a given thread.
    204   v->VisitPointer(&thread->pending_exception_);
    205   v->VisitPointer(&(thread->pending_message_obj_));
    206   v->VisitPointer(bit_cast<Object**>(&(thread->context_)));
    207   v->VisitPointer(&thread->scheduled_exception_);
    208 
    209   for (v8::TryCatch* block = thread->try_catch_handler();
    210        block != NULL;
    211        block = block->next_) {
    212     v->VisitPointer(bit_cast<Object**>(&(block->exception_)));
    213     v->VisitPointer(bit_cast<Object**>(&(block->message_obj_)));
    214   }
    215 
    216   // Iterate over pointers on native execution stack.
    217   for (StackFrameIterator it(this, thread); !it.done(); it.Advance()) {
    218     it.frame()->Iterate(v);
    219   }
    220 }
    221 
    222 
    223 void Isolate::Iterate(ObjectVisitor* v) {
    224   ThreadLocalTop* current_t = thread_local_top();
    225   Iterate(v, current_t);
    226 }
    227 
    228 
    229 void Isolate::IterateDeferredHandles(ObjectVisitor* visitor) {
    230   for (DeferredHandles* deferred = deferred_handles_head_;
    231        deferred != NULL;
    232        deferred = deferred->next_) {
    233     deferred->Iterate(visitor);
    234   }
    235 }
    236 
    237 
    238 #ifdef DEBUG
    239 bool Isolate::IsDeferredHandle(Object** handle) {
    240   // Each DeferredHandles instance keeps the handles to one job in the
    241   // concurrent recompilation queue, containing a list of blocks.  Each block
    242   // contains kHandleBlockSize handles except for the first block, which may
    243   // not be fully filled.
    244   // We iterate through all the blocks to see whether the argument handle
    245   // belongs to one of the blocks.  If so, it is deferred.
    246   for (DeferredHandles* deferred = deferred_handles_head_;
    247        deferred != NULL;
    248        deferred = deferred->next_) {
    249     List<Object**>* blocks = &deferred->blocks_;
    250     for (int i = 0; i < blocks->length(); i++) {
    251       Object** block_limit = (i == 0) ? deferred->first_block_limit_
    252                                       : blocks->at(i) + kHandleBlockSize;
    253       if (blocks->at(i) <= handle && handle < block_limit) return true;
    254     }
    255   }
    256   return false;
    257 }
    258 #endif  // DEBUG
    259 
    260 
    261 void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) {
    262   thread_local_top()->set_try_catch_handler(that);
    263 }
    264 
    265 
    266 void Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) {
    267   DCHECK(thread_local_top()->try_catch_handler() == that);
    268   thread_local_top()->set_try_catch_handler(that->next_);
    269 }
    270 
    271 
    272 Handle<String> Isolate::StackTraceString() {
    273   if (stack_trace_nesting_level_ == 0) {
    274     stack_trace_nesting_level_++;
    275     HeapStringAllocator allocator;
    276     StringStream::ClearMentionedObjectCache(this);
    277     StringStream accumulator(&allocator);
    278     incomplete_message_ = &accumulator;
    279     PrintStack(&accumulator);
    280     Handle<String> stack_trace = accumulator.ToString(this);
    281     incomplete_message_ = NULL;
    282     stack_trace_nesting_level_ = 0;
    283     return stack_trace;
    284   } else if (stack_trace_nesting_level_ == 1) {
    285     stack_trace_nesting_level_++;
    286     base::OS::PrintError(
    287       "\n\nAttempt to print stack while printing stack (double fault)\n");
    288     base::OS::PrintError(
    289       "If you are lucky you may find a partial stack dump on stdout.\n\n");
    290     incomplete_message_->OutputToStdOut();
    291     return factory()->empty_string();
    292   } else {
    293     base::OS::Abort();
    294     // Unreachable
    295     return factory()->empty_string();
    296   }
    297 }
    298 
    299 
    300 void Isolate::PushStackTraceAndDie(unsigned int magic, void* ptr1, void* ptr2,
    301                                    unsigned int magic2) {
    302   const int kMaxStackTraceSize = 32 * KB;
    303   Handle<String> trace = StackTraceString();
    304   uint8_t buffer[kMaxStackTraceSize];
    305   int length = Min(kMaxStackTraceSize - 1, trace->length());
    306   String::WriteToFlat(*trace, buffer, 0, length);
    307   buffer[length] = '\0';
    308   // TODO(dcarney): convert buffer to utf8?
    309   base::OS::PrintError("Stacktrace (%x-%x) %p %p: %s\n", magic, magic2, ptr1,
    310                        ptr2, reinterpret_cast<char*>(buffer));
    311   base::OS::Abort();
    312 }
    313 
    314 
    315 // Determines whether the given stack frame should be displayed in
    316 // a stack trace.  The caller is the error constructor that asked
    317 // for the stack trace to be collected.  The first time a construct
    318 // call to this function is encountered it is skipped.  The seen_caller
    319 // in/out parameter is used to remember if the caller has been seen
    320 // yet.
    321 static bool IsVisibleInStackTrace(JSFunction* fun,
    322                                   Object* caller,
    323                                   Object* receiver,
    324                                   bool* seen_caller) {
    325   if ((fun == caller) && !(*seen_caller)) {
    326     *seen_caller = true;
    327     return false;
    328   }
    329   // Skip all frames until we've seen the caller.
    330   if (!(*seen_caller)) return false;
    331   // Functions defined in native scripts are not visible unless directly
    332   // exposed, in which case the native flag is set.
    333   // The --builtins-in-stack-traces command line flag allows including
    334   // internal call sites in the stack trace for debugging purposes.
    335   if (!FLAG_builtins_in_stack_traces && fun->shared()->IsBuiltin()) {
    336     return fun->shared()->native();
    337   }
    338   return true;
    339 }
    340 
    341 
    342 Handle<Object> Isolate::CaptureSimpleStackTrace(Handle<JSObject> error_object,
    343                                                 Handle<Object> caller) {
    344   // Get stack trace limit.
    345   Handle<JSObject> error = error_function();
    346   Handle<String> stackTraceLimit =
    347       factory()->InternalizeUtf8String("stackTraceLimit");
    348   DCHECK(!stackTraceLimit.is_null());
    349   Handle<Object> stack_trace_limit =
    350       JSReceiver::GetDataProperty(error, stackTraceLimit);
    351   if (!stack_trace_limit->IsNumber()) return factory()->undefined_value();
    352   int limit = FastD2IChecked(stack_trace_limit->Number());
    353   limit = Max(limit, 0);  // Ensure that limit is not negative.
    354 
    355   int initial_size = Min(limit, 10);
    356   Handle<FixedArray> elements =
    357       factory()->NewFixedArrayWithHoles(initial_size * 4 + 1);
    358 
    359   // If the caller parameter is a function we skip frames until we're
    360   // under it before starting to collect.
    361   bool seen_caller = !caller->IsJSFunction();
    362   // First element is reserved to store the number of sloppy frames.
    363   int cursor = 1;
    364   int frames_seen = 0;
    365   int sloppy_frames = 0;
    366   bool encountered_strict_function = false;
    367   for (JavaScriptFrameIterator iter(this);
    368        !iter.done() && frames_seen < limit;
    369        iter.Advance()) {
    370     JavaScriptFrame* frame = iter.frame();
    371     // Set initial size to the maximum inlining level + 1 for the outermost
    372     // function.
    373     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
    374     frame->Summarize(&frames);
    375     for (int i = frames.length() - 1; i >= 0; i--) {
    376       Handle<JSFunction> fun = frames[i].function();
    377       Handle<Object> recv = frames[i].receiver();
    378       // Filter out internal frames that we do not want to show.
    379       if (!IsVisibleInStackTrace(*fun, *caller, *recv, &seen_caller)) continue;
    380       // Filter out frames from other security contexts.
    381       if (!this->context()->HasSameSecurityTokenAs(fun->context())) continue;
    382       if (cursor + 4 > elements->length()) {
    383         int new_capacity = JSObject::NewElementsCapacity(elements->length());
    384         Handle<FixedArray> new_elements =
    385             factory()->NewFixedArrayWithHoles(new_capacity);
    386         for (int i = 0; i < cursor; i++) {
    387           new_elements->set(i, elements->get(i));
    388         }
    389         elements = new_elements;
    390       }
    391       DCHECK(cursor + 4 <= elements->length());
    392 
    393       Handle<Code> code = frames[i].code();
    394       Handle<Smi> offset(Smi::FromInt(frames[i].offset()), this);
    395       // The stack trace API should not expose receivers and function
    396       // objects on frames deeper than the top-most one with a strict
    397       // mode function.  The number of sloppy frames is stored as
    398       // first element in the result array.
    399       if (!encountered_strict_function) {
    400         if (is_strict(fun->shared()->language_mode())) {
    401           encountered_strict_function = true;
    402         } else {
    403           sloppy_frames++;
    404         }
    405       }
    406       elements->set(cursor++, *recv);
    407       elements->set(cursor++, *fun);
    408       elements->set(cursor++, *code);
    409       elements->set(cursor++, *offset);
    410       frames_seen++;
    411     }
    412   }
    413   elements->set(0, Smi::FromInt(sloppy_frames));
    414   elements->Shrink(cursor);
    415   Handle<JSArray> result = factory()->NewJSArrayWithElements(elements);
    416   result->set_length(Smi::FromInt(cursor));
    417   // TODO(yangguo): Queue this structured stack trace for preprocessing on GC.
    418   return result;
    419 }
    420 
    421 
    422 MaybeHandle<JSObject> Isolate::CaptureAndSetDetailedStackTrace(
    423     Handle<JSObject> error_object) {
    424   if (capture_stack_trace_for_uncaught_exceptions_) {
    425     // Capture stack trace for a detailed exception message.
    426     Handle<Name> key = factory()->detailed_stack_trace_symbol();
    427     Handle<JSArray> stack_trace = CaptureCurrentStackTrace(
    428         stack_trace_for_uncaught_exceptions_frame_limit_,
    429         stack_trace_for_uncaught_exceptions_options_);
    430     RETURN_ON_EXCEPTION(
    431         this, JSObject::SetProperty(error_object, key, stack_trace, STRICT),
    432         JSObject);
    433   }
    434   return error_object;
    435 }
    436 
    437 
    438 MaybeHandle<JSObject> Isolate::CaptureAndSetSimpleStackTrace(
    439     Handle<JSObject> error_object, Handle<Object> caller) {
    440   // Capture stack trace for simple stack trace string formatting.
    441   Handle<Name> key = factory()->stack_trace_symbol();
    442   Handle<Object> stack_trace = CaptureSimpleStackTrace(error_object, caller);
    443   RETURN_ON_EXCEPTION(
    444       this, JSObject::SetProperty(error_object, key, stack_trace, STRICT),
    445       JSObject);
    446   return error_object;
    447 }
    448 
    449 
    450 Handle<JSArray> Isolate::GetDetailedStackTrace(Handle<JSObject> error_object) {
    451   Handle<Name> key_detailed = factory()->detailed_stack_trace_symbol();
    452   Handle<Object> stack_trace =
    453       JSReceiver::GetDataProperty(error_object, key_detailed);
    454   if (stack_trace->IsJSArray()) return Handle<JSArray>::cast(stack_trace);
    455 
    456   if (!capture_stack_trace_for_uncaught_exceptions_) return Handle<JSArray>();
    457 
    458   // Try to get details from simple stack trace.
    459   Handle<JSArray> detailed_stack_trace =
    460       GetDetailedFromSimpleStackTrace(error_object);
    461   if (!detailed_stack_trace.is_null()) {
    462     // Save the detailed stack since the simple one might be withdrawn later.
    463     JSObject::SetProperty(error_object, key_detailed, detailed_stack_trace,
    464                           STRICT).Assert();
    465   }
    466   return detailed_stack_trace;
    467 }
    468 
    469 
    470 class CaptureStackTraceHelper {
    471  public:
    472   CaptureStackTraceHelper(Isolate* isolate,
    473                           StackTrace::StackTraceOptions options)
    474       : isolate_(isolate) {
    475     if (options & StackTrace::kColumnOffset) {
    476       column_key_ =
    477           factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("column"));
    478     }
    479     if (options & StackTrace::kLineNumber) {
    480       line_key_ =
    481           factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("lineNumber"));
    482     }
    483     if (options & StackTrace::kScriptId) {
    484       script_id_key_ =
    485           factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptId"));
    486     }
    487     if (options & StackTrace::kScriptName) {
    488       script_name_key_ =
    489           factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("scriptName"));
    490     }
    491     if (options & StackTrace::kScriptNameOrSourceURL) {
    492       script_name_or_source_url_key_ = factory()->InternalizeOneByteString(
    493           STATIC_CHAR_VECTOR("scriptNameOrSourceURL"));
    494     }
    495     if (options & StackTrace::kFunctionName) {
    496       function_key_ = factory()->InternalizeOneByteString(
    497           STATIC_CHAR_VECTOR("functionName"));
    498     }
    499     if (options & StackTrace::kIsEval) {
    500       eval_key_ =
    501           factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("isEval"));
    502     }
    503     if (options & StackTrace::kIsConstructor) {
    504       constructor_key_ = factory()->InternalizeOneByteString(
    505           STATIC_CHAR_VECTOR("isConstructor"));
    506     }
    507   }
    508 
    509   Handle<JSObject> NewStackFrameObject(Handle<JSFunction> fun, int position,
    510                                        bool is_constructor) {
    511     Handle<JSObject> stack_frame =
    512         factory()->NewJSObject(isolate_->object_function());
    513 
    514     Handle<Script> script(Script::cast(fun->shared()->script()));
    515 
    516     if (!line_key_.is_null()) {
    517       int script_line_offset = script->line_offset();
    518       int line_number = Script::GetLineNumber(script, position);
    519       // line_number is already shifted by the script_line_offset.
    520       int relative_line_number = line_number - script_line_offset;
    521       if (!column_key_.is_null() && relative_line_number >= 0) {
    522         Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
    523         int start = (relative_line_number == 0) ? 0 :
    524             Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
    525         int column_offset = position - start;
    526         if (relative_line_number == 0) {
    527           // For the case where the code is on the same line as the script
    528           // tag.
    529           column_offset += script->column_offset();
    530         }
    531         JSObject::AddProperty(stack_frame, column_key_,
    532                               handle(Smi::FromInt(column_offset + 1), isolate_),
    533                               NONE);
    534       }
    535       JSObject::AddProperty(stack_frame, line_key_,
    536                             handle(Smi::FromInt(line_number + 1), isolate_),
    537                             NONE);
    538     }
    539 
    540     if (!script_id_key_.is_null()) {
    541       JSObject::AddProperty(stack_frame, script_id_key_,
    542                             handle(Smi::FromInt(script->id()), isolate_), NONE);
    543     }
    544 
    545     if (!script_name_key_.is_null()) {
    546       JSObject::AddProperty(stack_frame, script_name_key_,
    547                             handle(script->name(), isolate_), NONE);
    548     }
    549 
    550     if (!script_name_or_source_url_key_.is_null()) {
    551       Handle<Object> result = Script::GetNameOrSourceURL(script);
    552       JSObject::AddProperty(stack_frame, script_name_or_source_url_key_, result,
    553                             NONE);
    554     }
    555 
    556     if (!function_key_.is_null()) {
    557       Handle<Object> fun_name = JSFunction::GetDebugName(fun);
    558       JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
    559     }
    560 
    561     if (!eval_key_.is_null()) {
    562       Handle<Object> is_eval = factory()->ToBoolean(
    563           script->compilation_type() == Script::COMPILATION_TYPE_EVAL);
    564       JSObject::AddProperty(stack_frame, eval_key_, is_eval, NONE);
    565     }
    566 
    567     if (!constructor_key_.is_null()) {
    568       Handle<Object> is_constructor_obj = factory()->ToBoolean(is_constructor);
    569       JSObject::AddProperty(stack_frame, constructor_key_, is_constructor_obj,
    570                             NONE);
    571     }
    572 
    573     return stack_frame;
    574   }
    575 
    576  private:
    577   inline Factory* factory() { return isolate_->factory(); }
    578 
    579   Isolate* isolate_;
    580   Handle<String> column_key_;
    581   Handle<String> line_key_;
    582   Handle<String> script_id_key_;
    583   Handle<String> script_name_key_;
    584   Handle<String> script_name_or_source_url_key_;
    585   Handle<String> function_key_;
    586   Handle<String> eval_key_;
    587   Handle<String> constructor_key_;
    588 };
    589 
    590 
    591 int PositionFromStackTrace(Handle<FixedArray> elements, int index) {
    592   DisallowHeapAllocation no_gc;
    593   Object* maybe_code = elements->get(index + 2);
    594   if (maybe_code->IsSmi()) {
    595     return Smi::cast(maybe_code)->value();
    596   } else {
    597     Code* code = Code::cast(maybe_code);
    598     Address pc = code->address() + Smi::cast(elements->get(index + 3))->value();
    599     return code->SourcePosition(pc);
    600   }
    601 }
    602 
    603 
    604 Handle<JSArray> Isolate::GetDetailedFromSimpleStackTrace(
    605     Handle<JSObject> error_object) {
    606   Handle<Name> key = factory()->stack_trace_symbol();
    607   Handle<Object> property = JSReceiver::GetDataProperty(error_object, key);
    608   if (!property->IsJSArray()) return Handle<JSArray>();
    609   Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property);
    610 
    611   CaptureStackTraceHelper helper(this,
    612                                  stack_trace_for_uncaught_exceptions_options_);
    613 
    614   int frames_seen = 0;
    615   Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements()));
    616   int elements_limit = Smi::cast(simple_stack_trace->length())->value();
    617 
    618   int frame_limit = stack_trace_for_uncaught_exceptions_frame_limit_;
    619   if (frame_limit < 0) frame_limit = (elements_limit - 1) / 4;
    620 
    621   Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
    622   for (int i = 1; i < elements_limit && frames_seen < frame_limit; i += 4) {
    623     Handle<Object> recv = handle(elements->get(i), this);
    624     Handle<JSFunction> fun =
    625         handle(JSFunction::cast(elements->get(i + 1)), this);
    626     bool is_constructor =
    627         recv->IsJSObject() &&
    628         Handle<JSObject>::cast(recv)->map()->GetConstructor() == *fun;
    629     int position = PositionFromStackTrace(elements, i);
    630 
    631     Handle<JSObject> stack_frame =
    632         helper.NewStackFrameObject(fun, position, is_constructor);
    633 
    634     FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
    635     frames_seen++;
    636   }
    637 
    638   stack_trace->set_length(Smi::FromInt(frames_seen));
    639   return stack_trace;
    640 }
    641 
    642 
    643 Handle<JSArray> Isolate::CaptureCurrentStackTrace(
    644     int frame_limit, StackTrace::StackTraceOptions options) {
    645   CaptureStackTraceHelper helper(this, options);
    646 
    647   // Ensure no negative values.
    648   int limit = Max(frame_limit, 0);
    649   Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
    650 
    651   StackTraceFrameIterator it(this);
    652   int frames_seen = 0;
    653   while (!it.done() && (frames_seen < limit)) {
    654     JavaScriptFrame* frame = it.frame();
    655     // Set initial size to the maximum inlining level + 1 for the outermost
    656     // function.
    657     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
    658     frame->Summarize(&frames);
    659     for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
    660       Handle<JSFunction> fun = frames[i].function();
    661       // Filter frames from other security contexts.
    662       if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) &&
    663           !this->context()->HasSameSecurityTokenAs(fun->context())) continue;
    664       int position = frames[i].code()->SourcePosition(frames[i].pc());
    665       Handle<JSObject> stack_frame =
    666           helper.NewStackFrameObject(fun, position, frames[i].is_constructor());
    667 
    668       FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
    669       frames_seen++;
    670     }
    671     it.Advance();
    672   }
    673 
    674   stack_trace->set_length(Smi::FromInt(frames_seen));
    675   return stack_trace;
    676 }
    677 
    678 
    679 void Isolate::PrintStack(FILE* out, PrintStackMode mode) {
    680   if (stack_trace_nesting_level_ == 0) {
    681     stack_trace_nesting_level_++;
    682     StringStream::ClearMentionedObjectCache(this);
    683     HeapStringAllocator allocator;
    684     StringStream accumulator(&allocator);
    685     incomplete_message_ = &accumulator;
    686     PrintStack(&accumulator, mode);
    687     accumulator.OutputToFile(out);
    688     InitializeLoggingAndCounters();
    689     accumulator.Log(this);
    690     incomplete_message_ = NULL;
    691     stack_trace_nesting_level_ = 0;
    692   } else if (stack_trace_nesting_level_ == 1) {
    693     stack_trace_nesting_level_++;
    694     base::OS::PrintError(
    695       "\n\nAttempt to print stack while printing stack (double fault)\n");
    696     base::OS::PrintError(
    697       "If you are lucky you may find a partial stack dump on stdout.\n\n");
    698     incomplete_message_->OutputToFile(out);
    699   }
    700 }
    701 
    702 
    703 static void PrintFrames(Isolate* isolate,
    704                         StringStream* accumulator,
    705                         StackFrame::PrintMode mode) {
    706   StackFrameIterator it(isolate);
    707   for (int i = 0; !it.done(); it.Advance()) {
    708     it.frame()->Print(accumulator, mode, i++);
    709   }
    710 }
    711 
    712 
    713 void Isolate::PrintStack(StringStream* accumulator, PrintStackMode mode) {
    714   // The MentionedObjectCache is not GC-proof at the moment.
    715   DisallowHeapAllocation no_gc;
    716   DCHECK(accumulator->IsMentionedObjectCacheClear(this));
    717 
    718   // Avoid printing anything if there are no frames.
    719   if (c_entry_fp(thread_local_top()) == 0) return;
    720 
    721   accumulator->Add(
    722       "\n==== JS stack trace =========================================\n\n");
    723   PrintFrames(this, accumulator, StackFrame::OVERVIEW);
    724   if (mode == kPrintStackVerbose) {
    725     accumulator->Add(
    726         "\n==== Details ================================================\n\n");
    727     PrintFrames(this, accumulator, StackFrame::DETAILS);
    728     accumulator->PrintMentionedObjectCache(this);
    729   }
    730   accumulator->Add("=====================\n\n");
    731 }
    732 
    733 
    734 void Isolate::SetFailedAccessCheckCallback(
    735     v8::FailedAccessCheckCallback callback) {
    736   thread_local_top()->failed_access_check_callback_ = callback;
    737 }
    738 
    739 
    740 static inline AccessCheckInfo* GetAccessCheckInfo(Isolate* isolate,
    741                                                   Handle<JSObject> receiver) {
    742   Object* maybe_constructor = receiver->map()->GetConstructor();
    743   if (!maybe_constructor->IsJSFunction()) return NULL;
    744   JSFunction* constructor = JSFunction::cast(maybe_constructor);
    745   if (!constructor->shared()->IsApiFunction()) return NULL;
    746 
    747   Object* data_obj =
    748      constructor->shared()->get_api_func_data()->access_check_info();
    749   if (data_obj == isolate->heap()->undefined_value()) return NULL;
    750 
    751   return AccessCheckInfo::cast(data_obj);
    752 }
    753 
    754 
    755 void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver) {
    756   if (!thread_local_top()->failed_access_check_callback_) {
    757     return ScheduleThrow(*factory()->NewTypeError(MessageTemplate::kNoAccess));
    758   }
    759 
    760   DCHECK(receiver->IsAccessCheckNeeded());
    761   DCHECK(context());
    762 
    763   // Get the data object from access check info.
    764   HandleScope scope(this);
    765   Handle<Object> data;
    766   { DisallowHeapAllocation no_gc;
    767     AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
    768     if (!access_check_info) {
    769       AllowHeapAllocation doesnt_matter_anymore;
    770       return ScheduleThrow(
    771           *factory()->NewTypeError(MessageTemplate::kNoAccess));
    772     }
    773     data = handle(access_check_info->data(), this);
    774   }
    775 
    776   // Leaving JavaScript.
    777   VMState<EXTERNAL> state(this);
    778   thread_local_top()->failed_access_check_callback_(
    779       v8::Utils::ToLocal(receiver), v8::ACCESS_HAS, v8::Utils::ToLocal(data));
    780 }
    781 
    782 
    783 bool Isolate::IsInternallyUsedPropertyName(Handle<Object> name) {
    784   if (name->IsSymbol()) {
    785     return Handle<Symbol>::cast(name)->is_private();
    786   }
    787   return name.is_identical_to(factory()->hidden_string());
    788 }
    789 
    790 
    791 bool Isolate::MayAccess(Handle<Context> accessing_context,
    792                         Handle<JSObject> receiver) {
    793   DCHECK(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
    794 
    795   // Check for compatibility between the security tokens in the
    796   // current lexical context and the accessed object.
    797 
    798   // During bootstrapping, callback functions are not enabled yet.
    799   if (bootstrapper()->IsActive()) return true;
    800   {
    801     DisallowHeapAllocation no_gc;
    802 
    803     if (receiver->IsJSGlobalProxy()) {
    804       Object* receiver_context =
    805           JSGlobalProxy::cast(*receiver)->native_context();
    806       if (!receiver_context->IsContext()) return false;
    807 
    808       // Get the native context of current top context.
    809       // avoid using Isolate::native_context() because it uses Handle.
    810       Context* native_context =
    811           accessing_context->global_object()->native_context();
    812       if (receiver_context == native_context) return true;
    813 
    814       if (Context::cast(receiver_context)->security_token() ==
    815           native_context->security_token())
    816         return true;
    817     }
    818   }
    819 
    820   HandleScope scope(this);
    821   Handle<Object> data;
    822   v8::AccessCheckCallback callback = nullptr;
    823   v8::NamedSecurityCallback named_callback = nullptr;
    824   { DisallowHeapAllocation no_gc;
    825     AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
    826     if (!access_check_info) return false;
    827     Object* fun_obj = access_check_info->callback();
    828     callback = v8::ToCData<v8::AccessCheckCallback>(fun_obj);
    829     if (!callback) {
    830       fun_obj = access_check_info->named_callback();
    831       named_callback = v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
    832       if (!named_callback) return false;
    833       data = handle(access_check_info->data(), this);
    834     }
    835   }
    836 
    837   LOG(this, ApiSecurityCheck());
    838 
    839   {
    840     // Leaving JavaScript.
    841     VMState<EXTERNAL> state(this);
    842     if (callback) {
    843       return callback(v8::Utils::ToLocal(accessing_context),
    844                       v8::Utils::ToLocal(receiver));
    845     }
    846     Handle<Object> key = factory()->undefined_value();
    847     return named_callback(v8::Utils::ToLocal(receiver), v8::Utils::ToLocal(key),
    848                           v8::ACCESS_HAS, v8::Utils::ToLocal(data));
    849   }
    850 }
    851 
    852 
    853 const char* const Isolate::kStackOverflowMessage =
    854   "Uncaught RangeError: Maximum call stack size exceeded";
    855 
    856 
    857 Object* Isolate::StackOverflow() {
    858   HandleScope scope(this);
    859   // At this point we cannot create an Error object using its javascript
    860   // constructor.  Instead, we copy the pre-constructed boilerplate and
    861   // attach the stack trace as a hidden property.
    862   Handle<Object> exception;
    863   if (bootstrapper()->IsActive()) {
    864     // There is no boilerplate to use during bootstrapping.
    865     exception = factory()->NewStringFromAsciiChecked(
    866         MessageTemplate::TemplateString(MessageTemplate::kStackOverflow));
    867   } else {
    868     Handle<JSObject> boilerplate = stack_overflow_boilerplate();
    869     Handle<JSObject> copy = factory()->CopyJSObject(boilerplate);
    870     CaptureAndSetSimpleStackTrace(copy, factory()->undefined_value());
    871     exception = copy;
    872   }
    873   Throw(*exception, nullptr);
    874 
    875 #ifdef VERIFY_HEAP
    876   if (FLAG_verify_heap && FLAG_stress_compaction) {
    877     heap()->CollectAllAvailableGarbage("trigger compaction");
    878   }
    879 #endif  // VERIFY_HEAP
    880 
    881   return heap()->exception();
    882 }
    883 
    884 
    885 Object* Isolate::TerminateExecution() {
    886   return Throw(heap_.termination_exception(), nullptr);
    887 }
    888 
    889 
    890 void Isolate::CancelTerminateExecution() {
    891   if (try_catch_handler()) {
    892     try_catch_handler()->has_terminated_ = false;
    893   }
    894   if (has_pending_exception() &&
    895       pending_exception() == heap_.termination_exception()) {
    896     thread_local_top()->external_caught_exception_ = false;
    897     clear_pending_exception();
    898   }
    899   if (has_scheduled_exception() &&
    900       scheduled_exception() == heap_.termination_exception()) {
    901     thread_local_top()->external_caught_exception_ = false;
    902     clear_scheduled_exception();
    903   }
    904 }
    905 
    906 
    907 void Isolate::RequestInterrupt(InterruptCallback callback, void* data) {
    908   ExecutionAccess access(this);
    909   api_interrupts_queue_.push(InterruptEntry(callback, data));
    910   stack_guard()->RequestApiInterrupt();
    911 }
    912 
    913 
    914 void Isolate::InvokeApiInterruptCallbacks() {
    915   // Note: callback below should be called outside of execution access lock.
    916   while (true) {
    917     InterruptEntry entry;
    918     {
    919       ExecutionAccess access(this);
    920       if (api_interrupts_queue_.empty()) return;
    921       entry = api_interrupts_queue_.front();
    922       api_interrupts_queue_.pop();
    923     }
    924     VMState<EXTERNAL> state(this);
    925     HandleScope handle_scope(this);
    926     entry.first(reinterpret_cast<v8::Isolate*>(this), entry.second);
    927   }
    928 }
    929 
    930 
    931 void ReportBootstrappingException(Handle<Object> exception,
    932                                   MessageLocation* location) {
    933   base::OS::PrintError("Exception thrown during bootstrapping\n");
    934   if (location == NULL || location->script().is_null()) return;
    935   // We are bootstrapping and caught an error where the location is set
    936   // and we have a script for the location.
    937   // In this case we could have an extension (or an internal error
    938   // somewhere) and we print out the line number at which the error occured
    939   // to the console for easier debugging.
    940   int line_number =
    941       location->script()->GetLineNumber(location->start_pos()) + 1;
    942   if (exception->IsString() && location->script()->name()->IsString()) {
    943     base::OS::PrintError(
    944         "Extension or internal compilation error: %s in %s at line %d.\n",
    945         String::cast(*exception)->ToCString().get(),
    946         String::cast(location->script()->name())->ToCString().get(),
    947         line_number);
    948   } else if (location->script()->name()->IsString()) {
    949     base::OS::PrintError(
    950         "Extension or internal compilation error in %s at line %d.\n",
    951         String::cast(location->script()->name())->ToCString().get(),
    952         line_number);
    953   } else if (exception->IsString()) {
    954     base::OS::PrintError("Extension or internal compilation error: %s.\n",
    955                          String::cast(*exception)->ToCString().get());
    956   } else {
    957     base::OS::PrintError("Extension or internal compilation error.\n");
    958   }
    959 #ifdef OBJECT_PRINT
    960   // Since comments and empty lines have been stripped from the source of
    961   // builtins, print the actual source here so that line numbers match.
    962   if (location->script()->source()->IsString()) {
    963     Handle<String> src(String::cast(location->script()->source()));
    964     PrintF("Failing script:");
    965     int len = src->length();
    966     if (len == 0) {
    967       PrintF(" <not available>\n");
    968     } else {
    969       PrintF("\n");
    970       int line_number = 1;
    971       PrintF("%5d: ", line_number);
    972       for (int i = 0; i < len; i++) {
    973         uint16_t character = src->Get(i);
    974         PrintF("%c", character);
    975         if (character == '\n' && i < len - 2) {
    976           PrintF("%5d: ", ++line_number);
    977         }
    978       }
    979       PrintF("\n");
    980     }
    981   }
    982 #endif
    983 }
    984 
    985 
    986 Object* Isolate::Throw(Object* exception, MessageLocation* location) {
    987   DCHECK(!has_pending_exception());
    988 
    989   HandleScope scope(this);
    990   Handle<Object> exception_handle(exception, this);
    991 
    992   // Determine whether a message needs to be created for the given exception
    993   // depending on the following criteria:
    994   // 1) External v8::TryCatch missing: Always create a message because any
    995   //    JavaScript handler for a finally-block might re-throw to top-level.
    996   // 2) External v8::TryCatch exists: Only create a message if the handler
    997   //    captures messages or is verbose (which reports despite the catch).
    998   // 3) ReThrow from v8::TryCatch: The message from a previous throw still
    999   //    exists and we preserve it instead of creating a new message.
   1000   bool requires_message = try_catch_handler() == nullptr ||
   1001                           try_catch_handler()->is_verbose_ ||
   1002                           try_catch_handler()->capture_message_;
   1003   bool rethrowing_message = thread_local_top()->rethrowing_message_;
   1004 
   1005   thread_local_top()->rethrowing_message_ = false;
   1006 
   1007   // Notify debugger of exception.
   1008   if (is_catchable_by_javascript(exception)) {
   1009     debug()->OnThrow(exception_handle);
   1010   }
   1011 
   1012   // Generate the message if required.
   1013   if (requires_message && !rethrowing_message) {
   1014     MessageLocation computed_location;
   1015     // If no location was specified we try to use a computed one instead.
   1016     if (location == NULL && ComputeLocation(&computed_location)) {
   1017       location = &computed_location;
   1018     }
   1019 
   1020     if (bootstrapper()->IsActive()) {
   1021       // It's not safe to try to make message objects or collect stack traces
   1022       // while the bootstrapper is active since the infrastructure may not have
   1023       // been properly initialized.
   1024       ReportBootstrappingException(exception_handle, location);
   1025     } else {
   1026       Handle<Object> message_obj = CreateMessage(exception_handle, location);
   1027       thread_local_top()->pending_message_obj_ = *message_obj;
   1028 
   1029       // For any exception not caught by JavaScript, even when an external
   1030       // handler is present:
   1031       // If the abort-on-uncaught-exception flag is specified, and if the
   1032       // embedder didn't specify a custom uncaught exception callback,
   1033       // or if the custom callback determined that V8 should abort, then
   1034       // abort.
   1035       if (FLAG_abort_on_uncaught_exception &&
   1036           PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT &&
   1037           (!abort_on_uncaught_exception_callback_ ||
   1038            abort_on_uncaught_exception_callback_(
   1039                reinterpret_cast<v8::Isolate*>(this)))) {
   1040         // Prevent endless recursion.
   1041         FLAG_abort_on_uncaught_exception = false;
   1042         // This flag is intended for use by JavaScript developers, so
   1043         // print a user-friendly stack trace (not an internal one).
   1044         PrintF(stderr, "%s\n\nFROM\n",
   1045                MessageHandler::GetLocalizedMessage(this, message_obj).get());
   1046         PrintCurrentStackTrace(stderr);
   1047         base::OS::Abort();
   1048       }
   1049     }
   1050   }
   1051 
   1052   // Set the exception being thrown.
   1053   set_pending_exception(*exception_handle);
   1054   return heap()->exception();
   1055 }
   1056 
   1057 
   1058 Object* Isolate::ReThrow(Object* exception) {
   1059   DCHECK(!has_pending_exception());
   1060 
   1061   // Set the exception being re-thrown.
   1062   set_pending_exception(exception);
   1063   return heap()->exception();
   1064 }
   1065 
   1066 
   1067 Object* Isolate::UnwindAndFindHandler() {
   1068   Object* exception = pending_exception();
   1069 
   1070   Code* code = nullptr;
   1071   Context* context = nullptr;
   1072   intptr_t offset = 0;
   1073   Address handler_sp = nullptr;
   1074   Address handler_fp = nullptr;
   1075 
   1076   // Special handling of termination exceptions, uncatchable by JavaScript code,
   1077   // we unwind the handlers until the top ENTRY handler is found.
   1078   bool catchable_by_js = is_catchable_by_javascript(exception);
   1079 
   1080   // Compute handler and stack unwinding information by performing a full walk
   1081   // over the stack and dispatching according to the frame type.
   1082   for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) {
   1083     StackFrame* frame = iter.frame();
   1084 
   1085     // For JSEntryStub frames we always have a handler.
   1086     if (frame->is_entry() || frame->is_entry_construct()) {
   1087       StackHandler* handler = frame->top_handler();
   1088 
   1089       // Restore the next handler.
   1090       thread_local_top()->handler_ = handler->next()->address();
   1091 
   1092       // Gather information from the handler.
   1093       code = frame->LookupCode();
   1094       handler_sp = handler->address() + StackHandlerConstants::kSize;
   1095       offset = Smi::cast(code->handler_table()->get(0))->value();
   1096       break;
   1097     }
   1098 
   1099     // For optimized frames we perform a lookup in the handler table.
   1100     if (frame->is_optimized() && catchable_by_js) {
   1101       OptimizedFrame* js_frame = static_cast<OptimizedFrame*>(frame);
   1102       int stack_slots = 0;  // Will contain stack slot count of frame.
   1103       offset = js_frame->LookupExceptionHandlerInTable(&stack_slots, NULL);
   1104       if (offset >= 0) {
   1105         // Compute the stack pointer from the frame pointer. This ensures that
   1106         // argument slots on the stack are dropped as returning would.
   1107         Address return_sp = frame->fp() -
   1108                             StandardFrameConstants::kFixedFrameSizeFromFp -
   1109                             stack_slots * kPointerSize;
   1110 
   1111         // Gather information from the frame.
   1112         code = frame->LookupCode();
   1113         handler_sp = return_sp;
   1114         handler_fp = frame->fp();
   1115         break;
   1116       }
   1117     }
   1118 
   1119     // For JavaScript frames we perform a range lookup in the handler table.
   1120     if (frame->is_java_script() && catchable_by_js) {
   1121       JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame);
   1122       int stack_slots = 0;  // Will contain operand stack depth of handler.
   1123       offset = js_frame->LookupExceptionHandlerInTable(&stack_slots, NULL);
   1124       if (offset >= 0) {
   1125         // Compute the stack pointer from the frame pointer. This ensures that
   1126         // operand stack slots are dropped for nested statements. Also restore
   1127         // correct context for the handler which is pushed within the try-block.
   1128         Address return_sp = frame->fp() -
   1129                             StandardFrameConstants::kFixedFrameSizeFromFp -
   1130                             stack_slots * kPointerSize;
   1131         STATIC_ASSERT(TryBlockConstant::kElementCount == 1);
   1132         context = Context::cast(Memory::Object_at(return_sp - kPointerSize));
   1133 
   1134         // Gather information from the frame.
   1135         code = frame->LookupCode();
   1136         handler_sp = return_sp;
   1137         handler_fp = frame->fp();
   1138         break;
   1139       }
   1140     }
   1141 
   1142     RemoveMaterializedObjectsOnUnwind(frame);
   1143   }
   1144 
   1145   // Handler must exist.
   1146   CHECK(code != nullptr);
   1147 
   1148   // Store information to be consumed by the CEntryStub.
   1149   thread_local_top()->pending_handler_context_ = context;
   1150   thread_local_top()->pending_handler_code_ = code;
   1151   thread_local_top()->pending_handler_offset_ = offset;
   1152   thread_local_top()->pending_handler_fp_ = handler_fp;
   1153   thread_local_top()->pending_handler_sp_ = handler_sp;
   1154 
   1155   // Return and clear pending exception.
   1156   clear_pending_exception();
   1157   return exception;
   1158 }
   1159 
   1160 
   1161 Isolate::CatchType Isolate::PredictExceptionCatcher() {
   1162   Address external_handler = thread_local_top()->try_catch_handler_address();
   1163   Address entry_handler = Isolate::handler(thread_local_top());
   1164   if (IsExternalHandlerOnTop(nullptr)) return CAUGHT_BY_EXTERNAL;
   1165 
   1166   // Search for an exception handler by performing a full walk over the stack.
   1167   for (StackFrameIterator iter(this); !iter.done(); iter.Advance()) {
   1168     StackFrame* frame = iter.frame();
   1169 
   1170     // For JSEntryStub frames we update the JS_ENTRY handler.
   1171     if (frame->is_entry() || frame->is_entry_construct()) {
   1172       entry_handler = frame->top_handler()->next()->address();
   1173     }
   1174 
   1175     // For JavaScript frames we perform a lookup in the handler table.
   1176     if (frame->is_java_script()) {
   1177       JavaScriptFrame* js_frame = static_cast<JavaScriptFrame*>(frame);
   1178       int stack_slots = 0;  // The computed stack slot count is not used.
   1179       HandlerTable::CatchPrediction prediction;
   1180       if (js_frame->LookupExceptionHandlerInTable(&stack_slots, &prediction) >
   1181           0) {
   1182         // We are conservative with our prediction: try-finally is considered
   1183         // to always rethrow, to meet the expectation of the debugger.
   1184         if (prediction == HandlerTable::CAUGHT) return CAUGHT_BY_JAVASCRIPT;
   1185       }
   1186     }
   1187 
   1188     // The exception has been externally caught if and only if there is an
   1189     // external handler which is on top of the top-most JS_ENTRY handler.
   1190     if (external_handler != nullptr && !try_catch_handler()->is_verbose_) {
   1191       if (entry_handler == nullptr || entry_handler > external_handler) {
   1192         return CAUGHT_BY_EXTERNAL;
   1193       }
   1194     }
   1195   }
   1196 
   1197   // Handler not found.
   1198   return NOT_CAUGHT;
   1199 }
   1200 
   1201 
   1202 void Isolate::RemoveMaterializedObjectsOnUnwind(StackFrame* frame) {
   1203   if (frame->is_optimized()) {
   1204     bool removed = materialized_object_store_->Remove(frame->fp());
   1205     USE(removed);
   1206     // If there were any materialized objects, the code should be
   1207     // marked for deopt.
   1208     DCHECK(!removed || frame->LookupCode()->marked_for_deoptimization());
   1209   }
   1210 }
   1211 
   1212 
   1213 Object* Isolate::ThrowIllegalOperation() {
   1214   if (FLAG_stack_trace_on_illegal) PrintStack(stdout);
   1215   return Throw(heap()->illegal_access_string());
   1216 }
   1217 
   1218 
   1219 void Isolate::ScheduleThrow(Object* exception) {
   1220   // When scheduling a throw we first throw the exception to get the
   1221   // error reporting if it is uncaught before rescheduling it.
   1222   Throw(exception);
   1223   PropagatePendingExceptionToExternalTryCatch();
   1224   if (has_pending_exception()) {
   1225     thread_local_top()->scheduled_exception_ = pending_exception();
   1226     thread_local_top()->external_caught_exception_ = false;
   1227     clear_pending_exception();
   1228   }
   1229 }
   1230 
   1231 
   1232 void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) {
   1233   DCHECK(handler == try_catch_handler());
   1234   DCHECK(handler->HasCaught());
   1235   DCHECK(handler->rethrow_);
   1236   DCHECK(handler->capture_message_);
   1237   Object* message = reinterpret_cast<Object*>(handler->message_obj_);
   1238   DCHECK(message->IsJSMessageObject() || message->IsTheHole());
   1239   thread_local_top()->pending_message_obj_ = message;
   1240 }
   1241 
   1242 
   1243 void Isolate::CancelScheduledExceptionFromTryCatch(v8::TryCatch* handler) {
   1244   DCHECK(has_scheduled_exception());
   1245   if (scheduled_exception() == handler->exception_) {
   1246     DCHECK(scheduled_exception() != heap()->termination_exception());
   1247     clear_scheduled_exception();
   1248   }
   1249 }
   1250 
   1251 
   1252 Object* Isolate::PromoteScheduledException() {
   1253   Object* thrown = scheduled_exception();
   1254   clear_scheduled_exception();
   1255   // Re-throw the exception to avoid getting repeated error reporting.
   1256   return ReThrow(thrown);
   1257 }
   1258 
   1259 
   1260 void Isolate::PrintCurrentStackTrace(FILE* out) {
   1261   StackTraceFrameIterator it(this);
   1262   while (!it.done()) {
   1263     HandleScope scope(this);
   1264     // Find code position if recorded in relocation info.
   1265     JavaScriptFrame* frame = it.frame();
   1266     int pos = frame->LookupCode()->SourcePosition(frame->pc());
   1267     Handle<Object> pos_obj(Smi::FromInt(pos), this);
   1268     // Fetch function and receiver.
   1269     Handle<JSFunction> fun(frame->function());
   1270     Handle<Object> recv(frame->receiver(), this);
   1271     // Advance to the next JavaScript frame and determine if the
   1272     // current frame is the top-level frame.
   1273     it.Advance();
   1274     Handle<Object> is_top_level = factory()->ToBoolean(it.done());
   1275     // Generate and print stack trace line.
   1276     Handle<String> line =
   1277         Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);
   1278     if (line->length() > 0) {
   1279       line->PrintOn(out);
   1280       PrintF(out, "\n");
   1281     }
   1282   }
   1283 }
   1284 
   1285 
   1286 bool Isolate::ComputeLocation(MessageLocation* target) {
   1287   StackTraceFrameIterator it(this);
   1288   if (!it.done()) {
   1289     JavaScriptFrame* frame = it.frame();
   1290     JSFunction* fun = frame->function();
   1291     Object* script = fun->shared()->script();
   1292     if (script->IsScript() &&
   1293         !(Script::cast(script)->source()->IsUndefined())) {
   1294       Handle<Script> casted_script(Script::cast(script));
   1295       // Compute the location from the function and the relocation info of the
   1296       // baseline code. For optimized code this will use the deoptimization
   1297       // information to get canonical location information.
   1298       List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
   1299       it.frame()->Summarize(&frames);
   1300       FrameSummary& summary = frames.last();
   1301       int pos = summary.code()->SourcePosition(summary.pc());
   1302       *target = MessageLocation(casted_script, pos, pos + 1, handle(fun));
   1303       return true;
   1304     }
   1305   }
   1306   return false;
   1307 }
   1308 
   1309 
   1310 bool Isolate::ComputeLocationFromException(MessageLocation* target,
   1311                                            Handle<Object> exception) {
   1312   if (!exception->IsJSObject()) return false;
   1313 
   1314   Handle<Name> start_pos_symbol = factory()->error_start_pos_symbol();
   1315   Handle<Object> start_pos = JSReceiver::GetDataProperty(
   1316       Handle<JSObject>::cast(exception), start_pos_symbol);
   1317   if (!start_pos->IsSmi()) return false;
   1318   int start_pos_value = Handle<Smi>::cast(start_pos)->value();
   1319 
   1320   Handle<Name> end_pos_symbol = factory()->error_end_pos_symbol();
   1321   Handle<Object> end_pos = JSReceiver::GetDataProperty(
   1322       Handle<JSObject>::cast(exception), end_pos_symbol);
   1323   if (!end_pos->IsSmi()) return false;
   1324   int end_pos_value = Handle<Smi>::cast(end_pos)->value();
   1325 
   1326   Handle<Name> script_symbol = factory()->error_script_symbol();
   1327   Handle<Object> script = JSReceiver::GetDataProperty(
   1328       Handle<JSObject>::cast(exception), script_symbol);
   1329   if (!script->IsScript()) return false;
   1330 
   1331   Handle<Script> cast_script(Script::cast(*script));
   1332   *target = MessageLocation(cast_script, start_pos_value, end_pos_value);
   1333   return true;
   1334 }
   1335 
   1336 
   1337 bool Isolate::ComputeLocationFromStackTrace(MessageLocation* target,
   1338                                             Handle<Object> exception) {
   1339   if (!exception->IsJSObject()) return false;
   1340   Handle<Name> key = factory()->stack_trace_symbol();
   1341   Handle<Object> property =
   1342       JSReceiver::GetDataProperty(Handle<JSObject>::cast(exception), key);
   1343   if (!property->IsJSArray()) return false;
   1344   Handle<JSArray> simple_stack_trace = Handle<JSArray>::cast(property);
   1345 
   1346   Handle<FixedArray> elements(FixedArray::cast(simple_stack_trace->elements()));
   1347   int elements_limit = Smi::cast(simple_stack_trace->length())->value();
   1348 
   1349   for (int i = 1; i < elements_limit; i += 4) {
   1350     Handle<JSFunction> fun =
   1351         handle(JSFunction::cast(elements->get(i + 1)), this);
   1352     if (!fun->shared()->IsSubjectToDebugging()) continue;
   1353 
   1354     Object* script = fun->shared()->script();
   1355     if (script->IsScript() &&
   1356         !(Script::cast(script)->source()->IsUndefined())) {
   1357       int pos = PositionFromStackTrace(elements, i);
   1358       Handle<Script> casted_script(Script::cast(script));
   1359       *target = MessageLocation(casted_script, pos, pos + 1);
   1360       return true;
   1361     }
   1362   }
   1363   return false;
   1364 }
   1365 
   1366 
   1367 Handle<JSMessageObject> Isolate::CreateMessage(Handle<Object> exception,
   1368                                                MessageLocation* location) {
   1369   Handle<JSArray> stack_trace_object;
   1370   if (capture_stack_trace_for_uncaught_exceptions_) {
   1371     if (Object::IsErrorObject(this, exception)) {
   1372       // We fetch the stack trace that corresponds to this error object.
   1373       // If the lookup fails, the exception is probably not a valid Error
   1374       // object. In that case, we fall through and capture the stack trace
   1375       // at this throw site.
   1376       stack_trace_object =
   1377           GetDetailedStackTrace(Handle<JSObject>::cast(exception));
   1378     }
   1379     if (stack_trace_object.is_null()) {
   1380       // Not an error object, we capture stack and location at throw site.
   1381       stack_trace_object = CaptureCurrentStackTrace(
   1382           stack_trace_for_uncaught_exceptions_frame_limit_,
   1383           stack_trace_for_uncaught_exceptions_options_);
   1384     }
   1385   }
   1386   MessageLocation computed_location;
   1387   if (location == NULL &&
   1388       (ComputeLocationFromException(&computed_location, exception) ||
   1389        ComputeLocationFromStackTrace(&computed_location, exception) ||
   1390        ComputeLocation(&computed_location))) {
   1391     location = &computed_location;
   1392   }
   1393 
   1394   return MessageHandler::MakeMessageObject(
   1395       this, MessageTemplate::kUncaughtException, location, exception,
   1396       stack_trace_object);
   1397 }
   1398 
   1399 
   1400 bool Isolate::IsJavaScriptHandlerOnTop(Object* exception) {
   1401   DCHECK_NE(heap()->the_hole_value(), exception);
   1402 
   1403   // For uncatchable exceptions, the JavaScript handler cannot be on top.
   1404   if (!is_catchable_by_javascript(exception)) return false;
   1405 
   1406   // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist.
   1407   Address entry_handler = Isolate::handler(thread_local_top());
   1408   if (entry_handler == nullptr) return false;
   1409 
   1410   // Get the address of the external handler so we can compare the address to
   1411   // determine which one is closer to the top of the stack.
   1412   Address external_handler = thread_local_top()->try_catch_handler_address();
   1413   if (external_handler == nullptr) return true;
   1414 
   1415   // The exception has been externally caught if and only if there is an
   1416   // external handler which is on top of the top-most JS_ENTRY handler.
   1417   //
   1418   // Note, that finally clauses would re-throw an exception unless it's aborted
   1419   // by jumps in control flow (like return, break, etc.) and we'll have another
   1420   // chance to set proper v8::TryCatch later.
   1421   return (entry_handler < external_handler);
   1422 }
   1423 
   1424 
   1425 bool Isolate::IsExternalHandlerOnTop(Object* exception) {
   1426   DCHECK_NE(heap()->the_hole_value(), exception);
   1427 
   1428   // Get the address of the external handler so we can compare the address to
   1429   // determine which one is closer to the top of the stack.
   1430   Address external_handler = thread_local_top()->try_catch_handler_address();
   1431   if (external_handler == nullptr) return false;
   1432 
   1433   // For uncatchable exceptions, the external handler is always on top.
   1434   if (!is_catchable_by_javascript(exception)) return true;
   1435 
   1436   // Get the top-most JS_ENTRY handler, cannot be on top if it doesn't exist.
   1437   Address entry_handler = Isolate::handler(thread_local_top());
   1438   if (entry_handler == nullptr) return true;
   1439 
   1440   // The exception has been externally caught if and only if there is an
   1441   // external handler which is on top of the top-most JS_ENTRY handler.
   1442   //
   1443   // Note, that finally clauses would re-throw an exception unless it's aborted
   1444   // by jumps in control flow (like return, break, etc.) and we'll have another
   1445   // chance to set proper v8::TryCatch later.
   1446   return (entry_handler > external_handler);
   1447 }
   1448 
   1449 
   1450 void Isolate::ReportPendingMessages() {
   1451   Object* exception = pending_exception();
   1452 
   1453   // Try to propagate the exception to an external v8::TryCatch handler. If
   1454   // propagation was unsuccessful, then we will get another chance at reporting
   1455   // the pending message if the exception is re-thrown.
   1456   bool has_been_propagated = PropagatePendingExceptionToExternalTryCatch();
   1457   if (!has_been_propagated) return;
   1458 
   1459   // Clear the pending message object early to avoid endless recursion.
   1460   Object* message_obj = thread_local_top_.pending_message_obj_;
   1461   clear_pending_message();
   1462 
   1463   // For uncatchable exceptions we do nothing. If needed, the exception and the
   1464   // message have already been propagated to v8::TryCatch.
   1465   if (!is_catchable_by_javascript(exception)) return;
   1466 
   1467   // Determine whether the message needs to be reported to all message handlers
   1468   // depending on whether and external v8::TryCatch or an internal JavaScript
   1469   // handler is on top.
   1470   bool should_report_exception;
   1471   if (IsExternalHandlerOnTop(exception)) {
   1472     // Only report the exception if the external handler is verbose.
   1473     should_report_exception = try_catch_handler()->is_verbose_;
   1474   } else {
   1475     // Report the exception if it isn't caught by JavaScript code.
   1476     should_report_exception = !IsJavaScriptHandlerOnTop(exception);
   1477   }
   1478 
   1479   // Actually report the pending message to all message handlers.
   1480   if (!message_obj->IsTheHole() && should_report_exception) {
   1481     HandleScope scope(this);
   1482     Handle<JSMessageObject> message(JSMessageObject::cast(message_obj));
   1483     Handle<JSValue> script_wrapper(JSValue::cast(message->script()));
   1484     Handle<Script> script(Script::cast(script_wrapper->value()));
   1485     int start_pos = message->start_position();
   1486     int end_pos = message->end_position();
   1487     MessageLocation location(script, start_pos, end_pos);
   1488     MessageHandler::ReportMessage(this, &location, message);
   1489   }
   1490 }
   1491 
   1492 
   1493 MessageLocation Isolate::GetMessageLocation() {
   1494   DCHECK(has_pending_exception());
   1495 
   1496   if (thread_local_top_.pending_exception_ != heap()->termination_exception() &&
   1497       !thread_local_top_.pending_message_obj_->IsTheHole()) {
   1498     Handle<JSMessageObject> message_obj(
   1499         JSMessageObject::cast(thread_local_top_.pending_message_obj_));
   1500     Handle<JSValue> script_wrapper(JSValue::cast(message_obj->script()));
   1501     Handle<Script> script(Script::cast(script_wrapper->value()));
   1502     int start_pos = message_obj->start_position();
   1503     int end_pos = message_obj->end_position();
   1504     return MessageLocation(script, start_pos, end_pos);
   1505   }
   1506 
   1507   return MessageLocation();
   1508 }
   1509 
   1510 
   1511 bool Isolate::OptionalRescheduleException(bool is_bottom_call) {
   1512   DCHECK(has_pending_exception());
   1513   PropagatePendingExceptionToExternalTryCatch();
   1514 
   1515   bool is_termination_exception =
   1516       pending_exception() == heap_.termination_exception();
   1517 
   1518   // Do not reschedule the exception if this is the bottom call.
   1519   bool clear_exception = is_bottom_call;
   1520 
   1521   if (is_termination_exception) {
   1522     if (is_bottom_call) {
   1523       thread_local_top()->external_caught_exception_ = false;
   1524       clear_pending_exception();
   1525       return false;
   1526     }
   1527   } else if (thread_local_top()->external_caught_exception_) {
   1528     // If the exception is externally caught, clear it if there are no
   1529     // JavaScript frames on the way to the C++ frame that has the
   1530     // external handler.
   1531     DCHECK(thread_local_top()->try_catch_handler_address() != NULL);
   1532     Address external_handler_address =
   1533         thread_local_top()->try_catch_handler_address();
   1534     JavaScriptFrameIterator it(this);
   1535     if (it.done() || (it.frame()->sp() > external_handler_address)) {
   1536       clear_exception = true;
   1537     }
   1538   }
   1539 
   1540   // Clear the exception if needed.
   1541   if (clear_exception) {
   1542     thread_local_top()->external_caught_exception_ = false;
   1543     clear_pending_exception();
   1544     return false;
   1545   }
   1546 
   1547   // Reschedule the exception.
   1548   thread_local_top()->scheduled_exception_ = pending_exception();
   1549   clear_pending_exception();
   1550   return true;
   1551 }
   1552 
   1553 
   1554 void Isolate::PushPromise(Handle<JSObject> promise,
   1555                           Handle<JSFunction> function) {
   1556   ThreadLocalTop* tltop = thread_local_top();
   1557   PromiseOnStack* prev = tltop->promise_on_stack_;
   1558   Handle<JSObject> global_promise =
   1559       Handle<JSObject>::cast(global_handles()->Create(*promise));
   1560   Handle<JSFunction> global_function =
   1561       Handle<JSFunction>::cast(global_handles()->Create(*function));
   1562   tltop->promise_on_stack_ =
   1563       new PromiseOnStack(global_function, global_promise, prev);
   1564 }
   1565 
   1566 
   1567 void Isolate::PopPromise() {
   1568   ThreadLocalTop* tltop = thread_local_top();
   1569   if (tltop->promise_on_stack_ == NULL) return;
   1570   PromiseOnStack* prev = tltop->promise_on_stack_->prev();
   1571   Handle<Object> global_function = tltop->promise_on_stack_->function();
   1572   Handle<Object> global_promise = tltop->promise_on_stack_->promise();
   1573   delete tltop->promise_on_stack_;
   1574   tltop->promise_on_stack_ = prev;
   1575   global_handles()->Destroy(global_function.location());
   1576   global_handles()->Destroy(global_promise.location());
   1577 }
   1578 
   1579 
   1580 Handle<Object> Isolate::GetPromiseOnStackOnThrow() {
   1581   Handle<Object> undefined = factory()->undefined_value();
   1582   ThreadLocalTop* tltop = thread_local_top();
   1583   if (tltop->promise_on_stack_ == NULL) return undefined;
   1584   Handle<JSFunction> promise_function = tltop->promise_on_stack_->function();
   1585   // Find the top-most try-catch or try-finally handler.
   1586   if (PredictExceptionCatcher() != CAUGHT_BY_JAVASCRIPT) return undefined;
   1587   for (JavaScriptFrameIterator it(this); !it.done(); it.Advance()) {
   1588     JavaScriptFrame* frame = it.frame();
   1589     int stack_slots = 0;  // The computed stack slot count is not used.
   1590     if (frame->LookupExceptionHandlerInTable(&stack_slots, NULL) > 0) {
   1591       // Throwing inside a Promise only leads to a reject if not caught by an
   1592       // inner try-catch or try-finally.
   1593       if (frame->function() == *promise_function) {
   1594         return tltop->promise_on_stack_->promise();
   1595       }
   1596       return undefined;
   1597     }
   1598   }
   1599   return undefined;
   1600 }
   1601 
   1602 
   1603 void Isolate::SetCaptureStackTraceForUncaughtExceptions(
   1604       bool capture,
   1605       int frame_limit,
   1606       StackTrace::StackTraceOptions options) {
   1607   capture_stack_trace_for_uncaught_exceptions_ = capture;
   1608   stack_trace_for_uncaught_exceptions_frame_limit_ = frame_limit;
   1609   stack_trace_for_uncaught_exceptions_options_ = options;
   1610 }
   1611 
   1612 
   1613 void Isolate::SetAbortOnUncaughtExceptionCallback(
   1614     v8::Isolate::AbortOnUncaughtExceptionCallback callback) {
   1615   abort_on_uncaught_exception_callback_ = callback;
   1616 }
   1617 
   1618 
   1619 Handle<Context> Isolate::native_context() {
   1620   return handle(context()->native_context());
   1621 }
   1622 
   1623 
   1624 Handle<Context> Isolate::GetCallingNativeContext() {
   1625   JavaScriptFrameIterator it(this);
   1626   if (debug_->in_debug_scope()) {
   1627     while (!it.done()) {
   1628       JavaScriptFrame* frame = it.frame();
   1629       Context* context = Context::cast(frame->context());
   1630       if (context->native_context() == *debug_->debug_context()) {
   1631         it.Advance();
   1632       } else {
   1633         break;
   1634       }
   1635     }
   1636   }
   1637   if (it.done()) return Handle<Context>::null();
   1638   JavaScriptFrame* frame = it.frame();
   1639   Context* context = Context::cast(frame->context());
   1640   return Handle<Context>(context->native_context());
   1641 }
   1642 
   1643 
   1644 char* Isolate::ArchiveThread(char* to) {
   1645   MemCopy(to, reinterpret_cast<char*>(thread_local_top()),
   1646           sizeof(ThreadLocalTop));
   1647   InitializeThreadLocal();
   1648   clear_pending_exception();
   1649   clear_pending_message();
   1650   clear_scheduled_exception();
   1651   return to + sizeof(ThreadLocalTop);
   1652 }
   1653 
   1654 
   1655 char* Isolate::RestoreThread(char* from) {
   1656   MemCopy(reinterpret_cast<char*>(thread_local_top()), from,
   1657           sizeof(ThreadLocalTop));
   1658 // This might be just paranoia, but it seems to be needed in case a
   1659 // thread_local_top_ is restored on a separate OS thread.
   1660 #ifdef USE_SIMULATOR
   1661   thread_local_top()->simulator_ = Simulator::current(this);
   1662 #endif
   1663   DCHECK(context() == NULL || context()->IsContext());
   1664   return from + sizeof(ThreadLocalTop);
   1665 }
   1666 
   1667 
   1668 Isolate::ThreadDataTable::ThreadDataTable()
   1669     : list_(NULL) {
   1670 }
   1671 
   1672 
   1673 Isolate::ThreadDataTable::~ThreadDataTable() {
   1674   // TODO(svenpanne) The assertion below would fire if an embedder does not
   1675   // cleanly dispose all Isolates before disposing v8, so we are conservative
   1676   // and leave it out for now.
   1677   // DCHECK_NULL(list_);
   1678 }
   1679 
   1680 
   1681 Isolate::PerIsolateThreadData::~PerIsolateThreadData() {
   1682 #if defined(USE_SIMULATOR)
   1683   delete simulator_;
   1684 #endif
   1685 }
   1686 
   1687 
   1688 Isolate::PerIsolateThreadData*
   1689     Isolate::ThreadDataTable::Lookup(Isolate* isolate,
   1690                                      ThreadId thread_id) {
   1691   for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) {
   1692     if (data->Matches(isolate, thread_id)) return data;
   1693   }
   1694   return NULL;
   1695 }
   1696 
   1697 
   1698 void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) {
   1699   if (list_ != NULL) list_->prev_ = data;
   1700   data->next_ = list_;
   1701   list_ = data;
   1702 }
   1703 
   1704 
   1705 void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) {
   1706   if (list_ == data) list_ = data->next_;
   1707   if (data->next_ != NULL) data->next_->prev_ = data->prev_;
   1708   if (data->prev_ != NULL) data->prev_->next_ = data->next_;
   1709   delete data;
   1710 }
   1711 
   1712 
   1713 void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) {
   1714   PerIsolateThreadData* data = list_;
   1715   while (data != NULL) {
   1716     PerIsolateThreadData* next = data->next_;
   1717     if (data->isolate() == isolate) Remove(data);
   1718     data = next;
   1719   }
   1720 }
   1721 
   1722 
   1723 #ifdef DEBUG
   1724 #define TRACE_ISOLATE(tag)                                              \
   1725   do {                                                                  \
   1726     if (FLAG_trace_isolates) {                                          \
   1727       PrintF("Isolate %p (id %d)" #tag "\n",                            \
   1728              reinterpret_cast<void*>(this), id());                      \
   1729     }                                                                   \
   1730   } while (false)
   1731 #else
   1732 #define TRACE_ISOLATE(tag)
   1733 #endif
   1734 
   1735 
   1736 Isolate::Isolate(bool enable_serializer)
   1737     : embedder_data_(),
   1738       entry_stack_(NULL),
   1739       stack_trace_nesting_level_(0),
   1740       incomplete_message_(NULL),
   1741       bootstrapper_(NULL),
   1742       runtime_profiler_(NULL),
   1743       compilation_cache_(NULL),
   1744       counters_(NULL),
   1745       code_range_(NULL),
   1746       logger_(NULL),
   1747       stats_table_(NULL),
   1748       stub_cache_(NULL),
   1749       code_aging_helper_(NULL),
   1750       deoptimizer_data_(NULL),
   1751       materialized_object_store_(NULL),
   1752       capture_stack_trace_for_uncaught_exceptions_(false),
   1753       stack_trace_for_uncaught_exceptions_frame_limit_(0),
   1754       stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview),
   1755       memory_allocator_(NULL),
   1756       keyed_lookup_cache_(NULL),
   1757       context_slot_cache_(NULL),
   1758       descriptor_lookup_cache_(NULL),
   1759       handle_scope_implementer_(NULL),
   1760       unicode_cache_(NULL),
   1761       inner_pointer_to_code_cache_(NULL),
   1762       global_handles_(NULL),
   1763       eternal_handles_(NULL),
   1764       thread_manager_(NULL),
   1765       has_installed_extensions_(false),
   1766       regexp_stack_(NULL),
   1767       date_cache_(NULL),
   1768       call_descriptor_data_(NULL),
   1769       // TODO(bmeurer) Initialized lazily because it depends on flags; can
   1770       // be fixed once the default isolate cleanup is done.
   1771       random_number_generator_(NULL),
   1772       serializer_enabled_(enable_serializer),
   1773       has_fatal_error_(false),
   1774       initialized_from_snapshot_(false),
   1775       cpu_profiler_(NULL),
   1776       heap_profiler_(NULL),
   1777       function_entry_hook_(NULL),
   1778       deferred_handles_head_(NULL),
   1779       optimizing_compile_dispatcher_(NULL),
   1780       stress_deopt_count_(0),
   1781       virtual_handler_register_(NULL),
   1782       virtual_slot_register_(NULL),
   1783       next_optimization_id_(0),
   1784       js_calls_from_api_counter_(0),
   1785 #if TRACE_MAPS
   1786       next_unique_sfi_id_(0),
   1787 #endif
   1788       use_counter_callback_(NULL),
   1789       basic_block_profiler_(NULL),
   1790       cancelable_task_manager_(new CancelableTaskManager()),
   1791       abort_on_uncaught_exception_callback_(NULL) {
   1792   {
   1793     base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
   1794     CHECK(thread_data_table_);
   1795   }
   1796   id_ = base::NoBarrier_AtomicIncrement(&isolate_counter_, 1);
   1797   TRACE_ISOLATE(constructor);
   1798 
   1799   memset(isolate_addresses_, 0,
   1800       sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1));
   1801 
   1802   heap_.isolate_ = this;
   1803   stack_guard_.isolate_ = this;
   1804 
   1805   // ThreadManager is initialized early to support locking an isolate
   1806   // before it is entered.
   1807   thread_manager_ = new ThreadManager();
   1808   thread_manager_->isolate_ = this;
   1809 
   1810 #ifdef DEBUG
   1811   // heap_histograms_ initializes itself.
   1812   memset(&js_spill_information_, 0, sizeof(js_spill_information_));
   1813 #endif
   1814 
   1815   handle_scope_data_.Initialize();
   1816 
   1817 #define ISOLATE_INIT_EXECUTE(type, name, initial_value)                        \
   1818   name##_ = (initial_value);
   1819   ISOLATE_INIT_LIST(ISOLATE_INIT_EXECUTE)
   1820 #undef ISOLATE_INIT_EXECUTE
   1821 
   1822 #define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length)                         \
   1823   memset(name##_, 0, sizeof(type) * length);
   1824   ISOLATE_INIT_ARRAY_LIST(ISOLATE_INIT_ARRAY_EXECUTE)
   1825 #undef ISOLATE_INIT_ARRAY_EXECUTE
   1826 
   1827   InitializeLoggingAndCounters();
   1828   debug_ = new Debug(this);
   1829 
   1830   init_memcopy_functions(this);
   1831 }
   1832 
   1833 
   1834 void Isolate::TearDown() {
   1835   TRACE_ISOLATE(tear_down);
   1836 
   1837   // Temporarily set this isolate as current so that various parts of
   1838   // the isolate can access it in their destructors without having a
   1839   // direct pointer. We don't use Enter/Exit here to avoid
   1840   // initializing the thread data.
   1841   PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData();
   1842   DCHECK(base::NoBarrier_Load(&isolate_key_created_) == 1);
   1843   Isolate* saved_isolate =
   1844       reinterpret_cast<Isolate*>(base::Thread::GetThreadLocal(isolate_key_));
   1845   SetIsolateThreadLocals(this, NULL);
   1846 
   1847   Deinit();
   1848 
   1849   {
   1850     base::LockGuard<base::Mutex> lock_guard(thread_data_table_mutex_.Pointer());
   1851     thread_data_table_->RemoveAllThreads(this);
   1852   }
   1853 
   1854   delete this;
   1855 
   1856   // Restore the previous current isolate.
   1857   SetIsolateThreadLocals(saved_isolate, saved_data);
   1858 }
   1859 
   1860 
   1861 void Isolate::GlobalTearDown() {
   1862   delete thread_data_table_;
   1863   thread_data_table_ = NULL;
   1864 }
   1865 
   1866 
   1867 void Isolate::ClearSerializerData() {
   1868   delete external_reference_table_;
   1869   external_reference_table_ = NULL;
   1870   delete external_reference_map_;
   1871   external_reference_map_ = NULL;
   1872 }
   1873 
   1874 
   1875 void Isolate::Deinit() {
   1876   TRACE_ISOLATE(deinit);
   1877 
   1878   debug()->Unload();
   1879 
   1880   FreeThreadResources();
   1881 
   1882   if (concurrent_recompilation_enabled()) {
   1883     optimizing_compile_dispatcher_->Stop();
   1884     delete optimizing_compile_dispatcher_;
   1885     optimizing_compile_dispatcher_ = NULL;
   1886   }
   1887 
   1888   if (heap_.mark_compact_collector()->sweeping_in_progress()) {
   1889     heap_.mark_compact_collector()->EnsureSweepingCompleted();
   1890   }
   1891 
   1892   DumpAndResetCompilationStats();
   1893 
   1894   if (FLAG_print_deopt_stress) {
   1895     PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_);
   1896   }
   1897 
   1898   if (cpu_profiler_) {
   1899     cpu_profiler_->DeleteAllProfiles();
   1900   }
   1901 
   1902   // We must stop the logger before we tear down other components.
   1903   Sampler* sampler = logger_->sampler();
   1904   if (sampler && sampler->IsActive()) sampler->Stop();
   1905 
   1906   delete interpreter_;
   1907   interpreter_ = NULL;
   1908 
   1909   delete deoptimizer_data_;
   1910   deoptimizer_data_ = NULL;
   1911   builtins_.TearDown();
   1912   bootstrapper_->TearDown();
   1913 
   1914   if (runtime_profiler_ != NULL) {
   1915     delete runtime_profiler_;
   1916     runtime_profiler_ = NULL;
   1917   }
   1918 
   1919   delete basic_block_profiler_;
   1920   basic_block_profiler_ = NULL;
   1921 
   1922   heap_.TearDown();
   1923   logger_->TearDown();
   1924 
   1925   cancelable_task_manager()->CancelAndWait();
   1926 
   1927   delete heap_profiler_;
   1928   heap_profiler_ = NULL;
   1929   delete cpu_profiler_;
   1930   cpu_profiler_ = NULL;
   1931 
   1932   delete root_index_map_;
   1933   root_index_map_ = NULL;
   1934 
   1935   ClearSerializerData();
   1936 }
   1937 
   1938 
   1939 void Isolate::SetIsolateThreadLocals(Isolate* isolate,
   1940                                      PerIsolateThreadData* data) {
   1941   base::Thread::SetThreadLocal(isolate_key_, isolate);
   1942   base::Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
   1943 }
   1944 
   1945 
   1946 Isolate::~Isolate() {
   1947   TRACE_ISOLATE(destructor);
   1948 
   1949   // Has to be called while counters_ are still alive
   1950   runtime_zone_.DeleteKeptSegment();
   1951 
   1952   // The entry stack must be empty when we get here.
   1953   DCHECK(entry_stack_ == NULL || entry_stack_->previous_item == NULL);
   1954 
   1955   delete entry_stack_;
   1956   entry_stack_ = NULL;
   1957 
   1958   delete unicode_cache_;
   1959   unicode_cache_ = NULL;
   1960 
   1961   delete date_cache_;
   1962   date_cache_ = NULL;
   1963 
   1964   delete[] call_descriptor_data_;
   1965   call_descriptor_data_ = NULL;
   1966 
   1967   delete regexp_stack_;
   1968   regexp_stack_ = NULL;
   1969 
   1970   delete descriptor_lookup_cache_;
   1971   descriptor_lookup_cache_ = NULL;
   1972   delete context_slot_cache_;
   1973   context_slot_cache_ = NULL;
   1974   delete keyed_lookup_cache_;
   1975   keyed_lookup_cache_ = NULL;
   1976 
   1977   delete stub_cache_;
   1978   stub_cache_ = NULL;
   1979   delete code_aging_helper_;
   1980   code_aging_helper_ = NULL;
   1981   delete stats_table_;
   1982   stats_table_ = NULL;
   1983 
   1984   delete materialized_object_store_;
   1985   materialized_object_store_ = NULL;
   1986 
   1987   delete logger_;
   1988   logger_ = NULL;
   1989 
   1990   delete counters_;
   1991   counters_ = NULL;
   1992 
   1993   delete handle_scope_implementer_;
   1994   handle_scope_implementer_ = NULL;
   1995 
   1996   delete code_tracer();
   1997   set_code_tracer(NULL);
   1998 
   1999   delete compilation_cache_;
   2000   compilation_cache_ = NULL;
   2001   delete bootstrapper_;
   2002   bootstrapper_ = NULL;
   2003   delete inner_pointer_to_code_cache_;
   2004   inner_pointer_to_code_cache_ = NULL;
   2005 
   2006   delete thread_manager_;
   2007   thread_manager_ = NULL;
   2008 
   2009   delete memory_allocator_;
   2010   memory_allocator_ = NULL;
   2011   delete code_range_;
   2012   code_range_ = NULL;
   2013   delete global_handles_;
   2014   global_handles_ = NULL;
   2015   delete eternal_handles_;
   2016   eternal_handles_ = NULL;
   2017 
   2018   delete string_stream_debug_object_cache_;
   2019   string_stream_debug_object_cache_ = NULL;
   2020 
   2021   delete random_number_generator_;
   2022   random_number_generator_ = NULL;
   2023 
   2024   delete debug_;
   2025   debug_ = NULL;
   2026 
   2027   delete cancelable_task_manager_;
   2028   cancelable_task_manager_ = nullptr;
   2029 
   2030 #if USE_SIMULATOR
   2031   Simulator::TearDown(simulator_i_cache_, simulator_redirection_);
   2032   simulator_i_cache_ = nullptr;
   2033   simulator_redirection_ = nullptr;
   2034 #endif
   2035 }
   2036 
   2037 
   2038 void Isolate::InitializeThreadLocal() {
   2039   thread_local_top_.isolate_ = this;
   2040   thread_local_top_.Initialize();
   2041 }
   2042 
   2043 
   2044 bool Isolate::PropagatePendingExceptionToExternalTryCatch() {
   2045   Object* exception = pending_exception();
   2046 
   2047   if (IsJavaScriptHandlerOnTop(exception)) {
   2048     thread_local_top_.external_caught_exception_ = false;
   2049     return false;
   2050   }
   2051 
   2052   if (!IsExternalHandlerOnTop(exception)) {
   2053     thread_local_top_.external_caught_exception_ = false;
   2054     return true;
   2055   }
   2056 
   2057   thread_local_top_.external_caught_exception_ = true;
   2058   if (!is_catchable_by_javascript(exception)) {
   2059     try_catch_handler()->can_continue_ = false;
   2060     try_catch_handler()->has_terminated_ = true;
   2061     try_catch_handler()->exception_ = heap()->null_value();
   2062   } else {
   2063     v8::TryCatch* handler = try_catch_handler();
   2064     DCHECK(thread_local_top_.pending_message_obj_->IsJSMessageObject() ||
   2065            thread_local_top_.pending_message_obj_->IsTheHole());
   2066     handler->can_continue_ = true;
   2067     handler->has_terminated_ = false;
   2068     handler->exception_ = pending_exception();
   2069     // Propagate to the external try-catch only if we got an actual message.
   2070     if (thread_local_top_.pending_message_obj_->IsTheHole()) return true;
   2071 
   2072     handler->message_obj_ = thread_local_top_.pending_message_obj_;
   2073   }
   2074   return true;
   2075 }
   2076 
   2077 
   2078 void Isolate::InitializeLoggingAndCounters() {
   2079   if (logger_ == NULL) {
   2080     logger_ = new Logger(this);
   2081   }
   2082   if (counters_ == NULL) {
   2083     counters_ = new Counters(this);
   2084   }
   2085 }
   2086 
   2087 
   2088 bool Isolate::Init(Deserializer* des) {
   2089   TRACE_ISOLATE(init);
   2090 
   2091   stress_deopt_count_ = FLAG_deopt_every_n_times;
   2092 
   2093   has_fatal_error_ = false;
   2094 
   2095   if (function_entry_hook() != NULL) {
   2096     // When function entry hooking is in effect, we have to create the code
   2097     // stubs from scratch to get entry hooks, rather than loading the previously
   2098     // generated stubs from disk.
   2099     // If this assert fires, the initialization path has regressed.
   2100     DCHECK(des == NULL);
   2101   }
   2102 
   2103   // The initialization process does not handle memory exhaustion.
   2104   AlwaysAllocateScope always_allocate(this);
   2105 
   2106   memory_allocator_ = new MemoryAllocator(this);
   2107   code_range_ = new CodeRange(this);
   2108 
   2109   // Safe after setting Heap::isolate_, and initializing StackGuard
   2110   heap_.SetStackLimits();
   2111 
   2112 #define ASSIGN_ELEMENT(CamelName, hacker_name)                  \
   2113   isolate_addresses_[Isolate::k##CamelName##Address] =          \
   2114       reinterpret_cast<Address>(hacker_name##_address());
   2115   FOR_EACH_ISOLATE_ADDRESS_NAME(ASSIGN_ELEMENT)
   2116 #undef ASSIGN_ELEMENT
   2117 
   2118   compilation_cache_ = new CompilationCache(this);
   2119   keyed_lookup_cache_ = new KeyedLookupCache();
   2120   context_slot_cache_ = new ContextSlotCache();
   2121   descriptor_lookup_cache_ = new DescriptorLookupCache();
   2122   unicode_cache_ = new UnicodeCache();
   2123   inner_pointer_to_code_cache_ = new InnerPointerToCodeCache(this);
   2124   global_handles_ = new GlobalHandles(this);
   2125   eternal_handles_ = new EternalHandles();
   2126   bootstrapper_ = new Bootstrapper(this);
   2127   handle_scope_implementer_ = new HandleScopeImplementer(this);
   2128   stub_cache_ = new StubCache(this);
   2129   materialized_object_store_ = new MaterializedObjectStore(this);
   2130   regexp_stack_ = new RegExpStack();
   2131   regexp_stack_->isolate_ = this;
   2132   date_cache_ = new DateCache();
   2133   call_descriptor_data_ =
   2134       new CallInterfaceDescriptorData[CallDescriptors::NUMBER_OF_DESCRIPTORS];
   2135   cpu_profiler_ = new CpuProfiler(this);
   2136   heap_profiler_ = new HeapProfiler(heap());
   2137   interpreter_ = new interpreter::Interpreter(this);
   2138 
   2139   // Enable logging before setting up the heap
   2140   logger_->SetUp(this);
   2141 
   2142   // Initialize other runtime facilities
   2143 #if defined(USE_SIMULATOR)
   2144 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS || \
   2145     V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_PPC
   2146   Simulator::Initialize(this);
   2147 #endif
   2148 #endif
   2149 
   2150   code_aging_helper_ = new CodeAgingHelper(this);
   2151 
   2152   { // NOLINT
   2153     // Ensure that the thread has a valid stack guard.  The v8::Locker object
   2154     // will ensure this too, but we don't have to use lockers if we are only
   2155     // using one thread.
   2156     ExecutionAccess lock(this);
   2157     stack_guard_.InitThread(lock);
   2158   }
   2159 
   2160   // SetUp the object heap.
   2161   DCHECK(!heap_.HasBeenSetUp());
   2162   if (!heap_.SetUp()) {
   2163     V8::FatalProcessOutOfMemory("heap setup");
   2164     return false;
   2165   }
   2166 
   2167   deoptimizer_data_ = new DeoptimizerData(memory_allocator_);
   2168 
   2169   const bool create_heap_objects = (des == NULL);
   2170   if (create_heap_objects && !heap_.CreateHeapObjects()) {
   2171     V8::FatalProcessOutOfMemory("heap object creation");
   2172     return false;
   2173   }
   2174 
   2175   if (create_heap_objects) {
   2176     // Terminate the cache array with the sentinel so we can iterate.
   2177     partial_snapshot_cache_.Add(heap_.undefined_value());
   2178   }
   2179 
   2180   InitializeThreadLocal();
   2181 
   2182   bootstrapper_->Initialize(create_heap_objects);
   2183   builtins_.SetUp(this, create_heap_objects);
   2184 
   2185   if (FLAG_log_internal_timer_events) {
   2186     set_event_logger(Logger::DefaultEventLoggerSentinel);
   2187   }
   2188 
   2189   if (FLAG_trace_hydrogen || FLAG_trace_hydrogen_stubs) {
   2190     PrintF("Concurrent recompilation has been disabled for tracing.\n");
   2191   } else if (OptimizingCompileDispatcher::Enabled()) {
   2192     optimizing_compile_dispatcher_ = new OptimizingCompileDispatcher(this);
   2193   }
   2194 
   2195   // Initialize runtime profiler before deserialization, because collections may
   2196   // occur, clearing/updating ICs.
   2197   runtime_profiler_ = new RuntimeProfiler(this);
   2198 
   2199   // If we are deserializing, read the state into the now-empty heap.
   2200   if (!create_heap_objects) {
   2201     des->Deserialize(this);
   2202   }
   2203   stub_cache_->Initialize();
   2204 
   2205   if (FLAG_ignition) {
   2206     interpreter_->Initialize();
   2207   }
   2208 
   2209   // Finish initialization of ThreadLocal after deserialization is done.
   2210   clear_pending_exception();
   2211   clear_pending_message();
   2212   clear_scheduled_exception();
   2213 
   2214   // Deserializing may put strange things in the root array's copy of the
   2215   // stack guard.
   2216   heap_.SetStackLimits();
   2217 
   2218   // Quiet the heap NaN if needed on target platform.
   2219   if (!create_heap_objects) Assembler::QuietNaN(heap_.nan_value());
   2220 
   2221   if (FLAG_trace_turbo) {
   2222     // Create an empty file.
   2223     std::ofstream(GetTurboCfgFileName().c_str(), std::ios_base::trunc);
   2224   }
   2225 
   2226   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, embedder_data_)),
   2227            Internals::kIsolateEmbedderDataOffset);
   2228   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, heap_.roots_)),
   2229            Internals::kIsolateRootsOffset);
   2230   CHECK_EQ(static_cast<int>(
   2231                OFFSET_OF(Isolate, heap_.amount_of_external_allocated_memory_)),
   2232            Internals::kAmountOfExternalAllocatedMemoryOffset);
   2233   CHECK_EQ(static_cast<int>(OFFSET_OF(
   2234                Isolate,
   2235                heap_.amount_of_external_allocated_memory_at_last_global_gc_)),
   2236            Internals::kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset);
   2237 
   2238   time_millis_at_init_ = heap_.MonotonicallyIncreasingTimeInMs();
   2239 
   2240   heap_.NotifyDeserializationComplete();
   2241 
   2242   if (!create_heap_objects) {
   2243     // Now that the heap is consistent, it's OK to generate the code for the
   2244     // deopt entry table that might have been referred to by optimized code in
   2245     // the snapshot.
   2246     HandleScope scope(this);
   2247     Deoptimizer::EnsureCodeForDeoptimizationEntry(
   2248         this,
   2249         Deoptimizer::LAZY,
   2250         kDeoptTableSerializeEntryCount - 1);
   2251   }
   2252 
   2253   if (!serializer_enabled()) {
   2254     // Ensure that all stubs which need to be generated ahead of time, but
   2255     // cannot be serialized into the snapshot have been generated.
   2256     HandleScope scope(this);
   2257     CodeStub::GenerateFPStubs(this);
   2258     StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(this);
   2259     StubFailureTrampolineStub::GenerateAheadOfTime(this);
   2260   }
   2261 
   2262   initialized_from_snapshot_ = (des != NULL);
   2263 
   2264   if (!FLAG_inline_new) heap_.DisableInlineAllocation();
   2265 
   2266   return true;
   2267 }
   2268 
   2269 
   2270 // Initialized lazily to allow early
   2271 // v8::V8::SetAddHistogramSampleFunction calls.
   2272 StatsTable* Isolate::stats_table() {
   2273   if (stats_table_ == NULL) {
   2274     stats_table_ = new StatsTable;
   2275   }
   2276   return stats_table_;
   2277 }
   2278 
   2279 
   2280 void Isolate::Enter() {
   2281   Isolate* current_isolate = NULL;
   2282   PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
   2283   if (current_data != NULL) {
   2284     current_isolate = current_data->isolate_;
   2285     DCHECK(current_isolate != NULL);
   2286     if (current_isolate == this) {
   2287       DCHECK(Current() == this);
   2288       DCHECK(entry_stack_ != NULL);
   2289       DCHECK(entry_stack_->previous_thread_data == NULL ||
   2290              entry_stack_->previous_thread_data->thread_id().Equals(
   2291                  ThreadId::Current()));
   2292       // Same thread re-enters the isolate, no need to re-init anything.
   2293       entry_stack_->entry_count++;
   2294       return;
   2295     }
   2296   }
   2297 
   2298   PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread();
   2299   DCHECK(data != NULL);
   2300   DCHECK(data->isolate_ == this);
   2301 
   2302   EntryStackItem* item = new EntryStackItem(current_data,
   2303                                             current_isolate,
   2304                                             entry_stack_);
   2305   entry_stack_ = item;
   2306 
   2307   SetIsolateThreadLocals(this, data);
   2308 
   2309   // In case it's the first time some thread enters the isolate.
   2310   set_thread_id(data->thread_id());
   2311 }
   2312 
   2313 
   2314 void Isolate::Exit() {
   2315   DCHECK(entry_stack_ != NULL);
   2316   DCHECK(entry_stack_->previous_thread_data == NULL ||
   2317          entry_stack_->previous_thread_data->thread_id().Equals(
   2318              ThreadId::Current()));
   2319 
   2320   if (--entry_stack_->entry_count > 0) return;
   2321 
   2322   DCHECK(CurrentPerIsolateThreadData() != NULL);
   2323   DCHECK(CurrentPerIsolateThreadData()->isolate_ == this);
   2324 
   2325   // Pop the stack.
   2326   EntryStackItem* item = entry_stack_;
   2327   entry_stack_ = item->previous_item;
   2328 
   2329   PerIsolateThreadData* previous_thread_data = item->previous_thread_data;
   2330   Isolate* previous_isolate = item->previous_isolate;
   2331 
   2332   delete item;
   2333 
   2334   // Reinit the current thread for the isolate it was running before this one.
   2335   SetIsolateThreadLocals(previous_isolate, previous_thread_data);
   2336 }
   2337 
   2338 
   2339 void Isolate::LinkDeferredHandles(DeferredHandles* deferred) {
   2340   deferred->next_ = deferred_handles_head_;
   2341   if (deferred_handles_head_ != NULL) {
   2342     deferred_handles_head_->previous_ = deferred;
   2343   }
   2344   deferred_handles_head_ = deferred;
   2345 }
   2346 
   2347 
   2348 void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) {
   2349 #ifdef DEBUG
   2350   // In debug mode assert that the linked list is well-formed.
   2351   DeferredHandles* deferred_iterator = deferred;
   2352   while (deferred_iterator->previous_ != NULL) {
   2353     deferred_iterator = deferred_iterator->previous_;
   2354   }
   2355   DCHECK(deferred_handles_head_ == deferred_iterator);
   2356 #endif
   2357   if (deferred_handles_head_ == deferred) {
   2358     deferred_handles_head_ = deferred_handles_head_->next_;
   2359   }
   2360   if (deferred->next_ != NULL) {
   2361     deferred->next_->previous_ = deferred->previous_;
   2362   }
   2363   if (deferred->previous_ != NULL) {
   2364     deferred->previous_->next_ = deferred->next_;
   2365   }
   2366 }
   2367 
   2368 
   2369 void Isolate::DumpAndResetCompilationStats() {
   2370   if (turbo_statistics() != nullptr) {
   2371     OFStream os(stdout);
   2372     os << *turbo_statistics() << std::endl;
   2373   }
   2374   if (hstatistics() != nullptr) hstatistics()->Print();
   2375   delete turbo_statistics_;
   2376   turbo_statistics_ = nullptr;
   2377   delete hstatistics_;
   2378   hstatistics_ = nullptr;
   2379 }
   2380 
   2381 
   2382 HStatistics* Isolate::GetHStatistics() {
   2383   if (hstatistics() == NULL) set_hstatistics(new HStatistics());
   2384   return hstatistics();
   2385 }
   2386 
   2387 
   2388 CompilationStatistics* Isolate::GetTurboStatistics() {
   2389   if (turbo_statistics() == NULL)
   2390     set_turbo_statistics(new CompilationStatistics());
   2391   return turbo_statistics();
   2392 }
   2393 
   2394 
   2395 HTracer* Isolate::GetHTracer() {
   2396   if (htracer() == NULL) set_htracer(new HTracer(id()));
   2397   return htracer();
   2398 }
   2399 
   2400 
   2401 CodeTracer* Isolate::GetCodeTracer() {
   2402   if (code_tracer() == NULL) set_code_tracer(new CodeTracer(id()));
   2403   return code_tracer();
   2404 }
   2405 
   2406 
   2407 Map* Isolate::get_initial_js_array_map(ElementsKind kind, Strength strength) {
   2408   if (IsFastElementsKind(kind)) {
   2409     DisallowHeapAllocation no_gc;
   2410     Object* const initial_js_array_map = context()->native_context()->get(
   2411         Context::ArrayMapIndex(kind, strength));
   2412     if (!initial_js_array_map->IsUndefined()) {
   2413       return Map::cast(initial_js_array_map);
   2414     }
   2415   }
   2416   return nullptr;
   2417 }
   2418 
   2419 
   2420 bool Isolate::use_crankshaft() const {
   2421   return FLAG_crankshaft &&
   2422          !serializer_enabled_ &&
   2423          CpuFeatures::SupportsCrankshaft();
   2424 }
   2425 
   2426 
   2427 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
   2428   PropertyCell* no_elements_cell = heap()->array_protector();
   2429   bool cell_reports_intact =
   2430       no_elements_cell->value()->IsSmi() &&
   2431       Smi::cast(no_elements_cell->value())->value() == kArrayProtectorValid;
   2432 
   2433 #ifdef DEBUG
   2434   Map* root_array_map =
   2435       get_initial_js_array_map(GetInitialFastElementsKind());
   2436   Context* native_context = context()->native_context();
   2437   JSObject* initial_array_proto = JSObject::cast(
   2438       native_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
   2439   JSObject* initial_object_proto = JSObject::cast(
   2440       native_context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX));
   2441 
   2442   if (root_array_map == NULL || initial_array_proto == initial_object_proto) {
   2443     // We are in the bootstrapping process, and the entire check sequence
   2444     // shouldn't be performed.
   2445     return cell_reports_intact;
   2446   }
   2447 
   2448   // Check that the array prototype hasn't been altered WRT empty elements.
   2449   if (root_array_map->prototype() != initial_array_proto) {
   2450     DCHECK_EQ(false, cell_reports_intact);
   2451     return cell_reports_intact;
   2452   }
   2453 
   2454   FixedArrayBase* elements = initial_array_proto->elements();
   2455   if (elements != heap()->empty_fixed_array() &&
   2456       elements != heap()->empty_slow_element_dictionary()) {
   2457     DCHECK_EQ(false, cell_reports_intact);
   2458     return cell_reports_intact;
   2459   }
   2460 
   2461   // Check that the object prototype hasn't been altered WRT empty elements.
   2462   PrototypeIterator iter(this, initial_array_proto);
   2463   if (iter.IsAtEnd() || iter.GetCurrent() != initial_object_proto) {
   2464     DCHECK_EQ(false, cell_reports_intact);
   2465     return cell_reports_intact;
   2466   }
   2467 
   2468   elements = initial_object_proto->elements();
   2469   if (elements != heap()->empty_fixed_array() &&
   2470       elements != heap()->empty_slow_element_dictionary()) {
   2471     DCHECK_EQ(false, cell_reports_intact);
   2472     return cell_reports_intact;
   2473   }
   2474 
   2475   iter.Advance();
   2476   if (!iter.IsAtEnd()) {
   2477     DCHECK_EQ(false, cell_reports_intact);
   2478     return cell_reports_intact;
   2479   }
   2480 
   2481 #endif
   2482 
   2483   return cell_reports_intact;
   2484 }
   2485 
   2486 
   2487 void Isolate::UpdateArrayProtectorOnSetElement(Handle<JSObject> object) {
   2488   if (IsFastArrayConstructorPrototypeChainIntact() &&
   2489       object->map()->is_prototype_map()) {
   2490     Object* context = heap()->native_contexts_list();
   2491     while (!context->IsUndefined()) {
   2492       Context* current_context = Context::cast(context);
   2493       if (current_context->get(Context::INITIAL_OBJECT_PROTOTYPE_INDEX) ==
   2494               *object ||
   2495           current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
   2496               *object) {
   2497         PropertyCell::SetValueWithInvalidation(
   2498             factory()->array_protector(),
   2499             handle(Smi::FromInt(kArrayProtectorInvalid), this));
   2500         break;
   2501       }
   2502       context = current_context->get(Context::NEXT_CONTEXT_LINK);
   2503     }
   2504   }
   2505 }
   2506 
   2507 
   2508 bool Isolate::IsAnyInitialArrayPrototype(Handle<JSArray> array) {
   2509   if (array->map()->is_prototype_map()) {
   2510     Object* context = heap()->native_contexts_list();
   2511     while (!context->IsUndefined()) {
   2512       Context* current_context = Context::cast(context);
   2513       if (current_context->get(Context::INITIAL_ARRAY_PROTOTYPE_INDEX) ==
   2514           *array) {
   2515         return true;
   2516       }
   2517       context = current_context->get(Context::NEXT_CONTEXT_LINK);
   2518     }
   2519   }
   2520   return false;
   2521 }
   2522 
   2523 
   2524 CallInterfaceDescriptorData* Isolate::call_descriptor_data(int index) {
   2525   DCHECK(0 <= index && index < CallDescriptors::NUMBER_OF_DESCRIPTORS);
   2526   return &call_descriptor_data_[index];
   2527 }
   2528 
   2529 
   2530 base::RandomNumberGenerator* Isolate::random_number_generator() {
   2531   if (random_number_generator_ == NULL) {
   2532     if (FLAG_random_seed != 0) {
   2533       random_number_generator_ =
   2534           new base::RandomNumberGenerator(FLAG_random_seed);
   2535     } else {
   2536       random_number_generator_ = new base::RandomNumberGenerator();
   2537     }
   2538   }
   2539   return random_number_generator_;
   2540 }
   2541 
   2542 
   2543 Object* Isolate::FindCodeObject(Address a) {
   2544   return inner_pointer_to_code_cache()->GcSafeFindCodeForInnerPointer(a);
   2545 }
   2546 
   2547 
   2548 #ifdef DEBUG
   2549 #define ISOLATE_FIELD_OFFSET(type, name, ignored)                       \
   2550 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
   2551 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
   2552 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
   2553 #undef ISOLATE_FIELD_OFFSET
   2554 #endif
   2555 
   2556 
   2557 Handle<JSObject> Isolate::SetUpSubregistry(Handle<JSObject> registry,
   2558                                            Handle<Map> map, const char* cname) {
   2559   Handle<String> name = factory()->InternalizeUtf8String(cname);
   2560   Handle<JSObject> obj = factory()->NewJSObjectFromMap(map);
   2561   JSObject::NormalizeProperties(obj, CLEAR_INOBJECT_PROPERTIES, 0,
   2562                                 "SetupSymbolRegistry");
   2563   JSObject::AddProperty(registry, name, obj, NONE);
   2564   return obj;
   2565 }
   2566 
   2567 
   2568 Handle<JSObject> Isolate::GetSymbolRegistry() {
   2569   if (heap()->symbol_registry()->IsSmi()) {
   2570     Handle<Map> map = factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   2571     Handle<JSObject> registry = factory()->NewJSObjectFromMap(map);
   2572     heap()->set_symbol_registry(*registry);
   2573 
   2574     SetUpSubregistry(registry, map, "for");
   2575     SetUpSubregistry(registry, map, "for_api");
   2576     SetUpSubregistry(registry, map, "keyFor");
   2577     SetUpSubregistry(registry, map, "private_api");
   2578   }
   2579   return Handle<JSObject>::cast(factory()->symbol_registry());
   2580 }
   2581 
   2582 
   2583 void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
   2584   for (int i = 0; i < call_completed_callbacks_.length(); i++) {
   2585     if (callback == call_completed_callbacks_.at(i)) return;
   2586   }
   2587   call_completed_callbacks_.Add(callback);
   2588 }
   2589 
   2590 
   2591 void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
   2592   for (int i = 0; i < call_completed_callbacks_.length(); i++) {
   2593     if (callback == call_completed_callbacks_.at(i)) {
   2594       call_completed_callbacks_.Remove(i);
   2595     }
   2596   }
   2597 }
   2598 
   2599 
   2600 void Isolate::FireCallCompletedCallback() {
   2601   bool has_call_completed_callbacks = !call_completed_callbacks_.is_empty();
   2602   bool run_microtasks = autorun_microtasks() && pending_microtask_count();
   2603   if (!has_call_completed_callbacks && !run_microtasks) return;
   2604 
   2605   if (!handle_scope_implementer()->CallDepthIsZero()) return;
   2606   if (run_microtasks) RunMicrotasks();
   2607   // Fire callbacks.  Increase call depth to prevent recursive callbacks.
   2608   v8::Isolate::SuppressMicrotaskExecutionScope suppress(
   2609       reinterpret_cast<v8::Isolate*>(this));
   2610   for (int i = 0; i < call_completed_callbacks_.length(); i++) {
   2611     call_completed_callbacks_.at(i)();
   2612   }
   2613 }
   2614 
   2615 
   2616 void Isolate::SetPromiseRejectCallback(PromiseRejectCallback callback) {
   2617   promise_reject_callback_ = callback;
   2618 }
   2619 
   2620 
   2621 void Isolate::ReportPromiseReject(Handle<JSObject> promise,
   2622                                   Handle<Object> value,
   2623                                   v8::PromiseRejectEvent event) {
   2624   if (promise_reject_callback_ == NULL) return;
   2625   Handle<JSArray> stack_trace;
   2626   if (event == v8::kPromiseRejectWithNoHandler && value->IsJSObject()) {
   2627     stack_trace = GetDetailedStackTrace(Handle<JSObject>::cast(value));
   2628   }
   2629   promise_reject_callback_(v8::PromiseRejectMessage(
   2630       v8::Utils::PromiseToLocal(promise), event, v8::Utils::ToLocal(value),
   2631       v8::Utils::StackTraceToLocal(stack_trace)));
   2632 }
   2633 
   2634 
   2635 void Isolate::EnqueueMicrotask(Handle<Object> microtask) {
   2636   DCHECK(microtask->IsJSFunction() || microtask->IsCallHandlerInfo());
   2637   Handle<FixedArray> queue(heap()->microtask_queue(), this);
   2638   int num_tasks = pending_microtask_count();
   2639   DCHECK(num_tasks <= queue->length());
   2640   if (num_tasks == 0) {
   2641     queue = factory()->NewFixedArray(8);
   2642     heap()->set_microtask_queue(*queue);
   2643   } else if (num_tasks == queue->length()) {
   2644     queue = factory()->CopyFixedArrayAndGrow(queue, num_tasks);
   2645     heap()->set_microtask_queue(*queue);
   2646   }
   2647   DCHECK(queue->get(num_tasks)->IsUndefined());
   2648   queue->set(num_tasks, *microtask);
   2649   set_pending_microtask_count(num_tasks + 1);
   2650 }
   2651 
   2652 
   2653 void Isolate::RunMicrotasks() {
   2654   // Increase call depth to prevent recursive callbacks.
   2655   v8::Isolate::SuppressMicrotaskExecutionScope suppress(
   2656       reinterpret_cast<v8::Isolate*>(this));
   2657 
   2658   while (pending_microtask_count() > 0) {
   2659     HandleScope scope(this);
   2660     int num_tasks = pending_microtask_count();
   2661     Handle<FixedArray> queue(heap()->microtask_queue(), this);
   2662     DCHECK(num_tasks <= queue->length());
   2663     set_pending_microtask_count(0);
   2664     heap()->set_microtask_queue(heap()->empty_fixed_array());
   2665 
   2666     for (int i = 0; i < num_tasks; i++) {
   2667       HandleScope scope(this);
   2668       Handle<Object> microtask(queue->get(i), this);
   2669       if (microtask->IsJSFunction()) {
   2670         Handle<JSFunction> microtask_function =
   2671             Handle<JSFunction>::cast(microtask);
   2672         SaveContext save(this);
   2673         set_context(microtask_function->context()->native_context());
   2674         MaybeHandle<Object> maybe_exception;
   2675         MaybeHandle<Object> result = Execution::TryCall(
   2676             this, microtask_function, factory()->undefined_value(), 0, NULL,
   2677             &maybe_exception);
   2678         // If execution is terminating, just bail out.
   2679         Handle<Object> exception;
   2680         if (result.is_null() && maybe_exception.is_null()) {
   2681           // Clear out any remaining callbacks in the queue.
   2682           heap()->set_microtask_queue(heap()->empty_fixed_array());
   2683           set_pending_microtask_count(0);
   2684           return;
   2685         }
   2686       } else {
   2687         Handle<CallHandlerInfo> callback_info =
   2688             Handle<CallHandlerInfo>::cast(microtask);
   2689         v8::MicrotaskCallback callback =
   2690             v8::ToCData<v8::MicrotaskCallback>(callback_info->callback());
   2691         void* data = v8::ToCData<void*>(callback_info->data());
   2692         callback(data);
   2693       }
   2694     }
   2695   }
   2696 }
   2697 
   2698 
   2699 void Isolate::SetUseCounterCallback(v8::Isolate::UseCounterCallback callback) {
   2700   DCHECK(!use_counter_callback_);
   2701   use_counter_callback_ = callback;
   2702 }
   2703 
   2704 
   2705 void Isolate::CountUsage(v8::Isolate::UseCounterFeature feature) {
   2706   // The counter callback may cause the embedder to call into V8, which is not
   2707   // generally possible during GC.
   2708   if (heap_.gc_state() == Heap::NOT_IN_GC) {
   2709     if (use_counter_callback_) {
   2710       HandleScope handle_scope(this);
   2711       use_counter_callback_(reinterpret_cast<v8::Isolate*>(this), feature);
   2712     }
   2713   } else {
   2714     heap_.IncrementDeferredCount(feature);
   2715   }
   2716 }
   2717 
   2718 
   2719 BasicBlockProfiler* Isolate::GetOrCreateBasicBlockProfiler() {
   2720   if (basic_block_profiler_ == NULL) {
   2721     basic_block_profiler_ = new BasicBlockProfiler();
   2722   }
   2723   return basic_block_profiler_;
   2724 }
   2725 
   2726 
   2727 std::string Isolate::GetTurboCfgFileName() {
   2728   if (FLAG_trace_turbo_cfg_file == NULL) {
   2729     std::ostringstream os;
   2730     os << "turbo-" << base::OS::GetCurrentProcessId() << "-" << id() << ".cfg";
   2731     return os.str();
   2732   } else {
   2733     return FLAG_trace_turbo_cfg_file;
   2734   }
   2735 }
   2736 
   2737 
   2738 // Heap::detached_contexts tracks detached contexts as pairs
   2739 // (number of GC since the context was detached, the context).
   2740 void Isolate::AddDetachedContext(Handle<Context> context) {
   2741   HandleScope scope(this);
   2742   Handle<WeakCell> cell = factory()->NewWeakCell(context);
   2743   Handle<FixedArray> detached_contexts(heap()->detached_contexts());
   2744   int length = detached_contexts->length();
   2745   detached_contexts = factory()->CopyFixedArrayAndGrow(detached_contexts, 2);
   2746   detached_contexts->set(length, Smi::FromInt(0));
   2747   detached_contexts->set(length + 1, *cell);
   2748   heap()->set_detached_contexts(*detached_contexts);
   2749 }
   2750 
   2751 
   2752 void Isolate::CheckDetachedContextsAfterGC() {
   2753   HandleScope scope(this);
   2754   Handle<FixedArray> detached_contexts(heap()->detached_contexts());
   2755   int length = detached_contexts->length();
   2756   if (length == 0) return;
   2757   int new_length = 0;
   2758   for (int i = 0; i < length; i += 2) {
   2759     int mark_sweeps = Smi::cast(detached_contexts->get(i))->value();
   2760     DCHECK(detached_contexts->get(i + 1)->IsWeakCell());
   2761     WeakCell* cell = WeakCell::cast(detached_contexts->get(i + 1));
   2762     if (!cell->cleared()) {
   2763       detached_contexts->set(new_length, Smi::FromInt(mark_sweeps + 1));
   2764       detached_contexts->set(new_length + 1, cell);
   2765       new_length += 2;
   2766     }
   2767     counters()->detached_context_age_in_gc()->AddSample(mark_sweeps + 1);
   2768   }
   2769   if (FLAG_trace_detached_contexts) {
   2770     PrintF("%d detached contexts are collected out of %d\n",
   2771            length - new_length, length);
   2772     for (int i = 0; i < new_length; i += 2) {
   2773       int mark_sweeps = Smi::cast(detached_contexts->get(i))->value();
   2774       DCHECK(detached_contexts->get(i + 1)->IsWeakCell());
   2775       WeakCell* cell = WeakCell::cast(detached_contexts->get(i + 1));
   2776       if (mark_sweeps > 3) {
   2777         PrintF("detached context 0x%p\n survived %d GCs (leak?)\n",
   2778                static_cast<void*>(cell->value()), mark_sweeps);
   2779       }
   2780     }
   2781   }
   2782   if (new_length == 0) {
   2783     heap()->set_detached_contexts(heap()->empty_fixed_array());
   2784   } else if (new_length < length) {
   2785     heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
   2786         *detached_contexts, length - new_length);
   2787   }
   2788 }
   2789 
   2790 
   2791 bool StackLimitCheck::JsHasOverflowed(uintptr_t gap) const {
   2792   StackGuard* stack_guard = isolate_->stack_guard();
   2793 #ifdef USE_SIMULATOR
   2794   // The simulator uses a separate JS stack.
   2795   Address jssp_address = Simulator::current(isolate_)->get_sp();
   2796   uintptr_t jssp = reinterpret_cast<uintptr_t>(jssp_address);
   2797   if (jssp - gap < stack_guard->real_jslimit()) return true;
   2798 #endif  // USE_SIMULATOR
   2799   return GetCurrentStackPosition() - gap < stack_guard->real_climit();
   2800 }
   2801 
   2802 
   2803 SaveContext::SaveContext(Isolate* isolate)
   2804     : isolate_(isolate), prev_(isolate->save_context()) {
   2805   if (isolate->context() != NULL) {
   2806     context_ = Handle<Context>(isolate->context());
   2807   }
   2808   isolate->set_save_context(this);
   2809 
   2810   c_entry_fp_ = isolate->c_entry_fp(isolate->thread_local_top());
   2811 }
   2812 
   2813 
   2814 SaveContext::~SaveContext() {
   2815   isolate_->set_context(context_.is_null() ? NULL : *context_);
   2816   isolate_->set_save_context(prev_);
   2817 }
   2818 
   2819 
   2820 #ifdef DEBUG
   2821 AssertNoContextChange::AssertNoContextChange(Isolate* isolate)
   2822     : isolate_(isolate), context_(isolate->context(), isolate) {}
   2823 #endif  // DEBUG
   2824 
   2825 
   2826 bool PostponeInterruptsScope::Intercept(StackGuard::InterruptFlag flag) {
   2827   // First check whether the previous scope intercepts.
   2828   if (prev_ && prev_->Intercept(flag)) return true;
   2829   // Then check whether this scope intercepts.
   2830   if ((flag & intercept_mask_)) {
   2831     intercepted_flags_ |= flag;
   2832     return true;
   2833   }
   2834   return false;
   2835 }
   2836 
   2837 }  // namespace internal
   2838 }  // namespace v8
   2839