• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
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.
Current()231   static ThreadId Current() { return ThreadId(GetCurrentThreadId()); }
232 
233   // Returns invalid ThreadId (guaranteed not to be equal to any thread).
Invalid()234   static ThreadId Invalid() { return ThreadId(kInvalidId); }
235 
236   // Compares ThreadIds for equality.
INLINE(bool Equals (const ThreadId & other)const)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.
INLINE(bool IsValid ()const)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).
ToInteger()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).
FromInteger(int id)252   static ThreadId FromInteger(int id) { return ThreadId(id); }
253 
254  private:
255   static const int kInvalidId = -1;
256 
ThreadId(int id)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.
FIELD_ACCESSOR(v8::TryCatch *,try_catch_handler)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:
PerIsolateThreadData(Isolate * isolate,ThreadId thread_id)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();
isolate()461     Isolate* isolate() const { return isolate_; }
thread_id()462     ThreadId thread_id() const { return thread_id_; }
463 
FIELD_ACCESSOR(uintptr_t,stack_limit)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).
CurrentPerIsolateThreadData()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.
INLINE(static Isolate * Current ())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.
IsInUse()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).
isolate_key()557   static base::Thread::LocalStorageKey isolate_key() {
558     return isolate_key_;
559   }
560 
561   // Returns the key used to store process-wide thread IDs.
thread_id_key()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.
break_access()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).
context()574   Context* context() { return thread_local_top_.context_; }
575   inline void set_context(Context* context);
context_address()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 
THREAD_LOCAL_TOP_ADDRESS(Context *,pending_handler_context)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   }
external_caught_exception_address()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();
pending_message_obj_address()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).
c_entry_fp(ThreadLocalTop * thread)624   static Address c_entry_fp(ThreadLocalTop* thread) {
625     return thread->c_entry_fp_;
626   }
handler(ThreadLocalTop * thread)627   static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
c_function()628   Address c_function() { return thread_local_top_.c_function_; }
629 
c_entry_fp_address()630   inline Address* c_entry_fp_address() {
631     return &thread_local_top_.c_entry_fp_;
632   }
handler_address()633   inline Address* handler_address() { return &thread_local_top_.handler_; }
c_function_address()634   inline Address* c_function_address() {
635     return &thread_local_top_.c_function_;
636   }
637 
638   // Bottom JS entry.
js_entry_sp()639   Address js_entry_sp() {
640     return thread_local_top_.js_entry_sp_;
641   }
js_entry_sp_address()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 
ArchiveSpacePerThread()653   static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
FreeThreadResources()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   }
ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR)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_; }
counters()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   }
runtime_profiler()831   RuntimeProfiler* runtime_profiler() { return runtime_profiler_; }
compilation_cache()832   CompilationCache* compilation_cache() { return compilation_cache_; }
logger()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   }
stack_guard()839   StackGuard* stack_guard() { return &stack_guard_; }
heap()840   Heap* heap() { return &heap_; }
841   StatsTable* stats_table();
stub_cache()842   StubCache* stub_cache() { return stub_cache_; }
code_aging_helper()843   CodeAgingHelper* code_aging_helper() { return code_aging_helper_; }
deoptimizer_data()844   DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
deoptimizer_lazy_throw()845   bool deoptimizer_lazy_throw() const { return deoptimizer_lazy_throw_; }
set_deoptimizer_lazy_throw(bool value)846   void set_deoptimizer_lazy_throw(bool value) {
847     deoptimizer_lazy_throw_ = value;
848   }
thread_local_top()849   ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
materialized_object_store()850   MaterializedObjectStore* materialized_object_store() {
851     return materialized_object_store_;
852   }
853 
keyed_lookup_cache()854   KeyedLookupCache* keyed_lookup_cache() {
855     return keyed_lookup_cache_;
856   }
857 
context_slot_cache()858   ContextSlotCache* context_slot_cache() {
859     return context_slot_cache_;
860   }
861 
descriptor_lookup_cache()862   DescriptorLookupCache* descriptor_lookup_cache() {
863     return descriptor_lookup_cache_;
864   }
865 
handle_scope_data()866   HandleScopeData* handle_scope_data() { return &handle_scope_data_; }
867 
handle_scope_implementer()868   HandleScopeImplementer* handle_scope_implementer() {
869     DCHECK(handle_scope_implementer_);
870     return handle_scope_implementer_;
871   }
runtime_zone()872   Zone* runtime_zone() { return &runtime_zone_; }
interface_descriptor_zone()873   Zone* interface_descriptor_zone() { return &interface_descriptor_zone_; }
874 
unicode_cache()875   UnicodeCache* unicode_cache() {
876     return unicode_cache_;
877   }
878 
inner_pointer_to_code_cache()879   InnerPointerToCodeCache* inner_pointer_to_code_cache() {
880     return inner_pointer_to_code_cache_;
881   }
882 
global_handles()883   GlobalHandles* global_handles() { return global_handles_; }
884 
eternal_handles()885   EternalHandles* eternal_handles() { return eternal_handles_; }
886 
thread_manager()887   ThreadManager* thread_manager() { return thread_manager_; }
888 
jsregexp_uncanonicalize()889   unibrow::Mapping<unibrow::Ecma262UnCanonicalize>* jsregexp_uncanonicalize() {
890     return &jsregexp_uncanonicalize_;
891   }
892 
jsregexp_canonrange()893   unibrow::Mapping<unibrow::CanonicalizationRange>* jsregexp_canonrange() {
894     return &jsregexp_canonrange_;
895   }
896 
runtime_state()897   RuntimeState* runtime_state() { return &runtime_state_; }
898 
builtins()899   Builtins* builtins() { return &builtins_; }
900 
NotifyExtensionInstalled()901   void NotifyExtensionInstalled() {
902     has_installed_extensions_ = true;
903   }
904 
has_installed_extensions()905   bool has_installed_extensions() { return has_installed_extensions_; }
906 
907   unibrow::Mapping<unibrow::Ecma262Canonicalize>*
regexp_macro_assembler_canonicalize()908       regexp_macro_assembler_canonicalize() {
909     return &regexp_macro_assembler_canonicalize_;
910   }
911 
regexp_stack()912   RegExpStack* regexp_stack() { return regexp_stack_; }
913 
914   unibrow::Mapping<unibrow::Ecma262Canonicalize>*
interp_canonicalize_mapping()915       interp_canonicalize_mapping() {
916     return &regexp_macro_assembler_canonicalize_;
917   }
918 
debug()919   Debug* debug() { return debug_; }
920 
is_profiling_address()921   bool* is_profiling_address() { return &is_profiling_; }
code_event_dispatcher()922   CodeEventDispatcher* code_event_dispatcher() const {
923     return code_event_dispatcher_.get();
924   }
cpu_profiler()925   CpuProfiler* cpu_profiler() const { return cpu_profiler_; }
heap_profiler()926   HeapProfiler* heap_profiler() const { return heap_profiler_; }
927 
928 #ifdef DEBUG
heap_histograms()929   HistogramInfo* heap_histograms() { return heap_histograms_; }
930 
js_spill_information()931   JSObject::SpillInformation* js_spill_information() {
932     return &js_spill_information_;
933   }
934 #endif
935 
factory()936   Factory* factory() { return reinterpret_cast<Factory*>(this); }
937 
938   static const int kJSRegexpStaticOffsetsVectorSize = 128;
939 
THREAD_LOCAL_TOP_ACCESSOR(ExternalCallbackScope *,external_callback_scope)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   }
GetData(uint32_t slot)948   void* GetData(uint32_t slot) {
949     DCHECK(slot < Internals::kNumIsolateDataSlots);
950     return embedder_data_[slot];
951   }
952 
serializer_enabled()953   bool serializer_enabled() const { return serializer_enabled_; }
snapshot_available()954   bool snapshot_available() const {
955     return snapshot_blob_ != NULL && snapshot_blob_->raw_size != 0;
956   }
957 
IsDead()958   bool IsDead() { return has_fatal_error_; }
SignalFatalError()959   void SignalFatalError() { has_fatal_error_ = true; }
960 
961   bool use_crankshaft() const;
962 
initialized_from_snapshot()963   bool initialized_from_snapshot() { return initialized_from_snapshot_; }
964 
time_millis_since_init()965   double time_millis_since_init() {
966     return heap_.MonotonicallyIncreasingTimeInMs() - time_millis_at_init_;
967   }
968 
date_cache()969   DateCache* date_cache() {
970     return date_cache_;
971   }
972 
set_date_cache(DateCache * date_cache)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);
UpdateArrayProtectorOnSetLength(Handle<JSObject> object)995   void UpdateArrayProtectorOnSetLength(Handle<JSObject> object) {
996     UpdateArrayProtectorOnSetElement(object);
997   }
UpdateArrayProtectorOnSetPrototype(Handle<JSObject> object)998   void UpdateArrayProtectorOnSetPrototype(Handle<JSObject> object) {
999     UpdateArrayProtectorOnSetElement(object);
1000   }
UpdateArrayProtectorOnNormalizeElements(Handle<JSObject> object)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 
concurrent_recompilation_enabled()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 
optimizing_compile_dispatcher()1028   OptimizingCompileDispatcher* optimizing_compile_dispatcher() {
1029     return optimizing_compile_dispatcher_;
1030   }
1031 
id()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 
function_entry_hook()1041   FunctionEntryHook function_entry_hook() { return function_entry_hook_; }
set_function_entry_hook(FunctionEntryHook function_entry_hook)1042   void set_function_entry_hook(FunctionEntryHook function_entry_hook) {
1043     function_entry_hook_ = function_entry_hook;
1044   }
1045 
stress_deopt_count_address()1046   void* stress_deopt_count_address() { return &stress_deopt_count_; }
1047 
virtual_handler_register_address()1048   void* virtual_handler_register_address() {
1049     return &virtual_handler_register_;
1050   }
1051 
virtual_slot_register_address()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 
NextOptimizationId()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 
IncrementJsCallsFromApiCounter()1067   void IncrementJsCallsFromApiCounter() { ++js_calls_from_api_counter_; }
1068 
js_calls_from_api_counter()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();
IsRunningMicrotasks()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();
basic_block_profiler()1100   BasicBlockProfiler* basic_block_profiler() { return basic_block_profiler_; }
1101 
1102   std::string GetTurboCfgFileName();
1103 
1104 #if TRACE_MAPS
GetNextUniqueSharedFunctionInfoId()1105   int GetNextUniqueSharedFunctionInfoId() { return next_unique_sfi_id_++; }
1106 #endif
1107 
1108   // Support for dynamically disabling tail call elimination.
is_tail_call_elimination_enabled_address()1109   Address is_tail_call_elimination_enabled_address() {
1110     return reinterpret_cast<Address>(&is_tail_call_elimination_enabled_);
1111   }
is_tail_call_elimination_enabled()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 
partial_snapshot_cache()1120   List<Object*>* partial_snapshot_cache() { return &partial_snapshot_cache_; }
1121 
set_array_buffer_allocator(v8::ArrayBuffer::Allocator * allocator)1122   void set_array_buffer_allocator(v8::ArrayBuffer::Allocator* allocator) {
1123     array_buffer_allocator_ = allocator;
1124   }
array_buffer_allocator()1125   v8::ArrayBuffer::Allocator* array_buffer_allocator() const {
1126     return array_buffer_allocator_;
1127   }
1128 
futex_wait_list_node()1129   FutexWaitListNode* futex_wait_list_node() { return &futex_wait_list_node_; }
1130 
cancelable_task_manager()1131   CancelableTaskManager* cancelable_task_manager() {
1132     return cancelable_task_manager_;
1133   }
1134 
interpreter()1135   interpreter::Interpreter* interpreter() const { return interpreter_; }
1136 
allocator()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:
EntryStackItem(PerIsolateThreadData * previous_thread_data,Isolate * previous_isolate,EntryStackItem * previous_item)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 
RAILModeName(RAILMode rail_mode)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:
PromiseOnStack(Handle<JSFunction> function,Handle<JSObject> promise,PromiseOnStack * prev)1441   PromiseOnStack(Handle<JSFunction> function, Handle<JSObject> promise,
1442                  PromiseOnStack* prev)
1443       : function_(function), promise_(promise), prev_(prev) {}
function()1444   Handle<JSFunction> function() { return function_; }
promise()1445   Handle<JSObject> promise() { return promise_; }
prev()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 
context()1463   Handle<Context> context() { return context_; }
prev()1464   SaveContext* prev() { return prev_; }
1465 
1466   // Returns true if this save context is below a given JavaScript frame.
IsBelowFrame(JavaScriptFrame * 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);
~AssertNoContextChange()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:
ExecutionAccess(Isolate * isolate)1499   explicit ExecutionAccess(Isolate* isolate) : isolate_(isolate) {
1500     Lock(isolate);
1501   }
~ExecutionAccess()1502   ~ExecutionAccess() { Unlock(isolate_); }
1503 
Lock(Isolate * isolate)1504   static void Lock(Isolate* isolate) { isolate->break_access()->Lock(); }
Unlock(Isolate * isolate)1505   static void Unlock(Isolate* isolate) { isolate->break_access()->Unlock(); }
1506 
TryLock(Isolate * isolate)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:
StackLimitCheck(Isolate * isolate)1519   explicit StackLimitCheck(Isolate* isolate) : isolate_(isolate) { }
1520 
1521   // Use this to check for stack-overflows in C++ code.
HasOverflowed()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.
InterruptRequested()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 
~PostponeInterruptsScope()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:
CodeTracer(int isolate_id)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:
Scope(CodeTracer * tracer)1606     explicit Scope(CodeTracer* tracer) : tracer_(tracer) { tracer->OpenFile(); }
~Scope()1607     ~Scope() { tracer_->CloseFile();  }
1608 
file()1609     FILE* file() const { return tracer_->file(); }
1610 
1611    private:
1612     CodeTracer* tracer_;
1613   };
1614 
OpenFile()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 
CloseFile()1627   void CloseFile() {
1628     if (!ShouldRedirect()) {
1629       return;
1630     }
1631 
1632     if (--scope_depth_ == 0) {
1633       fclose(file_);
1634       file_ = NULL;
1635     }
1636   }
1637 
file()1638   FILE* file() const { return file_; }
1639 
1640  private:
ShouldRedirect()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