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