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