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 <stdlib.h>
      6 
      7 #include "src/v8.h"
      8 
      9 #include "src/ast.h"
     10 #include "src/bootstrapper.h"
     11 #include "src/codegen.h"
     12 #include "src/compilation-cache.h"
     13 #include "src/cpu-profiler.h"
     14 #include "src/debug.h"
     15 #include "src/deoptimizer.h"
     16 #include "src/heap-profiler.h"
     17 #include "src/hydrogen.h"
     18 #include "src/isolate-inl.h"
     19 #include "src/lithium-allocator.h"
     20 #include "src/log.h"
     21 #include "src/messages.h"
     22 #include "src/platform.h"
     23 #include "src/regexp-stack.h"
     24 #include "src/runtime-profiler.h"
     25 #include "src/sampler.h"
     26 #include "src/scopeinfo.h"
     27 #include "src/serialize.h"
     28 #include "src/simulator.h"
     29 #include "src/spaces.h"
     30 #include "src/stub-cache.h"
     31 #include "src/sweeper-thread.h"
     32 #include "src/utils/random-number-generator.h"
     33 #include "src/version.h"
     34 #include "src/vm-state-inl.h"
     35 
     36 
     37 namespace v8 {
     38 namespace internal {
     39 
     40 base::Atomic32 ThreadId::highest_thread_id_ = 0;
     41 
     42 int ThreadId::AllocateThreadId() {
     43   int new_id = base::NoBarrier_AtomicIncrement(&highest_thread_id_, 1);
     44   return new_id;
     45 }
     46 
     47 
     48 int ThreadId::GetCurrentThreadId() {
     49   int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_);
     50   if (thread_id == 0) {
     51     thread_id = AllocateThreadId();
     52     Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id);
     53   }
     54   return thread_id;
     55 }
     56 
     57 
     58 ThreadLocalTop::ThreadLocalTop() {
     59   InitializeInternal();
     60 }
     61 
     62 
     63 void ThreadLocalTop::InitializeInternal() {
     64   c_entry_fp_ = 0;
     65   handler_ = 0;
     66 #ifdef USE_SIMULATOR
     67   simulator_ = NULL;
     68 #endif
     69   js_entry_sp_ = NULL;
     70   external_callback_scope_ = NULL;
     71   current_vm_state_ = EXTERNAL;
     72   try_catch_handler_ = NULL;
     73   context_ = NULL;
     74   thread_id_ = ThreadId::Invalid();
     75   external_caught_exception_ = false;
     76   failed_access_check_callback_ = NULL;
     77   save_context_ = NULL;
     78   catcher_ = NULL;
     79   top_lookup_result_ = NULL;
     80 
     81   // These members are re-initialized later after deserialization
     82   // is complete.
     83   pending_exception_ = NULL;
     84   has_pending_message_ = false;
     85   rethrowing_message_ = false;
     86   pending_message_obj_ = NULL;
     87   pending_message_script_ = NULL;
     88   scheduled_exception_ = NULL;
     89 }
     90 
     91 
     92 void ThreadLocalTop::Initialize() {
     93   InitializeInternal();
     94 #ifdef USE_SIMULATOR
     95   simulator_ = Simulator::current(isolate_);
     96 #endif
     97   thread_id_ = ThreadId::Current();
     98 }
     99 
    100 
    101 Thread::LocalStorageKey Isolate::isolate_key_;
    102 Thread::LocalStorageKey Isolate::thread_id_key_;
    103 Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
    104 #ifdef DEBUG
    105 Thread::LocalStorageKey PerThreadAssertScopeBase::thread_local_key;
    106 #endif  // DEBUG
    107 Mutex Isolate::process_wide_mutex_;
    108 // TODO(dcarney): Remove with default isolate.
    109 enum DefaultIsolateStatus {
    110   kDefaultIsolateUninitialized,
    111   kDefaultIsolateInitialized,
    112   kDefaultIsolateCrashIfInitialized
    113 };
    114 static DefaultIsolateStatus default_isolate_status_
    115     = kDefaultIsolateUninitialized;
    116 Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
    117 base::Atomic32 Isolate::isolate_counter_ = 0;
    118 
    119 Isolate::PerIsolateThreadData*
    120     Isolate::FindOrAllocatePerThreadDataForThisThread() {
    121   ThreadId thread_id = ThreadId::Current();
    122   PerIsolateThreadData* per_thread = NULL;
    123   {
    124     LockGuard<Mutex> lock_guard(&process_wide_mutex_);
    125     per_thread = thread_data_table_->Lookup(this, thread_id);
    126     if (per_thread == NULL) {
    127       per_thread = new PerIsolateThreadData(this, thread_id);
    128       thread_data_table_->Insert(per_thread);
    129     }
    130     ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread);
    131   }
    132   return per_thread;
    133 }
    134 
    135 
    136 Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThisThread() {
    137   ThreadId thread_id = ThreadId::Current();
    138   return FindPerThreadDataForThread(thread_id);
    139 }
    140 
    141 
    142 Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThread(
    143     ThreadId thread_id) {
    144   PerIsolateThreadData* per_thread = NULL;
    145   {
    146     LockGuard<Mutex> lock_guard(&process_wide_mutex_);
    147     per_thread = thread_data_table_->Lookup(this, thread_id);
    148   }
    149   return per_thread;
    150 }
    151 
    152 
    153 void Isolate::SetCrashIfDefaultIsolateInitialized() {
    154   LockGuard<Mutex> lock_guard(&process_wide_mutex_);
    155   CHECK(default_isolate_status_ != kDefaultIsolateInitialized);
    156   default_isolate_status_ = kDefaultIsolateCrashIfInitialized;
    157 }
    158 
    159 
    160 void Isolate::EnsureDefaultIsolate() {
    161   LockGuard<Mutex> lock_guard(&process_wide_mutex_);
    162   CHECK(default_isolate_status_ != kDefaultIsolateCrashIfInitialized);
    163   if (thread_data_table_ == NULL) {
    164     isolate_key_ = Thread::CreateThreadLocalKey();
    165     thread_id_key_ = Thread::CreateThreadLocalKey();
    166     per_isolate_thread_data_key_ = Thread::CreateThreadLocalKey();
    167 #ifdef DEBUG
    168     PerThreadAssertScopeBase::thread_local_key = Thread::CreateThreadLocalKey();
    169 #endif  // DEBUG
    170     thread_data_table_ = new Isolate::ThreadDataTable();
    171   }
    172 }
    173 
    174 struct StaticInitializer {
    175   StaticInitializer() {
    176     Isolate::EnsureDefaultIsolate();
    177   }
    178 } static_initializer;
    179 
    180 
    181 Address Isolate::get_address_from_id(Isolate::AddressId id) {
    182   return isolate_addresses_[id];
    183 }
    184 
    185 
    186 char* Isolate::Iterate(ObjectVisitor* v, char* thread_storage) {
    187   ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(thread_storage);
    188   Iterate(v, thread);
    189   return thread_storage + sizeof(ThreadLocalTop);
    190 }
    191 
    192 
    193 void Isolate::IterateThread(ThreadVisitor* v, char* t) {
    194   ThreadLocalTop* thread = reinterpret_cast<ThreadLocalTop*>(t);
    195   v->VisitThread(this, thread);
    196 }
    197 
    198 
    199 void Isolate::Iterate(ObjectVisitor* v, ThreadLocalTop* thread) {
    200   // Visit the roots from the top for a given thread.
    201   v->VisitPointer(&thread->pending_exception_);
    202   v->VisitPointer(&(thread->pending_message_obj_));
    203   v->VisitPointer(BitCast<Object**>(&(thread->pending_message_script_)));
    204   v->VisitPointer(BitCast<Object**>(&(thread->context_)));
    205   v->VisitPointer(&thread->scheduled_exception_);
    206 
    207   for (v8::TryCatch* block = thread->try_catch_handler();
    208        block != NULL;
    209        block = block->next_) {
    210     v->VisitPointer(BitCast<Object**>(&(block->exception_)));
    211     v->VisitPointer(BitCast<Object**>(&(block->message_obj_)));
    212     v->VisitPointer(BitCast<Object**>(&(block->message_script_)));
    213   }
    214 
    215   // Iterate over pointers on native execution stack.
    216   for (StackFrameIterator it(this, thread); !it.done(); it.Advance()) {
    217     it.frame()->Iterate(v);
    218   }
    219 
    220   // Iterate pointers in live lookup results.
    221   thread->top_lookup_result_->Iterate(v);
    222 }
    223 
    224 
    225 void Isolate::Iterate(ObjectVisitor* v) {
    226   ThreadLocalTop* current_t = thread_local_top();
    227   Iterate(v, current_t);
    228 }
    229 
    230 
    231 void Isolate::IterateDeferredHandles(ObjectVisitor* visitor) {
    232   for (DeferredHandles* deferred = deferred_handles_head_;
    233        deferred != NULL;
    234        deferred = deferred->next_) {
    235     deferred->Iterate(visitor);
    236   }
    237 }
    238 
    239 
    240 #ifdef DEBUG
    241 bool Isolate::IsDeferredHandle(Object** handle) {
    242   // Each DeferredHandles instance keeps the handles to one job in the
    243   // concurrent recompilation queue, containing a list of blocks.  Each block
    244   // contains kHandleBlockSize handles except for the first block, which may
    245   // not be fully filled.
    246   // We iterate through all the blocks to see whether the argument handle
    247   // belongs to one of the blocks.  If so, it is deferred.
    248   for (DeferredHandles* deferred = deferred_handles_head_;
    249        deferred != NULL;
    250        deferred = deferred->next_) {
    251     List<Object**>* blocks = &deferred->blocks_;
    252     for (int i = 0; i < blocks->length(); i++) {
    253       Object** block_limit = (i == 0) ? deferred->first_block_limit_
    254                                       : blocks->at(i) + kHandleBlockSize;
    255       if (blocks->at(i) <= handle && handle < block_limit) return true;
    256     }
    257   }
    258   return false;
    259 }
    260 #endif  // DEBUG
    261 
    262 
    263 void Isolate::RegisterTryCatchHandler(v8::TryCatch* that) {
    264   thread_local_top()->set_try_catch_handler(that);
    265 }
    266 
    267 
    268 void Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) {
    269   ASSERT(thread_local_top()->try_catch_handler() == that);
    270   thread_local_top()->set_try_catch_handler(that->next_);
    271   thread_local_top()->catcher_ = NULL;
    272 }
    273 
    274 
    275 Handle<String> Isolate::StackTraceString() {
    276   if (stack_trace_nesting_level_ == 0) {
    277     stack_trace_nesting_level_++;
    278     HeapStringAllocator allocator;
    279     StringStream::ClearMentionedObjectCache(this);
    280     StringStream accumulator(&allocator);
    281     incomplete_message_ = &accumulator;
    282     PrintStack(&accumulator);
    283     Handle<String> stack_trace = accumulator.ToString(this);
    284     incomplete_message_ = NULL;
    285     stack_trace_nesting_level_ = 0;
    286     return stack_trace;
    287   } else if (stack_trace_nesting_level_ == 1) {
    288     stack_trace_nesting_level_++;
    289     OS::PrintError(
    290       "\n\nAttempt to print stack while printing stack (double fault)\n");
    291     OS::PrintError(
    292       "If you are lucky you may find a partial stack dump on stdout.\n\n");
    293     incomplete_message_->OutputToStdOut();
    294     return factory()->empty_string();
    295   } else {
    296     OS::Abort();
    297     // Unreachable
    298     return factory()->empty_string();
    299   }
    300 }
    301 
    302 
    303 void Isolate::PushStackTraceAndDie(unsigned int magic,
    304                                    Object* object,
    305                                    Map* map,
    306                                    unsigned int magic2) {
    307   const int kMaxStackTraceSize = 8192;
    308   Handle<String> trace = StackTraceString();
    309   uint8_t buffer[kMaxStackTraceSize];
    310   int length = Min(kMaxStackTraceSize - 1, trace->length());
    311   String::WriteToFlat(*trace, buffer, 0, length);
    312   buffer[length] = '\0';
    313   // TODO(dcarney): convert buffer to utf8?
    314   OS::PrintError("Stacktrace (%x-%x) %p %p: %s\n",
    315                  magic, magic2,
    316                  static_cast<void*>(object), static_cast<void*>(map),
    317                  reinterpret_cast<char*>(buffer));
    318   OS::Abort();
    319 }
    320 
    321 
    322 // Determines whether the given stack frame should be displayed in
    323 // a stack trace.  The caller is the error constructor that asked
    324 // for the stack trace to be collected.  The first time a construct
    325 // call to this function is encountered it is skipped.  The seen_caller
    326 // in/out parameter is used to remember if the caller has been seen
    327 // yet.
    328 static bool IsVisibleInStackTrace(StackFrame* raw_frame,
    329                                   Object* caller,
    330                                   bool* seen_caller) {
    331   // Only display JS frames.
    332   if (!raw_frame->is_java_script()) return false;
    333   JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
    334   JSFunction* fun = frame->function();
    335   if ((fun == caller) && !(*seen_caller)) {
    336     *seen_caller = true;
    337     return false;
    338   }
    339   // Skip all frames until we've seen the caller.
    340   if (!(*seen_caller)) return false;
    341   // Also, skip non-visible built-in functions and any call with the builtins
    342   // object as receiver, so as to not reveal either the builtins object or
    343   // an internal function.
    344   // The --builtins-in-stack-traces command line flag allows including
    345   // internal call sites in the stack trace for debugging purposes.
    346   if (!FLAG_builtins_in_stack_traces) {
    347     if (frame->receiver()->IsJSBuiltinsObject() ||
    348         (fun->IsBuiltin() && !fun->shared()->native())) {
    349       return false;
    350     }
    351   }
    352   return true;
    353 }
    354 
    355 
    356 Handle<JSArray> Isolate::CaptureSimpleStackTrace(Handle<JSObject> error_object,
    357                                                  Handle<Object> caller,
    358                                                  int limit) {
    359   limit = Max(limit, 0);  // Ensure that limit is not negative.
    360   int initial_size = Min(limit, 10);
    361   Handle<FixedArray> elements =
    362       factory()->NewFixedArrayWithHoles(initial_size * 4 + 1);
    363 
    364   // If the caller parameter is a function we skip frames until we're
    365   // under it before starting to collect.
    366   bool seen_caller = !caller->IsJSFunction();
    367   // First element is reserved to store the number of sloppy frames.
    368   int cursor = 1;
    369   int frames_seen = 0;
    370   int sloppy_frames = 0;
    371   bool encountered_strict_function = false;
    372   for (StackFrameIterator iter(this);
    373        !iter.done() && frames_seen < limit;
    374        iter.Advance()) {
    375     StackFrame* raw_frame = iter.frame();
    376     if (IsVisibleInStackTrace(raw_frame, *caller, &seen_caller)) {
    377       JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
    378       // Set initial size to the maximum inlining level + 1 for the outermost
    379       // function.
    380       List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
    381       frame->Summarize(&frames);
    382       for (int i = frames.length() - 1; i >= 0; i--) {
    383         Handle<JSFunction> fun = frames[i].function();
    384         // Filter out frames from other security contexts.
    385         if (!this->context()->HasSameSecurityTokenAs(fun->context())) continue;
    386         if (cursor + 4 > elements->length()) {
    387           int new_capacity = JSObject::NewElementsCapacity(elements->length());
    388           Handle<FixedArray> new_elements =
    389               factory()->NewFixedArrayWithHoles(new_capacity);
    390           for (int i = 0; i < cursor; i++) {
    391             new_elements->set(i, elements->get(i));
    392           }
    393           elements = new_elements;
    394         }
    395         ASSERT(cursor + 4 <= elements->length());
    396 
    397         Handle<Object> recv = frames[i].receiver();
    398         Handle<Code> code = frames[i].code();
    399         Handle<Smi> offset(Smi::FromInt(frames[i].offset()), this);
    400         // The stack trace API should not expose receivers and function
    401         // objects on frames deeper than the top-most one with a strict
    402         // mode function.  The number of sloppy frames is stored as
    403         // first element in the result array.
    404         if (!encountered_strict_function) {
    405           if (fun->shared()->strict_mode() == STRICT) {
    406             encountered_strict_function = true;
    407           } else {
    408             sloppy_frames++;
    409           }
    410         }
    411         elements->set(cursor++, *recv);
    412         elements->set(cursor++, *fun);
    413         elements->set(cursor++, *code);
    414         elements->set(cursor++, *offset);
    415       }
    416       frames_seen++;
    417     }
    418   }
    419   elements->set(0, Smi::FromInt(sloppy_frames));
    420   Handle<JSArray> result = factory()->NewJSArrayWithElements(elements);
    421   result->set_length(Smi::FromInt(cursor));
    422   return result;
    423 }
    424 
    425 
    426 void Isolate::CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object) {
    427   if (capture_stack_trace_for_uncaught_exceptions_) {
    428     // Capture stack trace for a detailed exception message.
    429     Handle<String> key = factory()->hidden_stack_trace_string();
    430     Handle<JSArray> stack_trace = CaptureCurrentStackTrace(
    431         stack_trace_for_uncaught_exceptions_frame_limit_,
    432         stack_trace_for_uncaught_exceptions_options_);
    433     JSObject::SetHiddenProperty(error_object, key, stack_trace);
    434   }
    435 }
    436 
    437 
    438 Handle<JSArray> Isolate::CaptureCurrentStackTrace(
    439     int frame_limit, StackTrace::StackTraceOptions options) {
    440   // Ensure no negative values.
    441   int limit = Max(frame_limit, 0);
    442   Handle<JSArray> stack_trace = factory()->NewJSArray(frame_limit);
    443 
    444   Handle<String> column_key =
    445       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("column"));
    446   Handle<String> line_key =
    447       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("lineNumber"));
    448   Handle<String> script_id_key =
    449       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("scriptId"));
    450   Handle<String> script_name_key =
    451       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("scriptName"));
    452   Handle<String> script_name_or_source_url_key =
    453       factory()->InternalizeOneByteString(
    454           STATIC_ASCII_VECTOR("scriptNameOrSourceURL"));
    455   Handle<String> function_key =
    456       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("functionName"));
    457   Handle<String> eval_key =
    458       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("isEval"));
    459   Handle<String> constructor_key =
    460       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("isConstructor"));
    461 
    462   StackTraceFrameIterator it(this);
    463   int frames_seen = 0;
    464   while (!it.done() && (frames_seen < limit)) {
    465     JavaScriptFrame* frame = it.frame();
    466     // Set initial size to the maximum inlining level + 1 for the outermost
    467     // function.
    468     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
    469     frame->Summarize(&frames);
    470     for (int i = frames.length() - 1; i >= 0 && frames_seen < limit; i--) {
    471       Handle<JSFunction> fun = frames[i].function();
    472       // Filter frames from other security contexts.
    473       if (!(options & StackTrace::kExposeFramesAcrossSecurityOrigins) &&
    474           !this->context()->HasSameSecurityTokenAs(fun->context())) continue;
    475 
    476       // Create a JSObject to hold the information for the StackFrame.
    477       Handle<JSObject> stack_frame = factory()->NewJSObject(object_function());
    478 
    479       Handle<Script> script(Script::cast(fun->shared()->script()));
    480 
    481       if (options & StackTrace::kLineNumber) {
    482         int script_line_offset = script->line_offset()->value();
    483         int position = frames[i].code()->SourcePosition(frames[i].pc());
    484         int line_number = Script::GetLineNumber(script, position);
    485         // line_number is already shifted by the script_line_offset.
    486         int relative_line_number = line_number - script_line_offset;
    487         if (options & StackTrace::kColumnOffset && relative_line_number >= 0) {
    488           Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
    489           int start = (relative_line_number == 0) ? 0 :
    490               Smi::cast(line_ends->get(relative_line_number - 1))->value() + 1;
    491           int column_offset = position - start;
    492           if (relative_line_number == 0) {
    493             // For the case where the code is on the same line as the script
    494             // tag.
    495             column_offset += script->column_offset()->value();
    496           }
    497           JSObject::SetOwnPropertyIgnoreAttributes(
    498               stack_frame, column_key,
    499               Handle<Smi>(Smi::FromInt(column_offset + 1), this), NONE).Check();
    500         }
    501        JSObject::SetOwnPropertyIgnoreAttributes(
    502             stack_frame, line_key,
    503             Handle<Smi>(Smi::FromInt(line_number + 1), this), NONE).Check();
    504       }
    505 
    506       if (options & StackTrace::kScriptId) {
    507         Handle<Smi> script_id(script->id(), this);
    508         JSObject::SetOwnPropertyIgnoreAttributes(
    509             stack_frame, script_id_key, script_id, NONE).Check();
    510       }
    511 
    512       if (options & StackTrace::kScriptName) {
    513         Handle<Object> script_name(script->name(), this);
    514         JSObject::SetOwnPropertyIgnoreAttributes(
    515             stack_frame, script_name_key, script_name, NONE).Check();
    516       }
    517 
    518       if (options & StackTrace::kScriptNameOrSourceURL) {
    519         Handle<Object> result = Script::GetNameOrSourceURL(script);
    520         JSObject::SetOwnPropertyIgnoreAttributes(
    521             stack_frame, script_name_or_source_url_key, result, NONE).Check();
    522       }
    523 
    524       if (options & StackTrace::kFunctionName) {
    525         Handle<Object> fun_name(fun->shared()->name(), this);
    526         if (!fun_name->BooleanValue()) {
    527           fun_name = Handle<Object>(fun->shared()->inferred_name(), this);
    528         }
    529         JSObject::SetOwnPropertyIgnoreAttributes(
    530             stack_frame, function_key, fun_name, NONE).Check();
    531       }
    532 
    533       if (options & StackTrace::kIsEval) {
    534         Handle<Object> is_eval =
    535             script->compilation_type() == Script::COMPILATION_TYPE_EVAL ?
    536                 factory()->true_value() : factory()->false_value();
    537         JSObject::SetOwnPropertyIgnoreAttributes(
    538             stack_frame, eval_key, is_eval, NONE).Check();
    539       }
    540 
    541       if (options & StackTrace::kIsConstructor) {
    542         Handle<Object> is_constructor = (frames[i].is_constructor()) ?
    543             factory()->true_value() : factory()->false_value();
    544         JSObject::SetOwnPropertyIgnoreAttributes(
    545             stack_frame, constructor_key, is_constructor, NONE).Check();
    546       }
    547 
    548       FixedArray::cast(stack_trace->elements())->set(frames_seen, *stack_frame);
    549       frames_seen++;
    550     }
    551     it.Advance();
    552   }
    553 
    554   stack_trace->set_length(Smi::FromInt(frames_seen));
    555   return stack_trace;
    556 }
    557 
    558 
    559 void Isolate::PrintStack(FILE* out) {
    560   if (stack_trace_nesting_level_ == 0) {
    561     stack_trace_nesting_level_++;
    562     StringStream::ClearMentionedObjectCache(this);
    563     HeapStringAllocator allocator;
    564     StringStream accumulator(&allocator);
    565     incomplete_message_ = &accumulator;
    566     PrintStack(&accumulator);
    567     accumulator.OutputToFile(out);
    568     InitializeLoggingAndCounters();
    569     accumulator.Log(this);
    570     incomplete_message_ = NULL;
    571     stack_trace_nesting_level_ = 0;
    572   } else if (stack_trace_nesting_level_ == 1) {
    573     stack_trace_nesting_level_++;
    574     OS::PrintError(
    575       "\n\nAttempt to print stack while printing stack (double fault)\n");
    576     OS::PrintError(
    577       "If you are lucky you may find a partial stack dump on stdout.\n\n");
    578     incomplete_message_->OutputToFile(out);
    579   }
    580 }
    581 
    582 
    583 static void PrintFrames(Isolate* isolate,
    584                         StringStream* accumulator,
    585                         StackFrame::PrintMode mode) {
    586   StackFrameIterator it(isolate);
    587   for (int i = 0; !it.done(); it.Advance()) {
    588     it.frame()->Print(accumulator, mode, i++);
    589   }
    590 }
    591 
    592 
    593 void Isolate::PrintStack(StringStream* accumulator) {
    594   if (!IsInitialized()) {
    595     accumulator->Add(
    596         "\n==== JS stack trace is not available =======================\n\n");
    597     accumulator->Add(
    598         "\n==== Isolate for the thread is not initialized =============\n\n");
    599     return;
    600   }
    601   // The MentionedObjectCache is not GC-proof at the moment.
    602   DisallowHeapAllocation no_gc;
    603   ASSERT(StringStream::IsMentionedObjectCacheClear(this));
    604 
    605   // Avoid printing anything if there are no frames.
    606   if (c_entry_fp(thread_local_top()) == 0) return;
    607 
    608   accumulator->Add(
    609       "\n==== JS stack trace =========================================\n\n");
    610   PrintFrames(this, accumulator, StackFrame::OVERVIEW);
    611 
    612   accumulator->Add(
    613       "\n==== Details ================================================\n\n");
    614   PrintFrames(this, accumulator, StackFrame::DETAILS);
    615 
    616   accumulator->PrintMentionedObjectCache(this);
    617   accumulator->Add("=====================\n\n");
    618 }
    619 
    620 
    621 void Isolate::SetFailedAccessCheckCallback(
    622     v8::FailedAccessCheckCallback callback) {
    623   thread_local_top()->failed_access_check_callback_ = callback;
    624 }
    625 
    626 
    627 static inline AccessCheckInfo* GetAccessCheckInfo(Isolate* isolate,
    628                                                   Handle<JSObject> receiver) {
    629   JSFunction* constructor = JSFunction::cast(receiver->map()->constructor());
    630   if (!constructor->shared()->IsApiFunction()) return NULL;
    631 
    632   Object* data_obj =
    633      constructor->shared()->get_api_func_data()->access_check_info();
    634   if (data_obj == isolate->heap()->undefined_value()) return NULL;
    635 
    636   return AccessCheckInfo::cast(data_obj);
    637 }
    638 
    639 
    640 void Isolate::ReportFailedAccessCheck(Handle<JSObject> receiver,
    641                                       v8::AccessType type) {
    642   if (!thread_local_top()->failed_access_check_callback_) return;
    643 
    644   ASSERT(receiver->IsAccessCheckNeeded());
    645   ASSERT(context());
    646 
    647   // Get the data object from access check info.
    648   HandleScope scope(this);
    649   Handle<Object> data;
    650   { DisallowHeapAllocation no_gc;
    651     AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
    652     if (!access_check_info) return;
    653     data = handle(access_check_info->data(), this);
    654   }
    655 
    656   // Leaving JavaScript.
    657   VMState<EXTERNAL> state(this);
    658   thread_local_top()->failed_access_check_callback_(
    659       v8::Utils::ToLocal(receiver),
    660       type,
    661       v8::Utils::ToLocal(data));
    662 }
    663 
    664 
    665 enum MayAccessDecision {
    666   YES, NO, UNKNOWN
    667 };
    668 
    669 
    670 static MayAccessDecision MayAccessPreCheck(Isolate* isolate,
    671                                            Handle<JSObject> receiver,
    672                                            v8::AccessType type) {
    673   DisallowHeapAllocation no_gc;
    674   // During bootstrapping, callback functions are not enabled yet.
    675   if (isolate->bootstrapper()->IsActive()) return YES;
    676 
    677   if (receiver->IsJSGlobalProxy()) {
    678     Object* receiver_context = JSGlobalProxy::cast(*receiver)->native_context();
    679     if (!receiver_context->IsContext()) return NO;
    680 
    681     // Get the native context of current top context.
    682     // avoid using Isolate::native_context() because it uses Handle.
    683     Context* native_context =
    684         isolate->context()->global_object()->native_context();
    685     if (receiver_context == native_context) return YES;
    686 
    687     if (Context::cast(receiver_context)->security_token() ==
    688         native_context->security_token())
    689       return YES;
    690   }
    691 
    692   return UNKNOWN;
    693 }
    694 
    695 
    696 bool Isolate::MayNamedAccess(Handle<JSObject> receiver,
    697                              Handle<Object> key,
    698                              v8::AccessType type) {
    699   ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
    700 
    701   // Skip checks for hidden properties access.  Note, we do not
    702   // require existence of a context in this case.
    703   if (key.is_identical_to(factory()->hidden_string())) return true;
    704 
    705   // Check for compatibility between the security tokens in the
    706   // current lexical context and the accessed object.
    707   ASSERT(context());
    708 
    709   MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
    710   if (decision != UNKNOWN) return decision == YES;
    711 
    712   HandleScope scope(this);
    713   Handle<Object> data;
    714   v8::NamedSecurityCallback callback;
    715   { DisallowHeapAllocation no_gc;
    716     AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
    717     if (!access_check_info) return false;
    718     Object* fun_obj = access_check_info->named_callback();
    719     callback = v8::ToCData<v8::NamedSecurityCallback>(fun_obj);
    720     if (!callback) return false;
    721     data = handle(access_check_info->data(), this);
    722   }
    723 
    724   LOG(this, ApiNamedSecurityCheck(*key));
    725 
    726   // Leaving JavaScript.
    727   VMState<EXTERNAL> state(this);
    728   return callback(v8::Utils::ToLocal(receiver),
    729                   v8::Utils::ToLocal(key),
    730                   type,
    731                   v8::Utils::ToLocal(data));
    732 }
    733 
    734 
    735 bool Isolate::MayIndexedAccess(Handle<JSObject> receiver,
    736                                uint32_t index,
    737                                v8::AccessType type) {
    738   ASSERT(receiver->IsJSGlobalProxy() || receiver->IsAccessCheckNeeded());
    739   // Check for compatibility between the security tokens in the
    740   // current lexical context and the accessed object.
    741   ASSERT(context());
    742 
    743   MayAccessDecision decision = MayAccessPreCheck(this, receiver, type);
    744   if (decision != UNKNOWN) return decision == YES;
    745 
    746   HandleScope scope(this);
    747   Handle<Object> data;
    748   v8::IndexedSecurityCallback callback;
    749   { DisallowHeapAllocation no_gc;
    750     // Get named access check callback
    751     AccessCheckInfo* access_check_info = GetAccessCheckInfo(this, receiver);
    752     if (!access_check_info) return false;
    753     Object* fun_obj = access_check_info->indexed_callback();
    754     callback = v8::ToCData<v8::IndexedSecurityCallback>(fun_obj);
    755     if (!callback) return false;
    756     data = handle(access_check_info->data(), this);
    757   }
    758 
    759   LOG(this, ApiIndexedSecurityCheck(index));
    760 
    761   // Leaving JavaScript.
    762   VMState<EXTERNAL> state(this);
    763   return callback(
    764       v8::Utils::ToLocal(receiver), index, type, v8::Utils::ToLocal(data));
    765 }
    766 
    767 
    768 const char* const Isolate::kStackOverflowMessage =
    769   "Uncaught RangeError: Maximum call stack size exceeded";
    770 
    771 
    772 Object* Isolate::StackOverflow() {
    773   HandleScope scope(this);
    774   // At this point we cannot create an Error object using its javascript
    775   // constructor.  Instead, we copy the pre-constructed boilerplate and
    776   // attach the stack trace as a hidden property.
    777   Handle<String> key = factory()->stack_overflow_string();
    778   Handle<JSObject> boilerplate = Handle<JSObject>::cast(
    779       Object::GetProperty(js_builtins_object(), key).ToHandleChecked());
    780   Handle<JSObject> exception = factory()->CopyJSObject(boilerplate);
    781   DoThrow(*exception, NULL);
    782 
    783   // Get stack trace limit.
    784   Handle<Object> error = Object::GetProperty(
    785       this, js_builtins_object(), "$Error").ToHandleChecked();
    786   if (!error->IsJSObject()) return heap()->exception();
    787 
    788   Handle<String> stackTraceLimit =
    789       factory()->InternalizeUtf8String("stackTraceLimit");
    790   ASSERT(!stackTraceLimit.is_null());
    791   Handle<Object> stack_trace_limit =
    792       JSObject::GetDataProperty(Handle<JSObject>::cast(error),
    793                                 stackTraceLimit);
    794   if (!stack_trace_limit->IsNumber()) return heap()->exception();
    795   double dlimit = stack_trace_limit->Number();
    796   int limit = std::isnan(dlimit) ? 0 : static_cast<int>(dlimit);
    797 
    798   Handle<JSArray> stack_trace = CaptureSimpleStackTrace(
    799       exception, factory()->undefined_value(), limit);
    800   JSObject::SetHiddenProperty(exception,
    801                               factory()->hidden_stack_trace_string(),
    802                               stack_trace);
    803   return heap()->exception();
    804 }
    805 
    806 
    807 Object* Isolate::TerminateExecution() {
    808   DoThrow(heap_.termination_exception(), NULL);
    809   return heap()->exception();
    810 }
    811 
    812 
    813 void Isolate::CancelTerminateExecution() {
    814   if (try_catch_handler()) {
    815     try_catch_handler()->has_terminated_ = false;
    816   }
    817   if (has_pending_exception() &&
    818       pending_exception() == heap_.termination_exception()) {
    819     thread_local_top()->external_caught_exception_ = false;
    820     clear_pending_exception();
    821   }
    822   if (has_scheduled_exception() &&
    823       scheduled_exception() == heap_.termination_exception()) {
    824     thread_local_top()->external_caught_exception_ = false;
    825     clear_scheduled_exception();
    826   }
    827 }
    828 
    829 
    830 void Isolate::InvokeApiInterruptCallback() {
    831   // Note: callback below should be called outside of execution access lock.
    832   InterruptCallback callback = NULL;
    833   void* data = NULL;
    834   {
    835     ExecutionAccess access(this);
    836     callback = api_interrupt_callback_;
    837     data = api_interrupt_callback_data_;
    838     api_interrupt_callback_ = NULL;
    839     api_interrupt_callback_data_ = NULL;
    840   }
    841 
    842   if (callback != NULL) {
    843     VMState<EXTERNAL> state(this);
    844     HandleScope handle_scope(this);
    845     callback(reinterpret_cast<v8::Isolate*>(this), data);
    846   }
    847 }
    848 
    849 
    850 Object* Isolate::Throw(Object* exception, MessageLocation* location) {
    851   DoThrow(exception, location);
    852   return heap()->exception();
    853 }
    854 
    855 
    856 Object* Isolate::ReThrow(Object* exception) {
    857   bool can_be_caught_externally = false;
    858   bool catchable_by_javascript = is_catchable_by_javascript(exception);
    859   ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
    860 
    861   thread_local_top()->catcher_ = can_be_caught_externally ?
    862       try_catch_handler() : NULL;
    863 
    864   // Set the exception being re-thrown.
    865   set_pending_exception(exception);
    866   return heap()->exception();
    867 }
    868 
    869 
    870 Object* Isolate::ThrowIllegalOperation() {
    871   if (FLAG_stack_trace_on_illegal) PrintStack(stdout);
    872   return Throw(heap_.illegal_access_string());
    873 }
    874 
    875 
    876 Object* Isolate::ThrowInvalidStringLength() {
    877   return Throw(*factory()->NewRangeError(
    878       "invalid_string_length", HandleVector<Object>(NULL, 0)));
    879 }
    880 
    881 
    882 void Isolate::ScheduleThrow(Object* exception) {
    883   // When scheduling a throw we first throw the exception to get the
    884   // error reporting if it is uncaught before rescheduling it.
    885   Throw(exception);
    886   PropagatePendingExceptionToExternalTryCatch();
    887   if (has_pending_exception()) {
    888     thread_local_top()->scheduled_exception_ = pending_exception();
    889     thread_local_top()->external_caught_exception_ = false;
    890     clear_pending_exception();
    891   }
    892 }
    893 
    894 
    895 void Isolate::RestorePendingMessageFromTryCatch(v8::TryCatch* handler) {
    896   ASSERT(handler == try_catch_handler());
    897   ASSERT(handler->HasCaught());
    898   ASSERT(handler->rethrow_);
    899   ASSERT(handler->capture_message_);
    900   Object* message = reinterpret_cast<Object*>(handler->message_obj_);
    901   Object* script = reinterpret_cast<Object*>(handler->message_script_);
    902   ASSERT(message->IsJSMessageObject() || message->IsTheHole());
    903   ASSERT(script->IsScript() || script->IsTheHole());
    904   thread_local_top()->pending_message_obj_ = message;
    905   thread_local_top()->pending_message_script_ = script;
    906   thread_local_top()->pending_message_start_pos_ = handler->message_start_pos_;
    907   thread_local_top()->pending_message_end_pos_ = handler->message_end_pos_;
    908 }
    909 
    910 
    911 Object* Isolate::PromoteScheduledException() {
    912   Object* thrown = scheduled_exception();
    913   clear_scheduled_exception();
    914   // Re-throw the exception to avoid getting repeated error reporting.
    915   return ReThrow(thrown);
    916 }
    917 
    918 
    919 void Isolate::PrintCurrentStackTrace(FILE* out) {
    920   StackTraceFrameIterator it(this);
    921   while (!it.done()) {
    922     HandleScope scope(this);
    923     // Find code position if recorded in relocation info.
    924     JavaScriptFrame* frame = it.frame();
    925     int pos = frame->LookupCode()->SourcePosition(frame->pc());
    926     Handle<Object> pos_obj(Smi::FromInt(pos), this);
    927     // Fetch function and receiver.
    928     Handle<JSFunction> fun(frame->function());
    929     Handle<Object> recv(frame->receiver(), this);
    930     // Advance to the next JavaScript frame and determine if the
    931     // current frame is the top-level frame.
    932     it.Advance();
    933     Handle<Object> is_top_level = it.done()
    934         ? factory()->true_value()
    935         : factory()->false_value();
    936     // Generate and print stack trace line.
    937     Handle<String> line =
    938         Execution::GetStackTraceLine(recv, fun, pos_obj, is_top_level);
    939     if (line->length() > 0) {
    940       line->PrintOn(out);
    941       PrintF(out, "\n");
    942     }
    943   }
    944 }
    945 
    946 
    947 void Isolate::ComputeLocation(MessageLocation* target) {
    948   *target = MessageLocation(Handle<Script>(heap_.empty_script()), -1, -1);
    949   StackTraceFrameIterator it(this);
    950   if (!it.done()) {
    951     JavaScriptFrame* frame = it.frame();
    952     JSFunction* fun = frame->function();
    953     Object* script = fun->shared()->script();
    954     if (script->IsScript() &&
    955         !(Script::cast(script)->source()->IsUndefined())) {
    956       int pos = frame->LookupCode()->SourcePosition(frame->pc());
    957       // Compute the location from the function and the reloc info.
    958       Handle<Script> casted_script(Script::cast(script));
    959       *target = MessageLocation(casted_script, pos, pos + 1);
    960     }
    961   }
    962 }
    963 
    964 
    965 bool Isolate::ShouldReportException(bool* can_be_caught_externally,
    966                                     bool catchable_by_javascript) {
    967   // Find the top-most try-catch handler.
    968   StackHandler* handler =
    969       StackHandler::FromAddress(Isolate::handler(thread_local_top()));
    970   while (handler != NULL && !handler->is_catch()) {
    971     handler = handler->next();
    972   }
    973 
    974   // Get the address of the external handler so we can compare the address to
    975   // determine which one is closer to the top of the stack.
    976   Address external_handler_address =
    977       thread_local_top()->try_catch_handler_address();
    978 
    979   // The exception has been externally caught if and only if there is
    980   // an external handler which is on top of the top-most try-catch
    981   // handler.
    982   *can_be_caught_externally = external_handler_address != NULL &&
    983       (handler == NULL || handler->address() > external_handler_address ||
    984        !catchable_by_javascript);
    985 
    986   if (*can_be_caught_externally) {
    987     // Only report the exception if the external handler is verbose.
    988     return try_catch_handler()->is_verbose_;
    989   } else {
    990     // Report the exception if it isn't caught by JavaScript code.
    991     return handler == NULL;
    992   }
    993 }
    994 
    995 
    996 bool Isolate::IsErrorObject(Handle<Object> obj) {
    997   if (!obj->IsJSObject()) return false;
    998 
    999   Handle<String> error_key =
   1000       factory()->InternalizeOneByteString(STATIC_ASCII_VECTOR("$Error"));
   1001   Handle<Object> error_constructor = Object::GetProperty(
   1002       js_builtins_object(), error_key).ToHandleChecked();
   1003 
   1004   DisallowHeapAllocation no_gc;
   1005   for (Object* prototype = *obj; !prototype->IsNull();
   1006        prototype = prototype->GetPrototype(this)) {
   1007     if (!prototype->IsJSObject()) return false;
   1008     if (JSObject::cast(prototype)->map()->constructor() ==
   1009         *error_constructor) {
   1010       return true;
   1011     }
   1012   }
   1013   return false;
   1014 }
   1015 
   1016 static int fatal_exception_depth = 0;
   1017 
   1018 void Isolate::DoThrow(Object* exception, MessageLocation* location) {
   1019   ASSERT(!has_pending_exception());
   1020 
   1021   HandleScope scope(this);
   1022   Handle<Object> exception_handle(exception, this);
   1023 
   1024   // Determine reporting and whether the exception is caught externally.
   1025   bool catchable_by_javascript = is_catchable_by_javascript(exception);
   1026   bool can_be_caught_externally = false;
   1027   bool should_report_exception =
   1028       ShouldReportException(&can_be_caught_externally, catchable_by_javascript);
   1029   bool report_exception = catchable_by_javascript && should_report_exception;
   1030   bool try_catch_needs_message =
   1031       can_be_caught_externally && try_catch_handler()->capture_message_ &&
   1032       !thread_local_top()->rethrowing_message_;
   1033   bool bootstrapping = bootstrapper()->IsActive();
   1034 
   1035   thread_local_top()->rethrowing_message_ = false;
   1036 
   1037   // Notify debugger of exception.
   1038   if (catchable_by_javascript) {
   1039     debug()->OnException(exception_handle, report_exception);
   1040   }
   1041 
   1042   // Generate the message if required.
   1043   if (report_exception || try_catch_needs_message) {
   1044     MessageLocation potential_computed_location;
   1045     if (location == NULL) {
   1046       // If no location was specified we use a computed one instead.
   1047       ComputeLocation(&potential_computed_location);
   1048       location = &potential_computed_location;
   1049     }
   1050     // It's not safe to try to make message objects or collect stack traces
   1051     // while the bootstrapper is active since the infrastructure may not have
   1052     // been properly initialized.
   1053     if (!bootstrapping) {
   1054       Handle<JSArray> stack_trace_object;
   1055       if (capture_stack_trace_for_uncaught_exceptions_) {
   1056         if (IsErrorObject(exception_handle)) {
   1057           // We fetch the stack trace that corresponds to this error object.
   1058           Handle<String> key = factory()->hidden_stack_trace_string();
   1059           Object* stack_property =
   1060               JSObject::cast(*exception_handle)->GetHiddenProperty(key);
   1061           // Property lookup may have failed.  In this case it's probably not
   1062           // a valid Error object.
   1063           if (stack_property->IsJSArray()) {
   1064             stack_trace_object = Handle<JSArray>(JSArray::cast(stack_property));
   1065           }
   1066         }
   1067         if (stack_trace_object.is_null()) {
   1068           // Not an error object, we capture at throw site.
   1069           stack_trace_object = CaptureCurrentStackTrace(
   1070               stack_trace_for_uncaught_exceptions_frame_limit_,
   1071               stack_trace_for_uncaught_exceptions_options_);
   1072         }
   1073       }
   1074 
   1075       Handle<Object> exception_arg = exception_handle;
   1076       // If the exception argument is a custom object, turn it into a string
   1077       // before throwing as uncaught exception.  Note that the pending
   1078       // exception object to be set later must not be turned into a string.
   1079       if (exception_arg->IsJSObject() && !IsErrorObject(exception_arg)) {
   1080         MaybeHandle<Object> maybe_exception =
   1081             Execution::ToDetailString(this, exception_arg);
   1082         if (!maybe_exception.ToHandle(&exception_arg)) {
   1083           exception_arg = factory()->InternalizeOneByteString(
   1084               STATIC_ASCII_VECTOR("exception"));
   1085         }
   1086       }
   1087       Handle<Object> message_obj = MessageHandler::MakeMessageObject(
   1088           this,
   1089           "uncaught_exception",
   1090           location,
   1091           HandleVector<Object>(&exception_arg, 1),
   1092           stack_trace_object);
   1093       thread_local_top()->pending_message_obj_ = *message_obj;
   1094       if (location != NULL) {
   1095         thread_local_top()->pending_message_script_ = *location->script();
   1096         thread_local_top()->pending_message_start_pos_ = location->start_pos();
   1097         thread_local_top()->pending_message_end_pos_ = location->end_pos();
   1098       }
   1099 
   1100       // If the abort-on-uncaught-exception flag is specified, abort on any
   1101       // exception not caught by JavaScript, even when an external handler is
   1102       // present.  This flag is intended for use by JavaScript developers, so
   1103       // print a user-friendly stack trace (not an internal one).
   1104       if (fatal_exception_depth == 0 &&
   1105           FLAG_abort_on_uncaught_exception &&
   1106           (report_exception || can_be_caught_externally)) {
   1107         fatal_exception_depth++;
   1108         PrintF(stderr,
   1109                "%s\n\nFROM\n",
   1110                MessageHandler::GetLocalizedMessage(this, message_obj).get());
   1111         PrintCurrentStackTrace(stderr);
   1112         OS::Abort();
   1113       }
   1114     } else if (location != NULL && !location->script().is_null()) {
   1115       // We are bootstrapping and caught an error where the location is set
   1116       // and we have a script for the location.
   1117       // In this case we could have an extension (or an internal error
   1118       // somewhere) and we print out the line number at which the error occured
   1119       // to the console for easier debugging.
   1120       int line_number =
   1121           location->script()->GetLineNumber(location->start_pos()) + 1;
   1122       if (exception->IsString() && location->script()->name()->IsString()) {
   1123         OS::PrintError(
   1124             "Extension or internal compilation error: %s in %s at line %d.\n",
   1125             String::cast(exception)->ToCString().get(),
   1126             String::cast(location->script()->name())->ToCString().get(),
   1127             line_number);
   1128       } else if (location->script()->name()->IsString()) {
   1129         OS::PrintError(
   1130             "Extension or internal compilation error in %s at line %d.\n",
   1131             String::cast(location->script()->name())->ToCString().get(),
   1132             line_number);
   1133       } else {
   1134         OS::PrintError("Extension or internal compilation error.\n");
   1135       }
   1136 #ifdef OBJECT_PRINT
   1137       // Since comments and empty lines have been stripped from the source of
   1138       // builtins, print the actual source here so that line numbers match.
   1139       if (location->script()->source()->IsString()) {
   1140         Handle<String> src(String::cast(location->script()->source()));
   1141         PrintF("Failing script:\n");
   1142         int len = src->length();
   1143         int line_number = 1;
   1144         PrintF("%5d: ", line_number);
   1145         for (int i = 0; i < len; i++) {
   1146           uint16_t character = src->Get(i);
   1147           PrintF("%c", character);
   1148           if (character == '\n' && i < len - 2) {
   1149             PrintF("%5d: ", ++line_number);
   1150           }
   1151         }
   1152       }
   1153 #endif
   1154     }
   1155   }
   1156 
   1157   // Save the message for reporting if the the exception remains uncaught.
   1158   thread_local_top()->has_pending_message_ = report_exception;
   1159 
   1160   // Do not forget to clean catcher_ if currently thrown exception cannot
   1161   // be caught.  If necessary, ReThrow will update the catcher.
   1162   thread_local_top()->catcher_ = can_be_caught_externally ?
   1163       try_catch_handler() : NULL;
   1164 
   1165   set_pending_exception(*exception_handle);
   1166 }
   1167 
   1168 
   1169 bool Isolate::HasExternalTryCatch() {
   1170   ASSERT(has_pending_exception());
   1171 
   1172   return (thread_local_top()->catcher_ != NULL) &&
   1173       (try_catch_handler() == thread_local_top()->catcher_);
   1174 }
   1175 
   1176 
   1177 bool Isolate::IsFinallyOnTop() {
   1178   // Get the address of the external handler so we can compare the address to
   1179   // determine which one is closer to the top of the stack.
   1180   Address external_handler_address =
   1181       thread_local_top()->try_catch_handler_address();
   1182   ASSERT(external_handler_address != NULL);
   1183 
   1184   // The exception has been externally caught if and only if there is
   1185   // an external handler which is on top of the top-most try-finally
   1186   // handler.
   1187   // There should be no try-catch blocks as they would prohibit us from
   1188   // finding external catcher in the first place (see catcher_ check above).
   1189   //
   1190   // Note, that finally clause would rethrow an exception unless it's
   1191   // aborted by jumps in control flow like return, break, etc. and we'll
   1192   // have another chances to set proper v8::TryCatch.
   1193   StackHandler* handler =
   1194       StackHandler::FromAddress(Isolate::handler(thread_local_top()));
   1195   while (handler != NULL && handler->address() < external_handler_address) {
   1196     ASSERT(!handler->is_catch());
   1197     if (handler->is_finally()) return true;
   1198 
   1199     handler = handler->next();
   1200   }
   1201 
   1202   return false;
   1203 }
   1204 
   1205 
   1206 void Isolate::ReportPendingMessages() {
   1207   ASSERT(has_pending_exception());
   1208   bool can_clear_message = PropagatePendingExceptionToExternalTryCatch();
   1209 
   1210   HandleScope scope(this);
   1211   if (thread_local_top_.pending_exception_ ==
   1212           heap()->termination_exception()) {
   1213     // Do nothing: if needed, the exception has been already propagated to
   1214     // v8::TryCatch.
   1215   } else {
   1216     if (thread_local_top_.has_pending_message_) {
   1217       thread_local_top_.has_pending_message_ = false;
   1218       if (!thread_local_top_.pending_message_obj_->IsTheHole()) {
   1219         HandleScope scope(this);
   1220         Handle<Object> message_obj(thread_local_top_.pending_message_obj_,
   1221                                    this);
   1222         if (!thread_local_top_.pending_message_script_->IsTheHole()) {
   1223           Handle<Script> script(
   1224               Script::cast(thread_local_top_.pending_message_script_));
   1225           int start_pos = thread_local_top_.pending_message_start_pos_;
   1226           int end_pos = thread_local_top_.pending_message_end_pos_;
   1227           MessageLocation location(script, start_pos, end_pos);
   1228           MessageHandler::ReportMessage(this, &location, message_obj);
   1229         } else {
   1230           MessageHandler::ReportMessage(this, NULL, message_obj);
   1231         }
   1232       }
   1233     }
   1234   }
   1235   if (can_clear_message) clear_pending_message();
   1236 }
   1237 
   1238 
   1239 MessageLocation Isolate::GetMessageLocation() {
   1240   ASSERT(has_pending_exception());
   1241 
   1242   if (thread_local_top_.pending_exception_ != heap()->termination_exception() &&
   1243       thread_local_top_.has_pending_message_ &&
   1244       !thread_local_top_.pending_message_obj_->IsTheHole() &&
   1245       !thread_local_top_.pending_message_obj_->IsTheHole()) {
   1246     Handle<Script> script(
   1247         Script::cast(thread_local_top_.pending_message_script_));
   1248     int start_pos = thread_local_top_.pending_message_start_pos_;
   1249     int end_pos = thread_local_top_.pending_message_end_pos_;
   1250     return MessageLocation(script, start_pos, end_pos);
   1251   }
   1252 
   1253   return MessageLocation();
   1254 }
   1255 
   1256 
   1257 bool Isolate::OptionalRescheduleException(bool is_bottom_call) {
   1258   ASSERT(has_pending_exception());
   1259   PropagatePendingExceptionToExternalTryCatch();
   1260 
   1261   bool is_termination_exception =
   1262       pending_exception() == heap_.termination_exception();
   1263 
   1264   // Do not reschedule the exception if this is the bottom call.
   1265   bool clear_exception = is_bottom_call;
   1266 
   1267   if (is_termination_exception) {
   1268     if (is_bottom_call) {
   1269       thread_local_top()->external_caught_exception_ = false;
   1270       clear_pending_exception();
   1271       return false;
   1272     }
   1273   } else if (thread_local_top()->external_caught_exception_) {
   1274     // If the exception is externally caught, clear it if there are no
   1275     // JavaScript frames on the way to the C++ frame that has the
   1276     // external handler.
   1277     ASSERT(thread_local_top()->try_catch_handler_address() != NULL);
   1278     Address external_handler_address =
   1279         thread_local_top()->try_catch_handler_address();
   1280     JavaScriptFrameIterator it(this);
   1281     if (it.done() || (it.frame()->sp() > external_handler_address)) {
   1282       clear_exception = true;
   1283     }
   1284   }
   1285 
   1286   // Clear the exception if needed.
   1287   if (clear_exception) {
   1288     thread_local_top()->external_caught_exception_ = false;
   1289     clear_pending_exception();
   1290     return false;
   1291   }
   1292 
   1293   // Reschedule the exception.
   1294   thread_local_top()->scheduled_exception_ = pending_exception();
   1295   clear_pending_exception();
   1296   return true;
   1297 }
   1298 
   1299 
   1300 void Isolate::SetCaptureStackTraceForUncaughtExceptions(
   1301       bool capture,
   1302       int frame_limit,
   1303       StackTrace::StackTraceOptions options) {
   1304   capture_stack_trace_for_uncaught_exceptions_ = capture;
   1305   stack_trace_for_uncaught_exceptions_frame_limit_ = frame_limit;
   1306   stack_trace_for_uncaught_exceptions_options_ = options;
   1307 }
   1308 
   1309 
   1310 Handle<Context> Isolate::native_context() {
   1311   return Handle<Context>(context()->global_object()->native_context());
   1312 }
   1313 
   1314 
   1315 Handle<Context> Isolate::global_context() {
   1316   return Handle<Context>(context()->global_object()->global_context());
   1317 }
   1318 
   1319 
   1320 Handle<Context> Isolate::GetCallingNativeContext() {
   1321   JavaScriptFrameIterator it(this);
   1322   if (debug_->in_debug_scope()) {
   1323     while (!it.done()) {
   1324       JavaScriptFrame* frame = it.frame();
   1325       Context* context = Context::cast(frame->context());
   1326       if (context->native_context() == *debug_->debug_context()) {
   1327         it.Advance();
   1328       } else {
   1329         break;
   1330       }
   1331     }
   1332   }
   1333   if (it.done()) return Handle<Context>::null();
   1334   JavaScriptFrame* frame = it.frame();
   1335   Context* context = Context::cast(frame->context());
   1336   return Handle<Context>(context->native_context());
   1337 }
   1338 
   1339 
   1340 char* Isolate::ArchiveThread(char* to) {
   1341   MemCopy(to, reinterpret_cast<char*>(thread_local_top()),
   1342           sizeof(ThreadLocalTop));
   1343   InitializeThreadLocal();
   1344   clear_pending_exception();
   1345   clear_pending_message();
   1346   clear_scheduled_exception();
   1347   return to + sizeof(ThreadLocalTop);
   1348 }
   1349 
   1350 
   1351 char* Isolate::RestoreThread(char* from) {
   1352   MemCopy(reinterpret_cast<char*>(thread_local_top()), from,
   1353           sizeof(ThreadLocalTop));
   1354 // This might be just paranoia, but it seems to be needed in case a
   1355 // thread_local_top_ is restored on a separate OS thread.
   1356 #ifdef USE_SIMULATOR
   1357   thread_local_top()->simulator_ = Simulator::current(this);
   1358 #endif
   1359   ASSERT(context() == NULL || context()->IsContext());
   1360   return from + sizeof(ThreadLocalTop);
   1361 }
   1362 
   1363 
   1364 Isolate::ThreadDataTable::ThreadDataTable()
   1365     : list_(NULL) {
   1366 }
   1367 
   1368 
   1369 Isolate::ThreadDataTable::~ThreadDataTable() {
   1370   // TODO(svenpanne) The assertion below would fire if an embedder does not
   1371   // cleanly dispose all Isolates before disposing v8, so we are conservative
   1372   // and leave it out for now.
   1373   // ASSERT_EQ(NULL, list_);
   1374 }
   1375 
   1376 
   1377 Isolate::PerIsolateThreadData::~PerIsolateThreadData() {
   1378 #if defined(USE_SIMULATOR)
   1379   delete simulator_;
   1380 #endif
   1381 }
   1382 
   1383 
   1384 Isolate::PerIsolateThreadData*
   1385     Isolate::ThreadDataTable::Lookup(Isolate* isolate,
   1386                                      ThreadId thread_id) {
   1387   for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) {
   1388     if (data->Matches(isolate, thread_id)) return data;
   1389   }
   1390   return NULL;
   1391 }
   1392 
   1393 
   1394 void Isolate::ThreadDataTable::Insert(Isolate::PerIsolateThreadData* data) {
   1395   if (list_ != NULL) list_->prev_ = data;
   1396   data->next_ = list_;
   1397   list_ = data;
   1398 }
   1399 
   1400 
   1401 void Isolate::ThreadDataTable::Remove(PerIsolateThreadData* data) {
   1402   if (list_ == data) list_ = data->next_;
   1403   if (data->next_ != NULL) data->next_->prev_ = data->prev_;
   1404   if (data->prev_ != NULL) data->prev_->next_ = data->next_;
   1405   delete data;
   1406 }
   1407 
   1408 
   1409 void Isolate::ThreadDataTable::RemoveAllThreads(Isolate* isolate) {
   1410   PerIsolateThreadData* data = list_;
   1411   while (data != NULL) {
   1412     PerIsolateThreadData* next = data->next_;
   1413     if (data->isolate() == isolate) Remove(data);
   1414     data = next;
   1415   }
   1416 }
   1417 
   1418 
   1419 #ifdef DEBUG
   1420 #define TRACE_ISOLATE(tag)                                              \
   1421   do {                                                                  \
   1422     if (FLAG_trace_isolates) {                                          \
   1423       PrintF("Isolate %p (id %d)" #tag "\n",                            \
   1424              reinterpret_cast<void*>(this), id());                      \
   1425     }                                                                   \
   1426   } while (false)
   1427 #else
   1428 #define TRACE_ISOLATE(tag)
   1429 #endif
   1430 
   1431 
   1432 Isolate::Isolate()
   1433     : embedder_data_(),
   1434       state_(UNINITIALIZED),
   1435       entry_stack_(NULL),
   1436       stack_trace_nesting_level_(0),
   1437       incomplete_message_(NULL),
   1438       bootstrapper_(NULL),
   1439       runtime_profiler_(NULL),
   1440       compilation_cache_(NULL),
   1441       counters_(NULL),
   1442       code_range_(NULL),
   1443       logger_(NULL),
   1444       stats_table_(NULL),
   1445       stub_cache_(NULL),
   1446       code_aging_helper_(NULL),
   1447       deoptimizer_data_(NULL),
   1448       materialized_object_store_(NULL),
   1449       capture_stack_trace_for_uncaught_exceptions_(false),
   1450       stack_trace_for_uncaught_exceptions_frame_limit_(0),
   1451       stack_trace_for_uncaught_exceptions_options_(StackTrace::kOverview),
   1452       memory_allocator_(NULL),
   1453       keyed_lookup_cache_(NULL),
   1454       context_slot_cache_(NULL),
   1455       descriptor_lookup_cache_(NULL),
   1456       handle_scope_implementer_(NULL),
   1457       unicode_cache_(NULL),
   1458       runtime_zone_(this),
   1459       inner_pointer_to_code_cache_(NULL),
   1460       write_iterator_(NULL),
   1461       global_handles_(NULL),
   1462       eternal_handles_(NULL),
   1463       thread_manager_(NULL),
   1464       has_installed_extensions_(false),
   1465       string_tracker_(NULL),
   1466       regexp_stack_(NULL),
   1467       date_cache_(NULL),
   1468       code_stub_interface_descriptors_(NULL),
   1469       call_descriptors_(NULL),
   1470       // TODO(bmeurer) Initialized lazily because it depends on flags; can
   1471       // be fixed once the default isolate cleanup is done.
   1472       random_number_generator_(NULL),
   1473       serializer_enabled_(false),
   1474       has_fatal_error_(false),
   1475       initialized_from_snapshot_(false),
   1476       cpu_profiler_(NULL),
   1477       heap_profiler_(NULL),
   1478       function_entry_hook_(NULL),
   1479       deferred_handles_head_(NULL),
   1480       optimizing_compiler_thread_(NULL),
   1481       sweeper_thread_(NULL),
   1482       num_sweeper_threads_(0),
   1483       stress_deopt_count_(0),
   1484       next_optimization_id_(0) {
   1485   id_ = base::NoBarrier_AtomicIncrement(&isolate_counter_, 1);
   1486   TRACE_ISOLATE(constructor);
   1487 
   1488   memset(isolate_addresses_, 0,
   1489       sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1));
   1490 
   1491   heap_.isolate_ = this;
   1492   stack_guard_.isolate_ = this;
   1493 
   1494   // ThreadManager is initialized early to support locking an isolate
   1495   // before it is entered.
   1496   thread_manager_ = new ThreadManager();
   1497   thread_manager_->isolate_ = this;
   1498 
   1499 #ifdef DEBUG
   1500   // heap_histograms_ initializes itself.
   1501   memset(&js_spill_information_, 0, sizeof(js_spill_information_));
   1502 #endif
   1503 
   1504   handle_scope_data_.Initialize();
   1505 
   1506 #define ISOLATE_INIT_EXECUTE(type, name, initial_value)                        \
   1507   name##_ = (initial_value);
   1508   ISOLATE_INIT_LIST(ISOLATE_INIT_EXECUTE)
   1509 #undef ISOLATE_INIT_EXECUTE
   1510 
   1511 #define ISOLATE_INIT_ARRAY_EXECUTE(type, name, length)                         \
   1512   memset(name##_, 0, sizeof(type) * length);
   1513   ISOLATE_INIT_ARRAY_LIST(ISOLATE_INIT_ARRAY_EXECUTE)
   1514 #undef ISOLATE_INIT_ARRAY_EXECUTE
   1515 
   1516   InitializeLoggingAndCounters();
   1517   debug_ = new Debug(this);
   1518 }
   1519 
   1520 
   1521 void Isolate::TearDown() {
   1522   TRACE_ISOLATE(tear_down);
   1523 
   1524   // Temporarily set this isolate as current so that various parts of
   1525   // the isolate can access it in their destructors without having a
   1526   // direct pointer. We don't use Enter/Exit here to avoid
   1527   // initializing the thread data.
   1528   PerIsolateThreadData* saved_data = CurrentPerIsolateThreadData();
   1529   Isolate* saved_isolate = UncheckedCurrent();
   1530   SetIsolateThreadLocals(this, NULL);
   1531 
   1532   Deinit();
   1533 
   1534   { LockGuard<Mutex> lock_guard(&process_wide_mutex_);
   1535     thread_data_table_->RemoveAllThreads(this);
   1536   }
   1537 
   1538   if (serialize_partial_snapshot_cache_ != NULL) {
   1539     delete[] serialize_partial_snapshot_cache_;
   1540     serialize_partial_snapshot_cache_ = NULL;
   1541   }
   1542 
   1543   delete this;
   1544 
   1545   // Restore the previous current isolate.
   1546   SetIsolateThreadLocals(saved_isolate, saved_data);
   1547 }
   1548 
   1549 
   1550 void Isolate::GlobalTearDown() {
   1551   delete thread_data_table_;
   1552 }
   1553 
   1554 
   1555 void Isolate::Deinit() {
   1556   if (state_ == INITIALIZED) {
   1557     TRACE_ISOLATE(deinit);
   1558 
   1559     debug()->Unload();
   1560 
   1561     if (concurrent_recompilation_enabled()) {
   1562       optimizing_compiler_thread_->Stop();
   1563       delete optimizing_compiler_thread_;
   1564       optimizing_compiler_thread_ = NULL;
   1565     }
   1566 
   1567     for (int i = 0; i < num_sweeper_threads_; i++) {
   1568       sweeper_thread_[i]->Stop();
   1569       delete sweeper_thread_[i];
   1570       sweeper_thread_[i] = NULL;
   1571     }
   1572     delete[] sweeper_thread_;
   1573     sweeper_thread_ = NULL;
   1574 
   1575     if (FLAG_job_based_sweeping &&
   1576         heap_.mark_compact_collector()->IsConcurrentSweepingInProgress()) {
   1577       heap_.mark_compact_collector()->WaitUntilSweepingCompleted();
   1578     }
   1579 
   1580     if (FLAG_hydrogen_stats) GetHStatistics()->Print();
   1581 
   1582     if (FLAG_print_deopt_stress) {
   1583       PrintF(stdout, "=== Stress deopt counter: %u\n", stress_deopt_count_);
   1584     }
   1585 
   1586     // We must stop the logger before we tear down other components.
   1587     Sampler* sampler = logger_->sampler();
   1588     if (sampler && sampler->IsActive()) sampler->Stop();
   1589 
   1590     delete deoptimizer_data_;
   1591     deoptimizer_data_ = NULL;
   1592     builtins_.TearDown();
   1593     bootstrapper_->TearDown();
   1594 
   1595     if (runtime_profiler_ != NULL) {
   1596       delete runtime_profiler_;
   1597       runtime_profiler_ = NULL;
   1598     }
   1599     heap_.TearDown();
   1600     logger_->TearDown();
   1601 
   1602     delete heap_profiler_;
   1603     heap_profiler_ = NULL;
   1604     delete cpu_profiler_;
   1605     cpu_profiler_ = NULL;
   1606 
   1607     // The default isolate is re-initializable due to legacy API.
   1608     state_ = UNINITIALIZED;
   1609   }
   1610 }
   1611 
   1612 
   1613 void Isolate::PushToPartialSnapshotCache(Object* obj) {
   1614   int length = serialize_partial_snapshot_cache_length();
   1615   int capacity = serialize_partial_snapshot_cache_capacity();
   1616 
   1617   if (length >= capacity) {
   1618     int new_capacity = static_cast<int>((capacity + 10) * 1.2);
   1619     Object** new_array = new Object*[new_capacity];
   1620     for (int i = 0; i < length; i++) {
   1621       new_array[i] = serialize_partial_snapshot_cache()[i];
   1622     }
   1623     if (capacity != 0) delete[] serialize_partial_snapshot_cache();
   1624     set_serialize_partial_snapshot_cache(new_array);
   1625     set_serialize_partial_snapshot_cache_capacity(new_capacity);
   1626   }
   1627 
   1628   serialize_partial_snapshot_cache()[length] = obj;
   1629   set_serialize_partial_snapshot_cache_length(length + 1);
   1630 }
   1631 
   1632 
   1633 void Isolate::SetIsolateThreadLocals(Isolate* isolate,
   1634                                      PerIsolateThreadData* data) {
   1635   Thread::SetThreadLocal(isolate_key_, isolate);
   1636   Thread::SetThreadLocal(per_isolate_thread_data_key_, data);
   1637 }
   1638 
   1639 
   1640 Isolate::~Isolate() {
   1641   TRACE_ISOLATE(destructor);
   1642 
   1643   // Has to be called while counters_ are still alive
   1644   runtime_zone_.DeleteKeptSegment();
   1645 
   1646   // The entry stack must be empty when we get here.
   1647   ASSERT(entry_stack_ == NULL || entry_stack_->previous_item == NULL);
   1648 
   1649   delete entry_stack_;
   1650   entry_stack_ = NULL;
   1651 
   1652   delete[] assembler_spare_buffer_;
   1653   assembler_spare_buffer_ = NULL;
   1654 
   1655   delete unicode_cache_;
   1656   unicode_cache_ = NULL;
   1657 
   1658   delete date_cache_;
   1659   date_cache_ = NULL;
   1660 
   1661   delete[] code_stub_interface_descriptors_;
   1662   code_stub_interface_descriptors_ = NULL;
   1663 
   1664   delete[] call_descriptors_;
   1665   call_descriptors_ = NULL;
   1666 
   1667   delete regexp_stack_;
   1668   regexp_stack_ = NULL;
   1669 
   1670   delete descriptor_lookup_cache_;
   1671   descriptor_lookup_cache_ = NULL;
   1672   delete context_slot_cache_;
   1673   context_slot_cache_ = NULL;
   1674   delete keyed_lookup_cache_;
   1675   keyed_lookup_cache_ = NULL;
   1676 
   1677   delete stub_cache_;
   1678   stub_cache_ = NULL;
   1679   delete code_aging_helper_;
   1680   code_aging_helper_ = NULL;
   1681   delete stats_table_;
   1682   stats_table_ = NULL;
   1683 
   1684   delete materialized_object_store_;
   1685   materialized_object_store_ = NULL;
   1686 
   1687   delete logger_;
   1688   logger_ = NULL;
   1689 
   1690   delete counters_;
   1691   counters_ = NULL;
   1692 
   1693   delete handle_scope_implementer_;
   1694   handle_scope_implementer_ = NULL;
   1695 
   1696   delete compilation_cache_;
   1697   compilation_cache_ = NULL;
   1698   delete bootstrapper_;
   1699   bootstrapper_ = NULL;
   1700   delete inner_pointer_to_code_cache_;
   1701   inner_pointer_to_code_cache_ = NULL;
   1702   delete write_iterator_;
   1703   write_iterator_ = NULL;
   1704 
   1705   delete thread_manager_;
   1706   thread_manager_ = NULL;
   1707 
   1708   delete string_tracker_;
   1709   string_tracker_ = NULL;
   1710 
   1711   delete memory_allocator_;
   1712   memory_allocator_ = NULL;
   1713   delete code_range_;
   1714   code_range_ = NULL;
   1715   delete global_handles_;
   1716   global_handles_ = NULL;
   1717   delete eternal_handles_;
   1718   eternal_handles_ = NULL;
   1719 
   1720   delete string_stream_debug_object_cache_;
   1721   string_stream_debug_object_cache_ = NULL;
   1722 
   1723   delete external_reference_table_;
   1724   external_reference_table_ = NULL;
   1725 
   1726   delete random_number_generator_;
   1727   random_number_generator_ = NULL;
   1728 
   1729   delete debug_;
   1730   debug_ = NULL;
   1731 }
   1732 
   1733 
   1734 void Isolate::InitializeThreadLocal() {
   1735   thread_local_top_.isolate_ = this;
   1736   thread_local_top_.Initialize();
   1737 }
   1738 
   1739 
   1740 bool Isolate::PropagatePendingExceptionToExternalTryCatch() {
   1741   ASSERT(has_pending_exception());
   1742 
   1743   bool has_external_try_catch = HasExternalTryCatch();
   1744   if (!has_external_try_catch) {
   1745     thread_local_top_.external_caught_exception_ = false;
   1746     return true;
   1747   }
   1748 
   1749   bool catchable_by_js = is_catchable_by_javascript(pending_exception());
   1750   if (catchable_by_js && IsFinallyOnTop()) {
   1751     thread_local_top_.external_caught_exception_ = false;
   1752     return false;
   1753   }
   1754 
   1755   thread_local_top_.external_caught_exception_ = true;
   1756   if (thread_local_top_.pending_exception_ ==
   1757              heap()->termination_exception()) {
   1758     try_catch_handler()->can_continue_ = false;
   1759     try_catch_handler()->has_terminated_ = true;
   1760     try_catch_handler()->exception_ = heap()->null_value();
   1761   } else {
   1762     v8::TryCatch* handler = try_catch_handler();
   1763     ASSERT(thread_local_top_.pending_message_obj_->IsJSMessageObject() ||
   1764            thread_local_top_.pending_message_obj_->IsTheHole());
   1765     ASSERT(thread_local_top_.pending_message_script_->IsScript() ||
   1766            thread_local_top_.pending_message_script_->IsTheHole());
   1767     handler->can_continue_ = true;
   1768     handler->has_terminated_ = false;
   1769     handler->exception_ = pending_exception();
   1770     // Propagate to the external try-catch only if we got an actual message.
   1771     if (thread_local_top_.pending_message_obj_->IsTheHole()) return true;
   1772 
   1773     handler->message_obj_ = thread_local_top_.pending_message_obj_;
   1774     handler->message_script_ = thread_local_top_.pending_message_script_;
   1775     handler->message_start_pos_ = thread_local_top_.pending_message_start_pos_;
   1776     handler->message_end_pos_ = thread_local_top_.pending_message_end_pos_;
   1777   }
   1778   return true;
   1779 }
   1780 
   1781 
   1782 void Isolate::InitializeLoggingAndCounters() {
   1783   if (logger_ == NULL) {
   1784     logger_ = new Logger(this);
   1785   }
   1786   if (counters_ == NULL) {
   1787     counters_ = new Counters(this);
   1788   }
   1789 }
   1790 
   1791 
   1792 bool Isolate::Init(Deserializer* des) {
   1793   ASSERT(state_ != INITIALIZED);
   1794   TRACE_ISOLATE(init);
   1795 
   1796   stress_deopt_count_ = FLAG_deopt_every_n_times;
   1797 
   1798   has_fatal_error_ = false;
   1799 
   1800   if (function_entry_hook() != NULL) {
   1801     // When function entry hooking is in effect, we have to create the code
   1802     // stubs from scratch to get entry hooks, rather than loading the previously
   1803     // generated stubs from disk.
   1804     // If this assert fires, the initialization path has regressed.
   1805     ASSERT(des == NULL);
   1806   }
   1807 
   1808   // The initialization process does not handle memory exhaustion.
   1809   DisallowAllocationFailure disallow_allocation_failure(this);
   1810 
   1811   memory_allocator_ = new MemoryAllocator(this);
   1812   code_range_ = new CodeRange(this);
   1813 
   1814   // Safe after setting Heap::isolate_, and initializing StackGuard
   1815   heap_.SetStackLimits();
   1816 
   1817 #define ASSIGN_ELEMENT(CamelName, hacker_name)                  \
   1818   isolate_addresses_[Isolate::k##CamelName##Address] =          \
   1819       reinterpret_cast<Address>(hacker_name##_address());
   1820   FOR_EACH_ISOLATE_ADDRESS_NAME(ASSIGN_ELEMENT)
   1821 #undef ASSIGN_ELEMENT
   1822 
   1823   string_tracker_ = new StringTracker();
   1824   string_tracker_->isolate_ = this;
   1825   compilation_cache_ = new CompilationCache(this);
   1826   keyed_lookup_cache_ = new KeyedLookupCache();
   1827   context_slot_cache_ = new ContextSlotCache();
   1828   descriptor_lookup_cache_ = new DescriptorLookupCache();
   1829   unicode_cache_ = new UnicodeCache();
   1830   inner_pointer_to_code_cache_ = new InnerPointerToCodeCache(this);
   1831   write_iterator_ = new ConsStringIteratorOp();
   1832   global_handles_ = new GlobalHandles(this);
   1833   eternal_handles_ = new EternalHandles();
   1834   bootstrapper_ = new Bootstrapper(this);
   1835   handle_scope_implementer_ = new HandleScopeImplementer(this);
   1836   stub_cache_ = new StubCache(this);
   1837   materialized_object_store_ = new MaterializedObjectStore(this);
   1838   regexp_stack_ = new RegExpStack();
   1839   regexp_stack_->isolate_ = this;
   1840   date_cache_ = new DateCache();
   1841   code_stub_interface_descriptors_ =
   1842       new CodeStubInterfaceDescriptor[CodeStub::NUMBER_OF_IDS];
   1843   call_descriptors_ =
   1844       new CallInterfaceDescriptor[NUMBER_OF_CALL_DESCRIPTORS];
   1845   cpu_profiler_ = new CpuProfiler(this);
   1846   heap_profiler_ = new HeapProfiler(heap());
   1847 
   1848   // Enable logging before setting up the heap
   1849   logger_->SetUp(this);
   1850 
   1851   // Initialize other runtime facilities
   1852 #if defined(USE_SIMULATOR)
   1853 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_MIPS
   1854   Simulator::Initialize(this);
   1855 #endif
   1856 #endif
   1857 
   1858   code_aging_helper_ = new CodeAgingHelper();
   1859 
   1860   { // NOLINT
   1861     // Ensure that the thread has a valid stack guard.  The v8::Locker object
   1862     // will ensure this too, but we don't have to use lockers if we are only
   1863     // using one thread.
   1864     ExecutionAccess lock(this);
   1865     stack_guard_.InitThread(lock);
   1866   }
   1867 
   1868   // SetUp the object heap.
   1869   ASSERT(!heap_.HasBeenSetUp());
   1870   if (!heap_.SetUp()) {
   1871     V8::FatalProcessOutOfMemory("heap setup");
   1872     return false;
   1873   }
   1874 
   1875   deoptimizer_data_ = new DeoptimizerData(memory_allocator_);
   1876 
   1877   const bool create_heap_objects = (des == NULL);
   1878   if (create_heap_objects && !heap_.CreateHeapObjects()) {
   1879     V8::FatalProcessOutOfMemory("heap object creation");
   1880     return false;
   1881   }
   1882 
   1883   if (create_heap_objects) {
   1884     // Terminate the cache array with the sentinel so we can iterate.
   1885     PushToPartialSnapshotCache(heap_.undefined_value());
   1886   }
   1887 
   1888   InitializeThreadLocal();
   1889 
   1890   bootstrapper_->Initialize(create_heap_objects);
   1891   builtins_.SetUp(this, create_heap_objects);
   1892 
   1893   if (FLAG_log_internal_timer_events) {
   1894     set_event_logger(Logger::LogInternalEvents);
   1895   } else {
   1896     set_event_logger(Logger::EmptyLogInternalEvents);
   1897   }
   1898 
   1899   // Set default value if not yet set.
   1900   // TODO(yangguo): move this to ResourceConstraints::ConfigureDefaults
   1901   // once ResourceConstraints becomes an argument to the Isolate constructor.
   1902   if (max_available_threads_ < 1) {
   1903     // Choose the default between 1 and 4.
   1904     max_available_threads_ = Max(Min(OS::NumberOfProcessorsOnline(), 4), 1);
   1905   }
   1906 
   1907   if (!FLAG_job_based_sweeping) {
   1908     num_sweeper_threads_ =
   1909         SweeperThread::NumberOfThreads(max_available_threads_);
   1910   }
   1911 
   1912   if (FLAG_trace_hydrogen || FLAG_trace_hydrogen_stubs) {
   1913     PrintF("Concurrent recompilation has been disabled for tracing.\n");
   1914   } else if (OptimizingCompilerThread::Enabled(max_available_threads_)) {
   1915     optimizing_compiler_thread_ = new OptimizingCompilerThread(this);
   1916     optimizing_compiler_thread_->Start();
   1917   }
   1918 
   1919   if (num_sweeper_threads_ > 0) {
   1920     sweeper_thread_ = new SweeperThread*[num_sweeper_threads_];
   1921     for (int i = 0; i < num_sweeper_threads_; i++) {
   1922       sweeper_thread_[i] = new SweeperThread(this);
   1923       sweeper_thread_[i]->Start();
   1924     }
   1925   }
   1926 
   1927   // If we are deserializing, read the state into the now-empty heap.
   1928   if (!create_heap_objects) {
   1929     des->Deserialize(this);
   1930   }
   1931   stub_cache_->Initialize();
   1932 
   1933   // Finish initialization of ThreadLocal after deserialization is done.
   1934   clear_pending_exception();
   1935   clear_pending_message();
   1936   clear_scheduled_exception();
   1937 
   1938   // Deserializing may put strange things in the root array's copy of the
   1939   // stack guard.
   1940   heap_.SetStackLimits();
   1941 
   1942   // Quiet the heap NaN if needed on target platform.
   1943   if (!create_heap_objects) Assembler::QuietNaN(heap_.nan_value());
   1944 
   1945   runtime_profiler_ = new RuntimeProfiler(this);
   1946 
   1947   // If we are deserializing, log non-function code objects and compiled
   1948   // functions found in the snapshot.
   1949   if (!create_heap_objects &&
   1950       (FLAG_log_code ||
   1951        FLAG_ll_prof ||
   1952        FLAG_perf_jit_prof ||
   1953        FLAG_perf_basic_prof ||
   1954        logger_->is_logging_code_events())) {
   1955     HandleScope scope(this);
   1956     LOG(this, LogCodeObjects());
   1957     LOG(this, LogCompiledFunctions());
   1958   }
   1959 
   1960   // If we are profiling with the Linux perf tool, we need to disable
   1961   // code relocation.
   1962   if (FLAG_perf_jit_prof || FLAG_perf_basic_prof) {
   1963     FLAG_compact_code_space = false;
   1964   }
   1965 
   1966   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, embedder_data_)),
   1967            Internals::kIsolateEmbedderDataOffset);
   1968   CHECK_EQ(static_cast<int>(OFFSET_OF(Isolate, heap_.roots_)),
   1969            Internals::kIsolateRootsOffset);
   1970   CHECK_EQ(static_cast<int>(
   1971                OFFSET_OF(Isolate, heap_.amount_of_external_allocated_memory_)),
   1972            Internals::kAmountOfExternalAllocatedMemoryOffset);
   1973   CHECK_EQ(static_cast<int>(OFFSET_OF(
   1974                Isolate,
   1975                heap_.amount_of_external_allocated_memory_at_last_global_gc_)),
   1976            Internals::kAmountOfExternalAllocatedMemoryAtLastGlobalGCOffset);
   1977 
   1978   state_ = INITIALIZED;
   1979   time_millis_at_init_ = OS::TimeCurrentMillis();
   1980 
   1981   if (!create_heap_objects) {
   1982     // Now that the heap is consistent, it's OK to generate the code for the
   1983     // deopt entry table that might have been referred to by optimized code in
   1984     // the snapshot.
   1985     HandleScope scope(this);
   1986     Deoptimizer::EnsureCodeForDeoptimizationEntry(
   1987         this,
   1988         Deoptimizer::LAZY,
   1989         kDeoptTableSerializeEntryCount - 1);
   1990   }
   1991 
   1992   if (!serializer_enabled()) {
   1993     // Ensure that all stubs which need to be generated ahead of time, but
   1994     // cannot be serialized into the snapshot have been generated.
   1995     HandleScope scope(this);
   1996     CodeStub::GenerateFPStubs(this);
   1997     StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(this);
   1998     StubFailureTrampolineStub::GenerateAheadOfTime(this);
   1999     // Ensure interface descriptors are initialized even when stubs have been
   2000     // deserialized out of the snapshot without using the graph builder.
   2001     FastCloneShallowArrayStub::InstallDescriptors(this);
   2002     BinaryOpICStub::InstallDescriptors(this);
   2003     BinaryOpWithAllocationSiteStub::InstallDescriptors(this);
   2004     CompareNilICStub::InstallDescriptors(this);
   2005     ToBooleanStub::InstallDescriptors(this);
   2006     ToNumberStub::InstallDescriptors(this);
   2007     ArrayConstructorStubBase::InstallDescriptors(this);
   2008     InternalArrayConstructorStubBase::InstallDescriptors(this);
   2009     FastNewClosureStub::InstallDescriptors(this);
   2010     FastNewContextStub::InstallDescriptors(this);
   2011     NumberToStringStub::InstallDescriptors(this);
   2012     StringAddStub::InstallDescriptors(this);
   2013     RegExpConstructResultStub::InstallDescriptors(this);
   2014     KeyedLoadGenericElementStub::InstallDescriptors(this);
   2015   }
   2016 
   2017   CallDescriptors::InitializeForIsolate(this);
   2018 
   2019   initialized_from_snapshot_ = (des != NULL);
   2020 
   2021   return true;
   2022 }
   2023 
   2024 
   2025 // Initialized lazily to allow early
   2026 // v8::V8::SetAddHistogramSampleFunction calls.
   2027 StatsTable* Isolate::stats_table() {
   2028   if (stats_table_ == NULL) {
   2029     stats_table_ = new StatsTable;
   2030   }
   2031   return stats_table_;
   2032 }
   2033 
   2034 
   2035 void Isolate::Enter() {
   2036   Isolate* current_isolate = NULL;
   2037   PerIsolateThreadData* current_data = CurrentPerIsolateThreadData();
   2038   if (current_data != NULL) {
   2039     current_isolate = current_data->isolate_;
   2040     ASSERT(current_isolate != NULL);
   2041     if (current_isolate == this) {
   2042       ASSERT(Current() == this);
   2043       ASSERT(entry_stack_ != NULL);
   2044       ASSERT(entry_stack_->previous_thread_data == NULL ||
   2045              entry_stack_->previous_thread_data->thread_id().Equals(
   2046                  ThreadId::Current()));
   2047       // Same thread re-enters the isolate, no need to re-init anything.
   2048       entry_stack_->entry_count++;
   2049       return;
   2050     }
   2051   }
   2052 
   2053   // Threads can have default isolate set into TLS as Current but not yet have
   2054   // PerIsolateThreadData for it, as it requires more advanced phase of the
   2055   // initialization. For example, a thread might be the one that system used for
   2056   // static initializers - in this case the default isolate is set in TLS but
   2057   // the thread did not yet Enter the isolate. If PerisolateThreadData is not
   2058   // there, use the isolate set in TLS.
   2059   if (current_isolate == NULL) {
   2060     current_isolate = Isolate::UncheckedCurrent();
   2061   }
   2062 
   2063   PerIsolateThreadData* data = FindOrAllocatePerThreadDataForThisThread();
   2064   ASSERT(data != NULL);
   2065   ASSERT(data->isolate_ == this);
   2066 
   2067   EntryStackItem* item = new EntryStackItem(current_data,
   2068                                             current_isolate,
   2069                                             entry_stack_);
   2070   entry_stack_ = item;
   2071 
   2072   SetIsolateThreadLocals(this, data);
   2073 
   2074   // In case it's the first time some thread enters the isolate.
   2075   set_thread_id(data->thread_id());
   2076 }
   2077 
   2078 
   2079 void Isolate::Exit() {
   2080   ASSERT(entry_stack_ != NULL);
   2081   ASSERT(entry_stack_->previous_thread_data == NULL ||
   2082          entry_stack_->previous_thread_data->thread_id().Equals(
   2083              ThreadId::Current()));
   2084 
   2085   if (--entry_stack_->entry_count > 0) return;
   2086 
   2087   ASSERT(CurrentPerIsolateThreadData() != NULL);
   2088   ASSERT(CurrentPerIsolateThreadData()->isolate_ == this);
   2089 
   2090   // Pop the stack.
   2091   EntryStackItem* item = entry_stack_;
   2092   entry_stack_ = item->previous_item;
   2093 
   2094   PerIsolateThreadData* previous_thread_data = item->previous_thread_data;
   2095   Isolate* previous_isolate = item->previous_isolate;
   2096 
   2097   delete item;
   2098 
   2099   // Reinit the current thread for the isolate it was running before this one.
   2100   SetIsolateThreadLocals(previous_isolate, previous_thread_data);
   2101 }
   2102 
   2103 
   2104 void Isolate::LinkDeferredHandles(DeferredHandles* deferred) {
   2105   deferred->next_ = deferred_handles_head_;
   2106   if (deferred_handles_head_ != NULL) {
   2107     deferred_handles_head_->previous_ = deferred;
   2108   }
   2109   deferred_handles_head_ = deferred;
   2110 }
   2111 
   2112 
   2113 void Isolate::UnlinkDeferredHandles(DeferredHandles* deferred) {
   2114 #ifdef DEBUG
   2115   // In debug mode assert that the linked list is well-formed.
   2116   DeferredHandles* deferred_iterator = deferred;
   2117   while (deferred_iterator->previous_ != NULL) {
   2118     deferred_iterator = deferred_iterator->previous_;
   2119   }
   2120   ASSERT(deferred_handles_head_ == deferred_iterator);
   2121 #endif
   2122   if (deferred_handles_head_ == deferred) {
   2123     deferred_handles_head_ = deferred_handles_head_->next_;
   2124   }
   2125   if (deferred->next_ != NULL) {
   2126     deferred->next_->previous_ = deferred->previous_;
   2127   }
   2128   if (deferred->previous_ != NULL) {
   2129     deferred->previous_->next_ = deferred->next_;
   2130   }
   2131 }
   2132 
   2133 
   2134 HStatistics* Isolate::GetHStatistics() {
   2135   if (hstatistics() == NULL) set_hstatistics(new HStatistics());
   2136   return hstatistics();
   2137 }
   2138 
   2139 
   2140 HTracer* Isolate::GetHTracer() {
   2141   if (htracer() == NULL) set_htracer(new HTracer(id()));
   2142   return htracer();
   2143 }
   2144 
   2145 
   2146 CodeTracer* Isolate::GetCodeTracer() {
   2147   if (code_tracer() == NULL) set_code_tracer(new CodeTracer(id()));
   2148   return code_tracer();
   2149 }
   2150 
   2151 
   2152 Map* Isolate::get_initial_js_array_map(ElementsKind kind) {
   2153   Context* native_context = context()->native_context();
   2154   Object* maybe_map_array = native_context->js_array_maps();
   2155   if (!maybe_map_array->IsUndefined()) {
   2156     Object* maybe_transitioned_map =
   2157         FixedArray::cast(maybe_map_array)->get(kind);
   2158     if (!maybe_transitioned_map->IsUndefined()) {
   2159       return Map::cast(maybe_transitioned_map);
   2160     }
   2161   }
   2162   return NULL;
   2163 }
   2164 
   2165 
   2166 bool Isolate::use_crankshaft() const {
   2167   return FLAG_crankshaft &&
   2168          !serializer_enabled_ &&
   2169          CpuFeatures::SupportsCrankshaft();
   2170 }
   2171 
   2172 
   2173 bool Isolate::IsFastArrayConstructorPrototypeChainIntact() {
   2174   Map* root_array_map =
   2175       get_initial_js_array_map(GetInitialFastElementsKind());
   2176   ASSERT(root_array_map != NULL);
   2177   JSObject* initial_array_proto = JSObject::cast(*initial_array_prototype());
   2178 
   2179   // Check that the array prototype hasn't been altered WRT empty elements.
   2180   if (root_array_map->prototype() != initial_array_proto) return false;
   2181   if (initial_array_proto->elements() != heap()->empty_fixed_array()) {
   2182     return false;
   2183   }
   2184 
   2185   // Check that the object prototype hasn't been altered WRT empty elements.
   2186   JSObject* initial_object_proto = JSObject::cast(*initial_object_prototype());
   2187   Object* root_array_map_proto = initial_array_proto->GetPrototype();
   2188   if (root_array_map_proto != initial_object_proto) return false;
   2189   if (initial_object_proto->elements() != heap()->empty_fixed_array()) {
   2190     return false;
   2191   }
   2192 
   2193   return initial_object_proto->GetPrototype()->IsNull();
   2194 }
   2195 
   2196 
   2197 CodeStubInterfaceDescriptor*
   2198     Isolate::code_stub_interface_descriptor(int index) {
   2199   return code_stub_interface_descriptors_ + index;
   2200 }
   2201 
   2202 
   2203 CallInterfaceDescriptor*
   2204     Isolate::call_descriptor(CallDescriptorKey index) {
   2205   ASSERT(0 <= index && index < NUMBER_OF_CALL_DESCRIPTORS);
   2206   return &call_descriptors_[index];
   2207 }
   2208 
   2209 
   2210 Object* Isolate::FindCodeObject(Address a) {
   2211   return inner_pointer_to_code_cache()->GcSafeFindCodeForInnerPointer(a);
   2212 }
   2213 
   2214 
   2215 #ifdef DEBUG
   2216 #define ISOLATE_FIELD_OFFSET(type, name, ignored)                       \
   2217 const intptr_t Isolate::name##_debug_offset_ = OFFSET_OF(Isolate, name##_);
   2218 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
   2219 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
   2220 #undef ISOLATE_FIELD_OFFSET
   2221 #endif
   2222 
   2223 
   2224 Handle<JSObject> Isolate::GetSymbolRegistry() {
   2225   if (heap()->symbol_registry()->IsUndefined()) {
   2226     Handle<Map> map = factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
   2227     Handle<JSObject> registry = factory()->NewJSObjectFromMap(map);
   2228     heap()->set_symbol_registry(*registry);
   2229 
   2230     static const char* nested[] = {
   2231       "for", "for_api", "for_intern", "keyFor", "private_api", "private_intern"
   2232     };
   2233     for (unsigned i = 0; i < ARRAY_SIZE(nested); ++i) {
   2234       Handle<String> name = factory()->InternalizeUtf8String(nested[i]);
   2235       Handle<JSObject> obj = factory()->NewJSObjectFromMap(map);
   2236       JSObject::NormalizeProperties(obj, KEEP_INOBJECT_PROPERTIES, 8);
   2237       JSObject::SetProperty(registry, name, obj, NONE, STRICT).Assert();
   2238     }
   2239   }
   2240   return Handle<JSObject>::cast(factory()->symbol_registry());
   2241 }
   2242 
   2243 
   2244 void Isolate::AddCallCompletedCallback(CallCompletedCallback callback) {
   2245   for (int i = 0; i < call_completed_callbacks_.length(); i++) {
   2246     if (callback == call_completed_callbacks_.at(i)) return;
   2247   }
   2248   call_completed_callbacks_.Add(callback);
   2249 }
   2250 
   2251 
   2252 void Isolate::RemoveCallCompletedCallback(CallCompletedCallback callback) {
   2253   for (int i = 0; i < call_completed_callbacks_.length(); i++) {
   2254     if (callback == call_completed_callbacks_.at(i)) {
   2255       call_completed_callbacks_.Remove(i);
   2256     }
   2257   }
   2258 }
   2259 
   2260 
   2261 void Isolate::FireCallCompletedCallback() {
   2262   bool has_call_completed_callbacks = !call_completed_callbacks_.is_empty();
   2263   bool run_microtasks = autorun_microtasks() && pending_microtask_count();
   2264   if (!has_call_completed_callbacks && !run_microtasks) return;
   2265 
   2266   if (!handle_scope_implementer()->CallDepthIsZero()) return;
   2267   if (run_microtasks) RunMicrotasks();
   2268   // Fire callbacks.  Increase call depth to prevent recursive callbacks.
   2269   v8::Isolate::SuppressMicrotaskExecutionScope suppress(
   2270       reinterpret_cast<v8::Isolate*>(this));
   2271   for (int i = 0; i < call_completed_callbacks_.length(); i++) {
   2272     call_completed_callbacks_.at(i)();
   2273   }
   2274 }
   2275 
   2276 
   2277 void Isolate::EnqueueMicrotask(Handle<Object> microtask) {
   2278   ASSERT(microtask->IsJSFunction() || microtask->IsCallHandlerInfo());
   2279   Handle<FixedArray> queue(heap()->microtask_queue(), this);
   2280   int num_tasks = pending_microtask_count();
   2281   ASSERT(num_tasks <= queue->length());
   2282   if (num_tasks == 0) {
   2283     queue = factory()->NewFixedArray(8);
   2284     heap()->set_microtask_queue(*queue);
   2285   } else if (num_tasks == queue->length()) {
   2286     queue = FixedArray::CopySize(queue, num_tasks * 2);
   2287     heap()->set_microtask_queue(*queue);
   2288   }
   2289   ASSERT(queue->get(num_tasks)->IsUndefined());
   2290   queue->set(num_tasks, *microtask);
   2291   set_pending_microtask_count(num_tasks + 1);
   2292 }
   2293 
   2294 
   2295 void Isolate::RunMicrotasks() {
   2296   // TODO(adamk): This ASSERT triggers in mjsunit tests which
   2297   // call the %RunMicrotasks runtime function. But it should
   2298   // never happen outside of tests, so it would be nice to
   2299   // uncomment it.
   2300   //
   2301   // ASSERT(handle_scope_implementer()->CallDepthIsZero());
   2302 
   2303   // Increase call depth to prevent recursive callbacks.
   2304   v8::Isolate::SuppressMicrotaskExecutionScope suppress(
   2305       reinterpret_cast<v8::Isolate*>(this));
   2306 
   2307   while (pending_microtask_count() > 0) {
   2308     HandleScope scope(this);
   2309     int num_tasks = pending_microtask_count();
   2310     Handle<FixedArray> queue(heap()->microtask_queue(), this);
   2311     ASSERT(num_tasks <= queue->length());
   2312     set_pending_microtask_count(0);
   2313     heap()->set_microtask_queue(heap()->empty_fixed_array());
   2314 
   2315     for (int i = 0; i < num_tasks; i++) {
   2316       HandleScope scope(this);
   2317       Handle<Object> microtask(queue->get(i), this);
   2318       if (microtask->IsJSFunction()) {
   2319         Handle<JSFunction> microtask_function =
   2320             Handle<JSFunction>::cast(microtask);
   2321         Handle<Object> exception;
   2322         MaybeHandle<Object> result = Execution::TryCall(
   2323             microtask_function, factory()->undefined_value(),
   2324             0, NULL, &exception);
   2325         // If execution is terminating, just bail out.
   2326         if (result.is_null() &&
   2327             !exception.is_null() &&
   2328             *exception == heap()->termination_exception()) {
   2329           // Clear out any remaining callbacks in the queue.
   2330           heap()->set_microtask_queue(heap()->empty_fixed_array());
   2331           set_pending_microtask_count(0);
   2332           return;
   2333         }
   2334       } else {
   2335         Handle<CallHandlerInfo> callback_info =
   2336             Handle<CallHandlerInfo>::cast(microtask);
   2337         v8::MicrotaskCallback callback =
   2338             v8::ToCData<v8::MicrotaskCallback>(callback_info->callback());
   2339         void* data = v8::ToCData<void*>(callback_info->data());
   2340         callback(data);
   2341       }
   2342     }
   2343   }
   2344 }
   2345 
   2346 
   2347 bool StackLimitCheck::JsHasOverflowed() const {
   2348   StackGuard* stack_guard = isolate_->stack_guard();
   2349 #ifdef USE_SIMULATOR
   2350   // The simulator uses a separate JS stack.
   2351   Address jssp_address = Simulator::current(isolate_)->get_sp();
   2352   uintptr_t jssp = reinterpret_cast<uintptr_t>(jssp_address);
   2353   if (jssp < stack_guard->real_jslimit()) return true;
   2354 #endif  // USE_SIMULATOR
   2355   return reinterpret_cast<uintptr_t>(this) < stack_guard->real_climit();
   2356 }
   2357 
   2358 
   2359 } }  // namespace v8::internal
   2360