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 #ifndef V8_ISOLATE_H_
      6 #define V8_ISOLATE_H_
      7 
      8 #include "include/v8-debug.h"
      9 #include "src/allocation.h"
     10 #include "src/assert-scope.h"
     11 #include "src/base/atomicops.h"
     12 #include "src/builtins.h"
     13 #include "src/contexts.h"
     14 #include "src/date.h"
     15 #include "src/execution.h"
     16 #include "src/frames.h"
     17 #include "src/global-handles.h"
     18 #include "src/handles.h"
     19 #include "src/hashmap.h"
     20 #include "src/heap/heap.h"
     21 #include "src/optimizing-compiler-thread.h"
     22 #include "src/regexp-stack.h"
     23 #include "src/runtime.h"
     24 #include "src/runtime-profiler.h"
     25 #include "src/zone.h"
     26 
     27 namespace v8 {
     28 
     29 namespace base {
     30 class RandomNumberGenerator;
     31 }
     32 
     33 namespace internal {
     34 
     35 class Bootstrapper;
     36 class CallInterfaceDescriptorData;
     37 class CodeGenerator;
     38 class CodeRange;
     39 class CodeStubDescriptor;
     40 class CodeTracer;
     41 class CompilationCache;
     42 class ConsStringIteratorOp;
     43 class ContextSlotCache;
     44 class Counters;
     45 class CpuFeatures;
     46 class CpuProfiler;
     47 class DeoptimizerData;
     48 class Deserializer;
     49 class EmptyStatement;
     50 class ExternalCallbackScope;
     51 class ExternalReferenceTable;
     52 class Factory;
     53 class FunctionInfoListener;
     54 class HandleScopeImplementer;
     55 class HeapProfiler;
     56 class HStatistics;
     57 class HTracer;
     58 class InlineRuntimeFunctionsTable;
     59 class InnerPointerToCodeCache;
     60 class MaterializedObjectStore;
     61 class CodeAgingHelper;
     62 class RegExpStack;
     63 class SaveContext;
     64 class StringTracker;
     65 class StubCache;
     66 class SweeperThread;
     67 class ThreadManager;
     68 class ThreadState;
     69 class ThreadVisitor;  // Defined in v8threads.h
     70 class UnicodeCache;
     71 template <StateTag Tag> class VMState;
     72 
     73 // 'void function pointer', used to roundtrip the
     74 // ExternalReference::ExternalReferenceRedirector since we can not include
     75 // assembler.h, where it is defined, here.
     76 typedef void* ExternalReferenceRedirectorPointer();
     77 
     78 
     79 class Debug;
     80 class Debugger;
     81 class PromiseOnStack;
     82 
     83 #if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
     84     !defined(__aarch64__) && V8_TARGET_ARCH_ARM64 || \
     85     !defined(__mips__) && V8_TARGET_ARCH_MIPS || \
     86     !defined(__mips__) && V8_TARGET_ARCH_MIPS64
     87 class Redirection;
     88 class Simulator;
     89 #endif
     90 
     91 
     92 // Static indirection table for handles to constants.  If a frame
     93 // element represents a constant, the data contains an index into
     94 // this table of handles to the actual constants.
     95 // Static indirection table for handles to constants.  If a Result
     96 // represents a constant, the data contains an index into this table
     97 // of handles to the actual constants.
     98 typedef ZoneList<Handle<Object> > ZoneObjectList;
     99 
    100 #define RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate)    \
    101   do {                                                    \
    102     Isolate* __isolate__ = (isolate);                     \
    103     if (__isolate__->has_scheduled_exception()) {         \
    104       return __isolate__->PromoteScheduledException();    \
    105     }                                                     \
    106   } while (false)
    107 
    108 // Macros for MaybeHandle.
    109 
    110 #define RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, value) \
    111   do {                                                      \
    112     Isolate* __isolate__ = (isolate);                       \
    113     if (__isolate__->has_scheduled_exception()) {           \
    114       __isolate__->PromoteScheduledException();             \
    115       return value;                                         \
    116     }                                                       \
    117   } while (false)
    118 
    119 #define RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, T) \
    120   RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, MaybeHandle<T>())
    121 
    122 #define ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, value)  \
    123   do {                                                               \
    124     if (!(call).ToHandle(&dst)) {                                    \
    125       DCHECK((isolate)->has_pending_exception());                    \
    126       return value;                                                  \
    127     }                                                                \
    128   } while (false)
    129 
    130 #define ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, dst, call)  \
    131   ASSIGN_RETURN_ON_EXCEPTION_VALUE(                             \
    132       isolate, dst, call, isolate->heap()->exception())
    133 
    134 #define ASSIGN_RETURN_ON_EXCEPTION(isolate, dst, call, T)  \
    135   ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, dst, call, MaybeHandle<T>())
    136 
    137 #define THROW_NEW_ERROR(isolate, call, T)                                    \
    138   do {                                                                       \
    139     Handle<Object> __error__;                                                \
    140     ASSIGN_RETURN_ON_EXCEPTION(isolate, __error__, isolate->factory()->call, \
    141                                T);                                           \
    142     return isolate->Throw<T>(__error__);                                     \
    143   } while (false)
    144 
    145 #define THROW_NEW_ERROR_RETURN_FAILURE(isolate, call)             \
    146   do {                                                            \
    147     Handle<Object> __error__;                                     \
    148     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, __error__,        \
    149                                        isolate->factory()->call); \
    150     return isolate->Throw(*__error__);                            \
    151   } while (false)
    152 
    153 #define RETURN_ON_EXCEPTION_VALUE(isolate, call, value)            \
    154   do {                                                             \
    155     if ((call).is_null()) {                                        \
    156       DCHECK((isolate)->has_pending_exception());                  \
    157       return value;                                                \
    158     }                                                              \
    159   } while (false)
    160 
    161 #define RETURN_FAILURE_ON_EXCEPTION(isolate, call)  \
    162   RETURN_ON_EXCEPTION_VALUE(isolate, call, isolate->heap()->exception())
    163 
    164 #define RETURN_ON_EXCEPTION(isolate, call, T)  \
    165   RETURN_ON_EXCEPTION_VALUE(isolate, call, MaybeHandle<T>())
    166 
    167 
    168 #define FOR_EACH_ISOLATE_ADDRESS_NAME(C)                \
    169   C(Handler, handler)                                   \
    170   C(CEntryFP, c_entry_fp)                               \
    171   C(Context, context)                                   \
    172   C(PendingException, pending_exception)                \
    173   C(ExternalCaughtException, external_caught_exception) \
    174   C(JSEntrySP, js_entry_sp)
    175 
    176 
    177 // Platform-independent, reliable thread identifier.
    178 class ThreadId {
    179  public:
    180   // Creates an invalid ThreadId.
    181   ThreadId() : id_(kInvalidId) {}
    182 
    183   // Returns ThreadId for current thread.
    184   static ThreadId Current() { return ThreadId(GetCurrentThreadId()); }
    185 
    186   // Returns invalid ThreadId (guaranteed not to be equal to any thread).
    187   static ThreadId Invalid() { return ThreadId(kInvalidId); }
    188 
    189   // Compares ThreadIds for equality.
    190   INLINE(bool Equals(const ThreadId& other) const) {
    191     return id_ == other.id_;
    192   }
    193 
    194   // Checks whether this ThreadId refers to any thread.
    195   INLINE(bool IsValid() const) {
    196     return id_ != kInvalidId;
    197   }
    198 
    199   // Converts ThreadId to an integer representation
    200   // (required for public API: V8::V8::GetCurrentThreadId).
    201   int ToInteger() const { return id_; }
    202 
    203   // Converts ThreadId to an integer representation
    204   // (required for public API: V8::V8::TerminateExecution).
    205   static ThreadId FromInteger(int id) { return ThreadId(id); }
    206 
    207  private:
    208   static const int kInvalidId = -1;
    209 
    210   explicit ThreadId(int id) : id_(id) {}
    211 
    212   static int AllocateThreadId();
    213 
    214   static int GetCurrentThreadId();
    215 
    216   int id_;
    217 
    218   static base::Atomic32 highest_thread_id_;
    219 
    220   friend class Isolate;
    221 };
    222 
    223 
    224 #define FIELD_ACCESSOR(type, name)                 \
    225   inline void set_##name(type v) { name##_ = v; }  \
    226   inline type name() const { return name##_; }
    227 
    228 
    229 class ThreadLocalTop BASE_EMBEDDED {
    230  public:
    231   // Does early low-level initialization that does not depend on the
    232   // isolate being present.
    233   ThreadLocalTop();
    234 
    235   // Initialize the thread data.
    236   void Initialize();
    237 
    238   // Get the top C++ try catch handler or NULL if none are registered.
    239   //
    240   // This method is not guaranteed to return an address that can be
    241   // used for comparison with addresses into the JS stack.  If such an
    242   // address is needed, use try_catch_handler_address.
    243   FIELD_ACCESSOR(v8::TryCatch*, try_catch_handler)
    244 
    245   // Get the address of the top C++ try catch handler or NULL if
    246   // none are registered.
    247   //
    248   // This method always returns an address that can be compared to
    249   // pointers into the JavaScript stack.  When running on actual
    250   // hardware, try_catch_handler_address and TryCatchHandler return
    251   // the same pointer.  When running on a simulator with a separate JS
    252   // stack, try_catch_handler_address returns a JS stack address that
    253   // corresponds to the place on the JS stack where the C++ handler
    254   // would have been if the stack were not separate.
    255   Address try_catch_handler_address() {
    256     return reinterpret_cast<Address>(
    257         v8::TryCatch::JSStackComparableAddress(try_catch_handler()));
    258   }
    259 
    260   void Free();
    261 
    262   Isolate* isolate_;
    263   // The context where the current execution method is created and for variable
    264   // lookups.
    265   Context* context_;
    266   ThreadId thread_id_;
    267   Object* pending_exception_;
    268   bool has_pending_message_;
    269   bool rethrowing_message_;
    270   Object* pending_message_obj_;
    271   Object* pending_message_script_;
    272   int pending_message_start_pos_;
    273   int pending_message_end_pos_;
    274   // Use a separate value for scheduled exceptions to preserve the
    275   // invariants that hold about pending_exception.  We may want to
    276   // unify them later.
    277   Object* scheduled_exception_;
    278   bool external_caught_exception_;
    279   SaveContext* save_context_;
    280   v8::TryCatch* catcher_;
    281 
    282   // Stack.
    283   Address c_entry_fp_;  // the frame pointer of the top c entry frame
    284   Address handler_;   // try-blocks are chained through the stack
    285 
    286   // Throwing an exception may cause a Promise rejection.  For this purpose
    287   // we keep track of a stack of nested promises and the corresponding
    288   // try-catch handlers.
    289   PromiseOnStack* promise_on_stack_;
    290 
    291 #ifdef USE_SIMULATOR
    292   Simulator* simulator_;
    293 #endif
    294 
    295   Address js_entry_sp_;  // the stack pointer of the bottom JS entry frame
    296   // the external callback we're currently in
    297   ExternalCallbackScope* external_callback_scope_;
    298   StateTag current_vm_state_;
    299 
    300   // Generated code scratch locations.
    301   int32_t formal_count_;
    302 
    303   // Call back function to report unsafe JS accesses.
    304   v8::FailedAccessCheckCallback failed_access_check_callback_;
    305 
    306   // Head of the list of live LookupResults.
    307   LookupResult* top_lookup_result_;
    308 
    309  private:
    310   void InitializeInternal();
    311 
    312   v8::TryCatch* try_catch_handler_;
    313 };
    314 
    315 
    316 #if V8_TARGET_ARCH_ARM && !defined(__arm__) || \
    317     V8_TARGET_ARCH_ARM64 && !defined(__aarch64__) || \
    318     V8_TARGET_ARCH_MIPS && !defined(__mips__) || \
    319     V8_TARGET_ARCH_MIPS64 && !defined(__mips__)
    320 
    321 #define ISOLATE_INIT_SIMULATOR_LIST(V)                                         \
    322   V(bool, simulator_initialized, false)                                        \
    323   V(HashMap*, simulator_i_cache, NULL)                                         \
    324   V(Redirection*, simulator_redirection, NULL)
    325 #else
    326 
    327 #define ISOLATE_INIT_SIMULATOR_LIST(V)
    328 
    329 #endif
    330 
    331 
    332 #ifdef DEBUG
    333 
    334 #define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)                                       \
    335   V(CommentStatistic, paged_space_comments_statistics,                         \
    336       CommentStatistic::kMaxComments + 1)                                      \
    337   V(int, code_kind_statistics, Code::NUMBER_OF_KINDS)
    338 #else
    339 
    340 #define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
    341 
    342 #endif
    343 
    344 #define ISOLATE_INIT_ARRAY_LIST(V)                                             \
    345   /* SerializerDeserializer state. */                                          \
    346   V(int32_t, jsregexp_static_offsets_vector, kJSRegexpStaticOffsetsVectorSize) \
    347   V(int, bad_char_shift_table, kUC16AlphabetSize)                              \
    348   V(int, good_suffix_shift_table, (kBMMaxShift + 1))                           \
    349   V(int, suffix_table, (kBMMaxShift + 1))                                      \
    350   V(uint32_t, private_random_seed, 2)                                          \
    351   ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
    352 
    353 typedef List<HeapObject*> DebugObjectCache;
    354 
    355 #define ISOLATE_INIT_LIST(V)                                                   \
    356   /* SerializerDeserializer state. */                                          \
    357   V(int, serialize_partial_snapshot_cache_length, 0)                           \
    358   V(int, serialize_partial_snapshot_cache_capacity, 0)                         \
    359   V(Object**, serialize_partial_snapshot_cache, NULL)                          \
    360   /* Assembler state. */                                                       \
    361   V(FatalErrorCallback, exception_behavior, NULL)                              \
    362   V(LogEventCallback, event_logger, NULL)                                      \
    363   V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, NULL)     \
    364   /* To distinguish the function templates, so that we can find them in the */ \
    365   /* function cache of the native context. */                                  \
    366   V(int, next_serial_number, 0)                                                \
    367   V(ExternalReferenceRedirectorPointer*, external_reference_redirector, NULL)  \
    368   /* Part of the state of liveedit. */                                         \
    369   V(FunctionInfoListener*, active_function_info_listener, NULL)                \
    370   /* State for Relocatable. */                                                 \
    371   V(Relocatable*, relocatable_top, NULL)                                       \
    372   V(DebugObjectCache*, string_stream_debug_object_cache, NULL)                 \
    373   V(Object*, string_stream_current_security_token, NULL)                       \
    374   /* Serializer state. */                                                      \
    375   V(ExternalReferenceTable*, external_reference_table, NULL)                   \
    376   V(int, pending_microtask_count, 0)                                           \
    377   V(bool, autorun_microtasks, true)                                            \
    378   V(HStatistics*, hstatistics, NULL)                                           \
    379   V(HStatistics*, tstatistics, NULL)                                           \
    380   V(HTracer*, htracer, NULL)                                                   \
    381   V(CodeTracer*, code_tracer, NULL)                                            \
    382   V(bool, fp_stubs_generated, false)                                           \
    383   V(int, max_available_threads, 0)                                             \
    384   V(uint32_t, per_isolate_assert_data, 0xFFFFFFFFu)                            \
    385   V(InterruptCallback, api_interrupt_callback, NULL)                           \
    386   V(void*, api_interrupt_callback_data, NULL)                                  \
    387   ISOLATE_INIT_SIMULATOR_LIST(V)
    388 
    389 #define THREAD_LOCAL_TOP_ACCESSOR(type, name)                        \
    390   inline void set_##name(type v) { thread_local_top_.name##_ = v; }  \
    391   inline type name() const { return thread_local_top_.name##_; }
    392 
    393 
    394 class Isolate {
    395   // These forward declarations are required to make the friend declarations in
    396   // PerIsolateThreadData work on some older versions of gcc.
    397   class ThreadDataTable;
    398   class EntryStackItem;
    399  public:
    400   ~Isolate();
    401 
    402   // A thread has a PerIsolateThreadData instance for each isolate that it has
    403   // entered. That instance is allocated when the isolate is initially entered
    404   // and reused on subsequent entries.
    405   class PerIsolateThreadData {
    406    public:
    407     PerIsolateThreadData(Isolate* isolate, ThreadId thread_id)
    408         : isolate_(isolate),
    409           thread_id_(thread_id),
    410           stack_limit_(0),
    411           thread_state_(NULL),
    412 #if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
    413     !defined(__aarch64__) && V8_TARGET_ARCH_ARM64 || \
    414     !defined(__mips__) && V8_TARGET_ARCH_MIPS || \
    415     !defined(__mips__) && V8_TARGET_ARCH_MIPS64
    416           simulator_(NULL),
    417 #endif
    418           next_(NULL),
    419           prev_(NULL) { }
    420     ~PerIsolateThreadData();
    421     Isolate* isolate() const { return isolate_; }
    422     ThreadId thread_id() const { return thread_id_; }
    423 
    424     FIELD_ACCESSOR(uintptr_t, stack_limit)
    425     FIELD_ACCESSOR(ThreadState*, thread_state)
    426 
    427 #if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
    428     !defined(__aarch64__) && V8_TARGET_ARCH_ARM64 || \
    429     !defined(__mips__) && V8_TARGET_ARCH_MIPS || \
    430     !defined(__mips__) && V8_TARGET_ARCH_MIPS64
    431     FIELD_ACCESSOR(Simulator*, simulator)
    432 #endif
    433 
    434     bool Matches(Isolate* isolate, ThreadId thread_id) const {
    435       return isolate_ == isolate && thread_id_.Equals(thread_id);
    436     }
    437 
    438    private:
    439     Isolate* isolate_;
    440     ThreadId thread_id_;
    441     uintptr_t stack_limit_;
    442     ThreadState* thread_state_;
    443 
    444 #if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
    445     !defined(__aarch64__) && V8_TARGET_ARCH_ARM64 || \
    446     !defined(__mips__) && V8_TARGET_ARCH_MIPS || \
    447     !defined(__mips__) && V8_TARGET_ARCH_MIPS64
    448     Simulator* simulator_;
    449 #endif
    450 
    451     PerIsolateThreadData* next_;
    452     PerIsolateThreadData* prev_;
    453 
    454     friend class Isolate;
    455     friend class ThreadDataTable;
    456     friend class EntryStackItem;
    457 
    458     DISALLOW_COPY_AND_ASSIGN(PerIsolateThreadData);
    459   };
    460 
    461 
    462   enum AddressId {
    463 #define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address,
    464     FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM)
    465 #undef DECLARE_ENUM
    466     kIsolateAddressCount
    467   };
    468 
    469   static void InitializeOncePerProcess();
    470 
    471   // Returns the PerIsolateThreadData for the current thread (or NULL if one is
    472   // not currently set).
    473   static PerIsolateThreadData* CurrentPerIsolateThreadData() {
    474     return reinterpret_cast<PerIsolateThreadData*>(
    475         base::Thread::GetThreadLocal(per_isolate_thread_data_key_));
    476   }
    477 
    478   // Returns the isolate inside which the current thread is running.
    479   INLINE(static Isolate* Current()) {
    480     Isolate* isolate = reinterpret_cast<Isolate*>(
    481         base::Thread::GetExistingThreadLocal(isolate_key_));
    482     DCHECK(isolate != NULL);
    483     return isolate;
    484   }
    485 
    486   INLINE(static Isolate* UncheckedCurrent()) {
    487     return reinterpret_cast<Isolate*>(
    488         base::Thread::GetThreadLocal(isolate_key_));
    489   }
    490 
    491   // Like UncheckedCurrent, but skips the check that |isolate_key_| was
    492   // initialized. Callers have to ensure that themselves.
    493   INLINE(static Isolate* UnsafeCurrent()) {
    494     return reinterpret_cast<Isolate*>(
    495         base::Thread::GetThreadLocal(isolate_key_));
    496   }
    497 
    498   // Usually called by Init(), but can be called early e.g. to allow
    499   // testing components that require logging but not the whole
    500   // isolate.
    501   //
    502   // Safe to call more than once.
    503   void InitializeLoggingAndCounters();
    504 
    505   bool Init(Deserializer* des);
    506 
    507   bool IsInitialized() { return state_ == INITIALIZED; }
    508 
    509   // True if at least one thread Enter'ed this isolate.
    510   bool IsInUse() { return entry_stack_ != NULL; }
    511 
    512   // Destroys the non-default isolates.
    513   // Sets default isolate into "has_been_disposed" state rather then destroying,
    514   // for legacy API reasons.
    515   void TearDown();
    516 
    517   static void GlobalTearDown();
    518 
    519   // Find the PerThread for this particular (isolate, thread) combination
    520   // If one does not yet exist, return null.
    521   PerIsolateThreadData* FindPerThreadDataForThisThread();
    522 
    523   // Find the PerThread for given (isolate, thread) combination
    524   // If one does not yet exist, return null.
    525   PerIsolateThreadData* FindPerThreadDataForThread(ThreadId thread_id);
    526 
    527   // Returns the key used to store the pointer to the current isolate.
    528   // Used internally for V8 threads that do not execute JavaScript but still
    529   // are part of the domain of an isolate (like the context switcher).
    530   static base::Thread::LocalStorageKey isolate_key() {
    531     return isolate_key_;
    532   }
    533 
    534   // Returns the key used to store process-wide thread IDs.
    535   static base::Thread::LocalStorageKey thread_id_key() {
    536     return thread_id_key_;
    537   }
    538 
    539   static base::Thread::LocalStorageKey per_isolate_thread_data_key();
    540 
    541   // Mutex for serializing access to break control structures.
    542   base::RecursiveMutex* break_access() { return &break_access_; }
    543 
    544   Address get_address_from_id(AddressId id);
    545 
    546   // Access to top context (where the current function object was created).
    547   Context* context() { return thread_local_top_.context_; }
    548   void set_context(Context* context) {
    549     DCHECK(context == NULL || context->IsContext());
    550     thread_local_top_.context_ = context;
    551   }
    552   Context** context_address() { return &thread_local_top_.context_; }
    553 
    554   THREAD_LOCAL_TOP_ACCESSOR(SaveContext*, save_context)
    555 
    556   // Access to current thread id.
    557   THREAD_LOCAL_TOP_ACCESSOR(ThreadId, thread_id)
    558 
    559   // Interface to pending exception.
    560   Object* pending_exception() {
    561     DCHECK(has_pending_exception());
    562     DCHECK(!thread_local_top_.pending_exception_->IsException());
    563     return thread_local_top_.pending_exception_;
    564   }
    565 
    566   void set_pending_exception(Object* exception_obj) {
    567     DCHECK(!exception_obj->IsException());
    568     thread_local_top_.pending_exception_ = exception_obj;
    569   }
    570 
    571   void clear_pending_exception() {
    572     DCHECK(!thread_local_top_.pending_exception_->IsException());
    573     thread_local_top_.pending_exception_ = heap_.the_hole_value();
    574   }
    575 
    576   Object** pending_exception_address() {
    577     return &thread_local_top_.pending_exception_;
    578   }
    579 
    580   bool has_pending_exception() {
    581     DCHECK(!thread_local_top_.pending_exception_->IsException());
    582     return !thread_local_top_.pending_exception_->IsTheHole();
    583   }
    584 
    585   THREAD_LOCAL_TOP_ACCESSOR(bool, external_caught_exception)
    586 
    587   void clear_pending_message() {
    588     thread_local_top_.has_pending_message_ = false;
    589     thread_local_top_.pending_message_obj_ = heap_.the_hole_value();
    590     thread_local_top_.pending_message_script_ = heap_.the_hole_value();
    591   }
    592   v8::TryCatch* try_catch_handler() {
    593     return thread_local_top_.try_catch_handler();
    594   }
    595   Address try_catch_handler_address() {
    596     return thread_local_top_.try_catch_handler_address();
    597   }
    598   bool* external_caught_exception_address() {
    599     return &thread_local_top_.external_caught_exception_;
    600   }
    601 
    602   THREAD_LOCAL_TOP_ACCESSOR(v8::TryCatch*, catcher)
    603 
    604   Object** scheduled_exception_address() {
    605     return &thread_local_top_.scheduled_exception_;
    606   }
    607 
    608   Address pending_message_obj_address() {
    609     return reinterpret_cast<Address>(&thread_local_top_.pending_message_obj_);
    610   }
    611 
    612   Address has_pending_message_address() {
    613     return reinterpret_cast<Address>(&thread_local_top_.has_pending_message_);
    614   }
    615 
    616   Address pending_message_script_address() {
    617     return reinterpret_cast<Address>(
    618         &thread_local_top_.pending_message_script_);
    619   }
    620 
    621   Object* scheduled_exception() {
    622     DCHECK(has_scheduled_exception());
    623     DCHECK(!thread_local_top_.scheduled_exception_->IsException());
    624     return thread_local_top_.scheduled_exception_;
    625   }
    626   bool has_scheduled_exception() {
    627     DCHECK(!thread_local_top_.scheduled_exception_->IsException());
    628     return thread_local_top_.scheduled_exception_ != heap_.the_hole_value();
    629   }
    630   void clear_scheduled_exception() {
    631     DCHECK(!thread_local_top_.scheduled_exception_->IsException());
    632     thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
    633   }
    634 
    635   bool HasExternalTryCatch();
    636   bool IsFinallyOnTop();
    637 
    638   bool is_catchable_by_javascript(Object* exception) {
    639     return exception != heap()->termination_exception();
    640   }
    641 
    642   // Serializer.
    643   void PushToPartialSnapshotCache(Object* obj);
    644 
    645   // JS execution stack (see frames.h).
    646   static Address c_entry_fp(ThreadLocalTop* thread) {
    647     return thread->c_entry_fp_;
    648   }
    649   static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
    650 
    651   inline Address* c_entry_fp_address() {
    652     return &thread_local_top_.c_entry_fp_;
    653   }
    654   inline Address* handler_address() { return &thread_local_top_.handler_; }
    655 
    656   // Bottom JS entry.
    657   Address js_entry_sp() {
    658     return thread_local_top_.js_entry_sp_;
    659   }
    660   inline Address* js_entry_sp_address() {
    661     return &thread_local_top_.js_entry_sp_;
    662   }
    663 
    664   // Generated code scratch locations.
    665   void* formal_count_address() { return &thread_local_top_.formal_count_; }
    666 
    667   // Returns the global object of the current context. It could be
    668   // a builtin object, or a JS global object.
    669   Handle<GlobalObject> global_object() {
    670     return Handle<GlobalObject>(context()->global_object());
    671   }
    672 
    673   // Returns the global proxy object of the current context.
    674   JSObject* global_proxy() {
    675     return context()->global_proxy();
    676   }
    677 
    678   Handle<JSBuiltinsObject> js_builtins_object() {
    679     return Handle<JSBuiltinsObject>(thread_local_top_.context_->builtins());
    680   }
    681 
    682   static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
    683   void FreeThreadResources() { thread_local_top_.Free(); }
    684 
    685   // This method is called by the api after operations that may throw
    686   // exceptions.  If an exception was thrown and not handled by an external
    687   // handler the exception is scheduled to be rethrown when we return to running
    688   // JavaScript code.  If an exception is scheduled true is returned.
    689   bool OptionalRescheduleException(bool is_bottom_call);
    690 
    691   // Push and pop a promise and the current try-catch handler.
    692   void PushPromise(Handle<JSObject> promise);
    693   void PopPromise();
    694   Handle<Object> GetPromiseOnStackOnThrow();
    695 
    696   class ExceptionScope {
    697    public:
    698     explicit ExceptionScope(Isolate* isolate) :
    699       // Scope currently can only be used for regular exceptions,
    700       // not termination exception.
    701       isolate_(isolate),
    702       pending_exception_(isolate_->pending_exception(), isolate_),
    703       catcher_(isolate_->catcher())
    704     { }
    705 
    706     ~ExceptionScope() {
    707       isolate_->set_catcher(catcher_);
    708       isolate_->set_pending_exception(*pending_exception_);
    709     }
    710 
    711    private:
    712     Isolate* isolate_;
    713     Handle<Object> pending_exception_;
    714     v8::TryCatch* catcher_;
    715   };
    716 
    717   void SetCaptureStackTraceForUncaughtExceptions(
    718       bool capture,
    719       int frame_limit,
    720       StackTrace::StackTraceOptions options);
    721 
    722   void PrintCurrentStackTrace(FILE* out);
    723   void PrintStack(StringStream* accumulator);
    724   void PrintStack(FILE* out);
    725   Handle<String> StackTraceString();
    726   NO_INLINE(void PushStackTraceAndDie(unsigned int magic,
    727                                       Object* object,
    728                                       Map* map,
    729                                       unsigned int magic2));
    730   Handle<JSArray> CaptureCurrentStackTrace(
    731       int frame_limit,
    732       StackTrace::StackTraceOptions options);
    733   Handle<Object> CaptureSimpleStackTrace(Handle<JSObject> error_object,
    734                                          Handle<Object> caller);
    735   void CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object);
    736   void CaptureAndSetSimpleStackTrace(Handle<JSObject> error_object,
    737                                      Handle<Object> caller);
    738 
    739   // Returns if the top context may access the given global object. If
    740   // the result is false, the pending exception is guaranteed to be
    741   // set.
    742 
    743   bool MayNamedAccess(Handle<JSObject> receiver,
    744                       Handle<Object> key,
    745                       v8::AccessType type);
    746   bool MayIndexedAccess(Handle<JSObject> receiver,
    747                         uint32_t index,
    748                         v8::AccessType type);
    749 
    750   void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
    751   void ReportFailedAccessCheck(Handle<JSObject> receiver, v8::AccessType type);
    752 
    753   // Exception throwing support. The caller should use the result
    754   // of Throw() as its return value.
    755   Object* Throw(Object* exception, MessageLocation* location = NULL);
    756 
    757   template <typename T>
    758   MUST_USE_RESULT MaybeHandle<T> Throw(Handle<Object> exception,
    759                                        MessageLocation* location = NULL) {
    760     Throw(*exception, location);
    761     return MaybeHandle<T>();
    762   }
    763 
    764   // Re-throw an exception.  This involves no error reporting since
    765   // error reporting was handled when the exception was thrown
    766   // originally.
    767   Object* ReThrow(Object* exception);
    768   void ScheduleThrow(Object* exception);
    769   // Re-set pending message, script and positions reported to the TryCatch
    770   // back to the TLS for re-use when rethrowing.
    771   void RestorePendingMessageFromTryCatch(v8::TryCatch* handler);
    772   // Un-schedule an exception that was caught by a TryCatch handler.
    773   void CancelScheduledExceptionFromTryCatch(v8::TryCatch* handler);
    774   void ReportPendingMessages();
    775   // Return pending location if any or unfilled structure.
    776   MessageLocation GetMessageLocation();
    777   Object* ThrowIllegalOperation();
    778 
    779   // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
    780   Object* PromoteScheduledException();
    781   void DoThrow(Object* exception, MessageLocation* location);
    782   // Checks if exception should be reported and finds out if it's
    783   // caught externally.
    784   bool ShouldReportException(bool* can_be_caught_externally,
    785                              bool catchable_by_javascript);
    786 
    787   // Attempts to compute the current source location, storing the
    788   // result in the target out parameter.
    789   void ComputeLocation(MessageLocation* target);
    790 
    791   // Out of resource exception helpers.
    792   Object* StackOverflow();
    793   Object* TerminateExecution();
    794   void CancelTerminateExecution();
    795 
    796   void InvokeApiInterruptCallback();
    797 
    798   // Administration
    799   void Iterate(ObjectVisitor* v);
    800   void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
    801   char* Iterate(ObjectVisitor* v, char* t);
    802   void IterateThread(ThreadVisitor* v, char* t);
    803 
    804 
    805   // Returns the current native and global context.
    806   Handle<Context> native_context();
    807   Handle<Context> global_context();
    808 
    809   // Returns the native context of the calling JavaScript code.  That
    810   // is, the native context of the top-most JavaScript frame.
    811   Handle<Context> GetCallingNativeContext();
    812 
    813   void RegisterTryCatchHandler(v8::TryCatch* that);
    814   void UnregisterTryCatchHandler(v8::TryCatch* that);
    815 
    816   char* ArchiveThread(char* to);
    817   char* RestoreThread(char* from);
    818 
    819   static const char* const kStackOverflowMessage;
    820 
    821   static const int kUC16AlphabetSize = 256;  // See StringSearchBase.
    822   static const int kBMMaxShift = 250;        // See StringSearchBase.
    823 
    824   // Accessors.
    825 #define GLOBAL_ACCESSOR(type, name, initialvalue)                       \
    826   inline type name() const {                                            \
    827     DCHECK(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
    828     return name##_;                                                     \
    829   }                                                                     \
    830   inline void set_##name(type value) {                                  \
    831     DCHECK(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
    832     name##_ = value;                                                    \
    833   }
    834   ISOLATE_INIT_LIST(GLOBAL_ACCESSOR)
    835 #undef GLOBAL_ACCESSOR
    836 
    837 #define GLOBAL_ARRAY_ACCESSOR(type, name, length)                       \
    838   inline type* name() {                                                 \
    839     DCHECK(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
    840     return &(name##_)[0];                                               \
    841   }
    842   ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR)
    843 #undef GLOBAL_ARRAY_ACCESSOR
    844 
    845 #define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name)            \
    846   Handle<type> name() {                                             \
    847     return Handle<type>(native_context()->name(), this);            \
    848   }                                                                 \
    849   bool is_##name(type* value) {                                     \
    850     return native_context()->is_##name(value);                      \
    851   }
    852   NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR)
    853 #undef NATIVE_CONTEXT_FIELD_ACCESSOR
    854 
    855   Bootstrapper* bootstrapper() { return bootstrapper_; }
    856   Counters* counters() {
    857     // Call InitializeLoggingAndCounters() if logging is needed before
    858     // the isolate is fully initialized.
    859     DCHECK(counters_ != NULL);
    860     return counters_;
    861   }
    862   CodeRange* code_range() { return code_range_; }
    863   RuntimeProfiler* runtime_profiler() { return runtime_profiler_; }
    864   CompilationCache* compilation_cache() { return compilation_cache_; }
    865   Logger* logger() {
    866     // Call InitializeLoggingAndCounters() if logging is needed before
    867     // the isolate is fully initialized.
    868     DCHECK(logger_ != NULL);
    869     return logger_;
    870   }
    871   StackGuard* stack_guard() { return &stack_guard_; }
    872   Heap* heap() { return &heap_; }
    873   StatsTable* stats_table();
    874   StubCache* stub_cache() { return stub_cache_; }
    875   CodeAgingHelper* code_aging_helper() { return code_aging_helper_; }
    876   DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
    877   ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
    878   MaterializedObjectStore* materialized_object_store() {
    879     return materialized_object_store_;
    880   }
    881 
    882   MemoryAllocator* memory_allocator() {
    883     return memory_allocator_;
    884   }
    885 
    886   KeyedLookupCache* keyed_lookup_cache() {
    887     return keyed_lookup_cache_;
    888   }
    889 
    890   ContextSlotCache* context_slot_cache() {
    891     return context_slot_cache_;
    892   }
    893 
    894   DescriptorLookupCache* descriptor_lookup_cache() {
    895     return descriptor_lookup_cache_;
    896   }
    897 
    898   HandleScopeData* handle_scope_data() { return &handle_scope_data_; }
    899 
    900   HandleScopeImplementer* handle_scope_implementer() {
    901     DCHECK(handle_scope_implementer_);
    902     return handle_scope_implementer_;
    903   }
    904   Zone* runtime_zone() { return &runtime_zone_; }
    905 
    906   UnicodeCache* unicode_cache() {
    907     return unicode_cache_;
    908   }
    909 
    910   InnerPointerToCodeCache* inner_pointer_to_code_cache() {
    911     return inner_pointer_to_code_cache_;
    912   }
    913 
    914   ConsStringIteratorOp* write_iterator() { return write_iterator_; }
    915 
    916   GlobalHandles* global_handles() { return global_handles_; }
    917 
    918   EternalHandles* eternal_handles() { return eternal_handles_; }
    919 
    920   ThreadManager* thread_manager() { return thread_manager_; }
    921 
    922   StringTracker* string_tracker() { return string_tracker_; }
    923 
    924   unibrow::Mapping<unibrow::Ecma262UnCanonicalize>* jsregexp_uncanonicalize() {
    925     return &jsregexp_uncanonicalize_;
    926   }
    927 
    928   unibrow::Mapping<unibrow::CanonicalizationRange>* jsregexp_canonrange() {
    929     return &jsregexp_canonrange_;
    930   }
    931 
    932   ConsStringIteratorOp* objects_string_compare_iterator_a() {
    933     return &objects_string_compare_iterator_a_;
    934   }
    935 
    936   ConsStringIteratorOp* objects_string_compare_iterator_b() {
    937     return &objects_string_compare_iterator_b_;
    938   }
    939 
    940   StaticResource<ConsStringIteratorOp>* objects_string_iterator() {
    941     return &objects_string_iterator_;
    942   }
    943 
    944   RuntimeState* runtime_state() { return &runtime_state_; }
    945 
    946   Builtins* builtins() { return &builtins_; }
    947 
    948   void NotifyExtensionInstalled() {
    949     has_installed_extensions_ = true;
    950   }
    951 
    952   bool has_installed_extensions() { return has_installed_extensions_; }
    953 
    954   unibrow::Mapping<unibrow::Ecma262Canonicalize>*
    955       regexp_macro_assembler_canonicalize() {
    956     return &regexp_macro_assembler_canonicalize_;
    957   }
    958 
    959   RegExpStack* regexp_stack() { return regexp_stack_; }
    960 
    961   unibrow::Mapping<unibrow::Ecma262Canonicalize>*
    962       interp_canonicalize_mapping() {
    963     return &interp_canonicalize_mapping_;
    964   }
    965 
    966   Debug* debug() { return debug_; }
    967 
    968   inline bool DebuggerHasBreakPoints();
    969 
    970   CpuProfiler* cpu_profiler() const { return cpu_profiler_; }
    971   HeapProfiler* heap_profiler() const { return heap_profiler_; }
    972 
    973 #ifdef DEBUG
    974   HistogramInfo* heap_histograms() { return heap_histograms_; }
    975 
    976   JSObject::SpillInformation* js_spill_information() {
    977     return &js_spill_information_;
    978   }
    979 #endif
    980 
    981   Factory* factory() { return reinterpret_cast<Factory*>(this); }
    982 
    983   static const int kJSRegexpStaticOffsetsVectorSize = 128;
    984 
    985   THREAD_LOCAL_TOP_ACCESSOR(ExternalCallbackScope*, external_callback_scope)
    986 
    987   THREAD_LOCAL_TOP_ACCESSOR(StateTag, current_vm_state)
    988 
    989   void SetData(uint32_t slot, void* data) {
    990     DCHECK(slot < Internals::kNumIsolateDataSlots);
    991     embedder_data_[slot] = data;
    992   }
    993   void* GetData(uint32_t slot) {
    994     DCHECK(slot < Internals::kNumIsolateDataSlots);
    995     return embedder_data_[slot];
    996   }
    997 
    998   THREAD_LOCAL_TOP_ACCESSOR(LookupResult*, top_lookup_result)
    999 
   1000   void enable_serializer() {
   1001     // The serializer can only be enabled before the isolate init.
   1002     DCHECK(state_ != INITIALIZED);
   1003     serializer_enabled_ = true;
   1004   }
   1005 
   1006   bool serializer_enabled() const { return serializer_enabled_; }
   1007 
   1008   bool IsDead() { return has_fatal_error_; }
   1009   void SignalFatalError() { has_fatal_error_ = true; }
   1010 
   1011   bool use_crankshaft() const;
   1012 
   1013   bool initialized_from_snapshot() { return initialized_from_snapshot_; }
   1014 
   1015   double time_millis_since_init() {
   1016     return base::OS::TimeCurrentMillis() - time_millis_at_init_;
   1017   }
   1018 
   1019   DateCache* date_cache() {
   1020     return date_cache_;
   1021   }
   1022 
   1023   void set_date_cache(DateCache* date_cache) {
   1024     if (date_cache != date_cache_) {
   1025       delete date_cache_;
   1026     }
   1027     date_cache_ = date_cache;
   1028   }
   1029 
   1030   Map* get_initial_js_array_map(ElementsKind kind);
   1031 
   1032   bool IsFastArrayConstructorPrototypeChainIntact();
   1033 
   1034   CallInterfaceDescriptorData* call_descriptor_data(int index);
   1035 
   1036   void IterateDeferredHandles(ObjectVisitor* visitor);
   1037   void LinkDeferredHandles(DeferredHandles* deferred_handles);
   1038   void UnlinkDeferredHandles(DeferredHandles* deferred_handles);
   1039 
   1040 #ifdef DEBUG
   1041   bool IsDeferredHandle(Object** location);
   1042 #endif  // DEBUG
   1043 
   1044   bool concurrent_recompilation_enabled() {
   1045     // Thread is only available with flag enabled.
   1046     DCHECK(optimizing_compiler_thread_ == NULL ||
   1047            FLAG_concurrent_recompilation);
   1048     return optimizing_compiler_thread_ != NULL;
   1049   }
   1050 
   1051   bool concurrent_osr_enabled() const {
   1052     // Thread is only available with flag enabled.
   1053     DCHECK(optimizing_compiler_thread_ == NULL ||
   1054            FLAG_concurrent_recompilation);
   1055     return optimizing_compiler_thread_ != NULL && FLAG_concurrent_osr;
   1056   }
   1057 
   1058   OptimizingCompilerThread* optimizing_compiler_thread() {
   1059     return optimizing_compiler_thread_;
   1060   }
   1061 
   1062   int num_sweeper_threads() const {
   1063     return num_sweeper_threads_;
   1064   }
   1065 
   1066   SweeperThread** sweeper_threads() {
   1067     return sweeper_thread_;
   1068   }
   1069 
   1070   int id() const { return static_cast<int>(id_); }
   1071 
   1072   HStatistics* GetHStatistics();
   1073   HStatistics* GetTStatistics();
   1074   HTracer* GetHTracer();
   1075   CodeTracer* GetCodeTracer();
   1076 
   1077   FunctionEntryHook function_entry_hook() { return function_entry_hook_; }
   1078   void set_function_entry_hook(FunctionEntryHook function_entry_hook) {
   1079     function_entry_hook_ = function_entry_hook;
   1080   }
   1081 
   1082   void* stress_deopt_count_address() { return &stress_deopt_count_; }
   1083 
   1084   inline base::RandomNumberGenerator* random_number_generator();
   1085 
   1086   // Given an address occupied by a live code object, return that object.
   1087   Object* FindCodeObject(Address a);
   1088 
   1089   int NextOptimizationId() {
   1090     int id = next_optimization_id_++;
   1091     if (!Smi::IsValid(next_optimization_id_)) {
   1092       next_optimization_id_ = 0;
   1093     }
   1094     return id;
   1095   }
   1096 
   1097   // Get (and lazily initialize) the registry for per-isolate symbols.
   1098   Handle<JSObject> GetSymbolRegistry();
   1099 
   1100   void AddCallCompletedCallback(CallCompletedCallback callback);
   1101   void RemoveCallCompletedCallback(CallCompletedCallback callback);
   1102   void FireCallCompletedCallback();
   1103 
   1104   void EnqueueMicrotask(Handle<Object> microtask);
   1105   void RunMicrotasks();
   1106 
   1107   void SetUseCounterCallback(v8::Isolate::UseCounterCallback callback);
   1108   void CountUsage(v8::Isolate::UseCounterFeature feature);
   1109 
   1110   static Isolate* NewForTesting() { return new Isolate(); }
   1111 
   1112  private:
   1113   Isolate();
   1114 
   1115   friend struct GlobalState;
   1116   friend struct InitializeGlobalState;
   1117 
   1118   enum State {
   1119     UNINITIALIZED,    // Some components may not have been allocated.
   1120     INITIALIZED       // All components are fully initialized.
   1121   };
   1122 
   1123   // These fields are accessed through the API, offsets must be kept in sync
   1124   // with v8::internal::Internals (in include/v8.h) constants. This is also
   1125   // verified in Isolate::Init() using runtime checks.
   1126   void* embedder_data_[Internals::kNumIsolateDataSlots];
   1127   Heap heap_;
   1128   State state_;  // Will be padded to kApiPointerSize.
   1129 
   1130   // The per-process lock should be acquired before the ThreadDataTable is
   1131   // modified.
   1132   class ThreadDataTable {
   1133    public:
   1134     ThreadDataTable();
   1135     ~ThreadDataTable();
   1136 
   1137     PerIsolateThreadData* Lookup(Isolate* isolate, ThreadId thread_id);
   1138     void Insert(PerIsolateThreadData* data);
   1139     void Remove(PerIsolateThreadData* data);
   1140     void RemoveAllThreads(Isolate* isolate);
   1141 
   1142    private:
   1143     PerIsolateThreadData* list_;
   1144   };
   1145 
   1146   // These items form a stack synchronously with threads Enter'ing and Exit'ing
   1147   // the Isolate. The top of the stack points to a thread which is currently
   1148   // running the Isolate. When the stack is empty, the Isolate is considered
   1149   // not entered by any thread and can be Disposed.
   1150   // If the same thread enters the Isolate more then once, the entry_count_
   1151   // is incremented rather then a new item pushed to the stack.
   1152   class EntryStackItem {
   1153    public:
   1154     EntryStackItem(PerIsolateThreadData* previous_thread_data,
   1155                    Isolate* previous_isolate,
   1156                    EntryStackItem* previous_item)
   1157         : entry_count(1),
   1158           previous_thread_data(previous_thread_data),
   1159           previous_isolate(previous_isolate),
   1160           previous_item(previous_item) { }
   1161 
   1162     int entry_count;
   1163     PerIsolateThreadData* previous_thread_data;
   1164     Isolate* previous_isolate;
   1165     EntryStackItem* previous_item;
   1166 
   1167    private:
   1168     DISALLOW_COPY_AND_ASSIGN(EntryStackItem);
   1169   };
   1170 
   1171   static base::LazyMutex thread_data_table_mutex_;
   1172 
   1173   static base::Thread::LocalStorageKey per_isolate_thread_data_key_;
   1174   static base::Thread::LocalStorageKey isolate_key_;
   1175   static base::Thread::LocalStorageKey thread_id_key_;
   1176   static ThreadDataTable* thread_data_table_;
   1177 
   1178   // A global counter for all generated Isolates, might overflow.
   1179   static base::Atomic32 isolate_counter_;
   1180 
   1181   void Deinit();
   1182 
   1183   static void SetIsolateThreadLocals(Isolate* isolate,
   1184                                      PerIsolateThreadData* data);
   1185 
   1186   // Find the PerThread for this particular (isolate, thread) combination.
   1187   // If one does not yet exist, allocate a new one.
   1188   PerIsolateThreadData* FindOrAllocatePerThreadDataForThisThread();
   1189 
   1190   // Initializes the current thread to run this Isolate.
   1191   // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
   1192   // at the same time, this should be prevented using external locking.
   1193   void Enter();
   1194 
   1195   // Exits the current thread. The previosuly entered Isolate is restored
   1196   // for the thread.
   1197   // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
   1198   // at the same time, this should be prevented using external locking.
   1199   void Exit();
   1200 
   1201   void InitializeThreadLocal();
   1202 
   1203   void MarkCompactPrologue(bool is_compacting,
   1204                            ThreadLocalTop* archived_thread_data);
   1205   void MarkCompactEpilogue(bool is_compacting,
   1206                            ThreadLocalTop* archived_thread_data);
   1207 
   1208   void FillCache();
   1209 
   1210   // Propagate pending exception message to the v8::TryCatch.
   1211   // If there is no external try-catch or message was successfully propagated,
   1212   // then return true.
   1213   bool PropagatePendingExceptionToExternalTryCatch();
   1214 
   1215   // Traverse prototype chain to find out whether the object is derived from
   1216   // the Error object.
   1217   bool IsErrorObject(Handle<Object> obj);
   1218 
   1219   base::Atomic32 id_;
   1220   EntryStackItem* entry_stack_;
   1221   int stack_trace_nesting_level_;
   1222   StringStream* incomplete_message_;
   1223   Address isolate_addresses_[kIsolateAddressCount + 1];  // NOLINT
   1224   Bootstrapper* bootstrapper_;
   1225   RuntimeProfiler* runtime_profiler_;
   1226   CompilationCache* compilation_cache_;
   1227   Counters* counters_;
   1228   CodeRange* code_range_;
   1229   base::RecursiveMutex break_access_;
   1230   base::Atomic32 debugger_initialized_;
   1231   Logger* logger_;
   1232   StackGuard stack_guard_;
   1233   StatsTable* stats_table_;
   1234   StubCache* stub_cache_;
   1235   CodeAgingHelper* code_aging_helper_;
   1236   DeoptimizerData* deoptimizer_data_;
   1237   MaterializedObjectStore* materialized_object_store_;
   1238   ThreadLocalTop thread_local_top_;
   1239   bool capture_stack_trace_for_uncaught_exceptions_;
   1240   int stack_trace_for_uncaught_exceptions_frame_limit_;
   1241   StackTrace::StackTraceOptions stack_trace_for_uncaught_exceptions_options_;
   1242   MemoryAllocator* memory_allocator_;
   1243   KeyedLookupCache* keyed_lookup_cache_;
   1244   ContextSlotCache* context_slot_cache_;
   1245   DescriptorLookupCache* descriptor_lookup_cache_;
   1246   HandleScopeData handle_scope_data_;
   1247   HandleScopeImplementer* handle_scope_implementer_;
   1248   UnicodeCache* unicode_cache_;
   1249   Zone runtime_zone_;
   1250   InnerPointerToCodeCache* inner_pointer_to_code_cache_;
   1251   ConsStringIteratorOp* write_iterator_;
   1252   GlobalHandles* global_handles_;
   1253   EternalHandles* eternal_handles_;
   1254   ThreadManager* thread_manager_;
   1255   RuntimeState runtime_state_;
   1256   Builtins builtins_;
   1257   bool has_installed_extensions_;
   1258   StringTracker* string_tracker_;
   1259   unibrow::Mapping<unibrow::Ecma262UnCanonicalize> jsregexp_uncanonicalize_;
   1260   unibrow::Mapping<unibrow::CanonicalizationRange> jsregexp_canonrange_;
   1261   ConsStringIteratorOp objects_string_compare_iterator_a_;
   1262   ConsStringIteratorOp objects_string_compare_iterator_b_;
   1263   StaticResource<ConsStringIteratorOp> objects_string_iterator_;
   1264   unibrow::Mapping<unibrow::Ecma262Canonicalize>
   1265       regexp_macro_assembler_canonicalize_;
   1266   RegExpStack* regexp_stack_;
   1267   DateCache* date_cache_;
   1268   unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
   1269   CallInterfaceDescriptorData* call_descriptor_data_;
   1270   base::RandomNumberGenerator* random_number_generator_;
   1271 
   1272   // Whether the isolate has been created for snapshotting.
   1273   bool serializer_enabled_;
   1274 
   1275   // True if fatal error has been signaled for this isolate.
   1276   bool has_fatal_error_;
   1277 
   1278   // True if this isolate was initialized from a snapshot.
   1279   bool initialized_from_snapshot_;
   1280 
   1281   // Time stamp at initialization.
   1282   double time_millis_at_init_;
   1283 
   1284 #ifdef DEBUG
   1285   // A static array of histogram info for each type.
   1286   HistogramInfo heap_histograms_[LAST_TYPE + 1];
   1287   JSObject::SpillInformation js_spill_information_;
   1288 #endif
   1289 
   1290   Debug* debug_;
   1291   CpuProfiler* cpu_profiler_;
   1292   HeapProfiler* heap_profiler_;
   1293   FunctionEntryHook function_entry_hook_;
   1294 
   1295 #define GLOBAL_BACKING_STORE(type, name, initialvalue)                         \
   1296   type name##_;
   1297   ISOLATE_INIT_LIST(GLOBAL_BACKING_STORE)
   1298 #undef GLOBAL_BACKING_STORE
   1299 
   1300 #define GLOBAL_ARRAY_BACKING_STORE(type, name, length)                         \
   1301   type name##_[length];
   1302   ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_BACKING_STORE)
   1303 #undef GLOBAL_ARRAY_BACKING_STORE
   1304 
   1305 #ifdef DEBUG
   1306   // This class is huge and has a number of fields controlled by
   1307   // preprocessor defines. Make sure the offsets of these fields agree
   1308   // between compilation units.
   1309 #define ISOLATE_FIELD_OFFSET(type, name, ignored)                              \
   1310   static const intptr_t name##_debug_offset_;
   1311   ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
   1312   ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
   1313 #undef ISOLATE_FIELD_OFFSET
   1314 #endif
   1315 
   1316   DeferredHandles* deferred_handles_head_;
   1317   OptimizingCompilerThread* optimizing_compiler_thread_;
   1318   SweeperThread** sweeper_thread_;
   1319   int num_sweeper_threads_;
   1320 
   1321   // Counts deopt points if deopt_every_n_times is enabled.
   1322   unsigned int stress_deopt_count_;
   1323 
   1324   int next_optimization_id_;
   1325 
   1326   // List of callbacks when a Call completes.
   1327   List<CallCompletedCallback> call_completed_callbacks_;
   1328 
   1329   v8::Isolate::UseCounterCallback use_counter_callback_;
   1330 
   1331   friend class ExecutionAccess;
   1332   friend class HandleScopeImplementer;
   1333   friend class IsolateInitializer;
   1334   friend class OptimizingCompilerThread;
   1335   friend class SweeperThread;
   1336   friend class ThreadManager;
   1337   friend class Simulator;
   1338   friend class StackGuard;
   1339   friend class ThreadId;
   1340   friend class TestMemoryAllocatorScope;
   1341   friend class TestCodeRangeScope;
   1342   friend class v8::Isolate;
   1343   friend class v8::Locker;
   1344   friend class v8::Unlocker;
   1345 
   1346   DISALLOW_COPY_AND_ASSIGN(Isolate);
   1347 };
   1348 
   1349 
   1350 #undef FIELD_ACCESSOR
   1351 #undef THREAD_LOCAL_TOP_ACCESSOR
   1352 
   1353 
   1354 class PromiseOnStack {
   1355  public:
   1356   PromiseOnStack(StackHandler* handler, Handle<JSObject> promise,
   1357                  PromiseOnStack* prev)
   1358       : handler_(handler), promise_(promise), prev_(prev) {}
   1359   StackHandler* handler() { return handler_; }
   1360   Handle<JSObject> promise() { return promise_; }
   1361   PromiseOnStack* prev() { return prev_; }
   1362 
   1363  private:
   1364   StackHandler* handler_;
   1365   Handle<JSObject> promise_;
   1366   PromiseOnStack* prev_;
   1367 };
   1368 
   1369 
   1370 // If the GCC version is 4.1.x or 4.2.x an additional field is added to the
   1371 // class as a work around for a bug in the generated code found with these
   1372 // versions of GCC. See V8 issue 122 for details.
   1373 class SaveContext BASE_EMBEDDED {
   1374  public:
   1375   inline explicit SaveContext(Isolate* isolate);
   1376 
   1377   ~SaveContext() {
   1378     isolate_->set_context(context_.is_null() ? NULL : *context_);
   1379     isolate_->set_save_context(prev_);
   1380   }
   1381 
   1382   Handle<Context> context() { return context_; }
   1383   SaveContext* prev() { return prev_; }
   1384 
   1385   // Returns true if this save context is below a given JavaScript frame.
   1386   bool IsBelowFrame(JavaScriptFrame* frame) {
   1387     return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp());
   1388   }
   1389 
   1390  private:
   1391   Isolate* isolate_;
   1392   Handle<Context> context_;
   1393   SaveContext* prev_;
   1394   Address c_entry_fp_;
   1395 };
   1396 
   1397 
   1398 class AssertNoContextChange BASE_EMBEDDED {
   1399 #ifdef DEBUG
   1400  public:
   1401   explicit AssertNoContextChange(Isolate* isolate)
   1402     : isolate_(isolate),
   1403       context_(isolate->context(), isolate) { }
   1404   ~AssertNoContextChange() {
   1405     DCHECK(isolate_->context() == *context_);
   1406   }
   1407 
   1408  private:
   1409   Isolate* isolate_;
   1410   Handle<Context> context_;
   1411 #else
   1412  public:
   1413   explicit AssertNoContextChange(Isolate* isolate) { }
   1414 #endif
   1415 };
   1416 
   1417 
   1418 class ExecutionAccess BASE_EMBEDDED {
   1419  public:
   1420   explicit ExecutionAccess(Isolate* isolate) : isolate_(isolate) {
   1421     Lock(isolate);
   1422   }
   1423   ~ExecutionAccess() { Unlock(isolate_); }
   1424 
   1425   static void Lock(Isolate* isolate) { isolate->break_access()->Lock(); }
   1426   static void Unlock(Isolate* isolate) { isolate->break_access()->Unlock(); }
   1427 
   1428   static bool TryLock(Isolate* isolate) {
   1429     return isolate->break_access()->TryLock();
   1430   }
   1431 
   1432  private:
   1433   Isolate* isolate_;
   1434 };
   1435 
   1436 
   1437 // Support for checking for stack-overflows.
   1438 class StackLimitCheck BASE_EMBEDDED {
   1439  public:
   1440   explicit StackLimitCheck(Isolate* isolate) : isolate_(isolate) { }
   1441 
   1442   // Use this to check for stack-overflows in C++ code.
   1443   inline bool HasOverflowed() const {
   1444     StackGuard* stack_guard = isolate_->stack_guard();
   1445     return GetCurrentStackPosition() < stack_guard->real_climit();
   1446   }
   1447 
   1448   // Use this to check for stack-overflow when entering runtime from JS code.
   1449   bool JsHasOverflowed() const;
   1450 
   1451  private:
   1452   Isolate* isolate_;
   1453 };
   1454 
   1455 
   1456 // Support for temporarily postponing interrupts. When the outermost
   1457 // postpone scope is left the interrupts will be re-enabled and any
   1458 // interrupts that occurred while in the scope will be taken into
   1459 // account.
   1460 class PostponeInterruptsScope BASE_EMBEDDED {
   1461  public:
   1462   PostponeInterruptsScope(Isolate* isolate,
   1463                           int intercept_mask = StackGuard::ALL_INTERRUPTS)
   1464       : stack_guard_(isolate->stack_guard()),
   1465         intercept_mask_(intercept_mask),
   1466         intercepted_flags_(0) {
   1467     stack_guard_->PushPostponeInterruptsScope(this);
   1468   }
   1469 
   1470   ~PostponeInterruptsScope() {
   1471     stack_guard_->PopPostponeInterruptsScope();
   1472   }
   1473 
   1474   // Find the bottom-most scope that intercepts this interrupt.
   1475   // Return whether the interrupt has been intercepted.
   1476   bool Intercept(StackGuard::InterruptFlag flag);
   1477 
   1478  private:
   1479   StackGuard* stack_guard_;
   1480   int intercept_mask_;
   1481   int intercepted_flags_;
   1482   PostponeInterruptsScope* prev_;
   1483 
   1484   friend class StackGuard;
   1485 };
   1486 
   1487 
   1488 class CodeTracer FINAL : public Malloced {
   1489  public:
   1490   explicit CodeTracer(int isolate_id)
   1491       : file_(NULL),
   1492         scope_depth_(0) {
   1493     if (!ShouldRedirect()) {
   1494       file_ = stdout;
   1495       return;
   1496     }
   1497 
   1498     if (FLAG_redirect_code_traces_to == NULL) {
   1499       SNPrintF(filename_,
   1500                "code-%d-%d.asm",
   1501                base::OS::GetCurrentProcessId(),
   1502                isolate_id);
   1503     } else {
   1504       StrNCpy(filename_, FLAG_redirect_code_traces_to, filename_.length());
   1505     }
   1506 
   1507     WriteChars(filename_.start(), "", 0, false);
   1508   }
   1509 
   1510   class Scope {
   1511    public:
   1512     explicit Scope(CodeTracer* tracer) : tracer_(tracer) { tracer->OpenFile(); }
   1513     ~Scope() { tracer_->CloseFile();  }
   1514 
   1515     FILE* file() const { return tracer_->file(); }
   1516 
   1517    private:
   1518     CodeTracer* tracer_;
   1519   };
   1520 
   1521   void OpenFile() {
   1522     if (!ShouldRedirect()) {
   1523       return;
   1524     }
   1525 
   1526     if (file_ == NULL) {
   1527       file_ = base::OS::FOpen(filename_.start(), "a");
   1528     }
   1529 
   1530     scope_depth_++;
   1531   }
   1532 
   1533   void CloseFile() {
   1534     if (!ShouldRedirect()) {
   1535       return;
   1536     }
   1537 
   1538     if (--scope_depth_ == 0) {
   1539       fclose(file_);
   1540       file_ = NULL;
   1541     }
   1542   }
   1543 
   1544   FILE* file() const { return file_; }
   1545 
   1546  private:
   1547   static bool ShouldRedirect() {
   1548     return FLAG_redirect_code_traces;
   1549   }
   1550 
   1551   EmbeddedVector<char, 128> filename_;
   1552   FILE* file_;
   1553   int scope_depth_;
   1554 };
   1555 
   1556 } }  // namespace v8::internal
   1557 
   1558 #endif  // V8_ISOLATE_H_
   1559