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