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