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