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