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