The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / isolate.h @ f230a1cf

History | View | Annotate | Download (50.5 KB)

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

    
51
namespace v8 {
52
namespace internal {
53

    
54
class Bootstrapper;
55
class CodeGenerator;
56
class CodeRange;
57
struct CodeStubInterfaceDescriptor;
58
class CompilationCache;
59
class ContextSlotCache;
60
class ContextSwitcher;
61
class Counters;
62
class CpuFeatures;
63
class CpuProfiler;
64
class DeoptimizerData;
65
class Deserializer;
66
class EmptyStatement;
67
class ExternalCallbackScope;
68
class ExternalReferenceTable;
69
class Factory;
70
class FunctionInfoListener;
71
class HandleScopeImplementer;
72
class HeapProfiler;
73
class HStatistics;
74
class HTracer;
75
class InlineRuntimeFunctionsTable;
76
class NoAllocationStringAllocator;
77
class InnerPointerToCodeCache;
78
class PreallocatedMemoryThread;
79
class RandomNumberGenerator;
80
class RegExpStack;
81
class SaveContext;
82
class UnicodeCache;
83
class ConsStringIteratorOp;
84
class StringTracker;
85
class StubCache;
86
class SweeperThread;
87
class ThreadManager;
88
class ThreadState;
89
class ThreadVisitor;  // Defined in v8threads.h
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.
95
typedef void* ExternalReferenceRedirectorPointer();
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(__mips__) && V8_TARGET_ARCH_MIPS
106
class Redirection;
107
class Simulator;
108
#endif
109

    
110

    
111
// Static indirection table for handles to constants.  If a frame
112
// element represents a constant, the data contains an index into
113
// this table of handles to the actual constants.
114
// Static indirection table for handles to constants.  If a Result
115
// represents a constant, the data contains an index into this table
116
// of handles to the actual constants.
117
typedef ZoneList<Handle<Object> > ZoneObjectList;
118

    
119
#define RETURN_IF_SCHEDULED_EXCEPTION(isolate)            \
120
  do {                                                    \
121
    Isolate* __isolate__ = (isolate);                     \
122
    if (__isolate__->has_scheduled_exception()) {         \
123
      return __isolate__->PromoteScheduledException();    \
124
    }                                                     \
125
  } while (false)
126

    
127
#define RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, T)  \
128
  do {                                                    \
129
    Isolate* __isolate__ = (isolate);                     \
130
    if (__isolate__->has_scheduled_exception()) {         \
131
      __isolate__->PromoteScheduledException();           \
132
      return Handle<T>::null();                           \
133
    }                                                     \
134
  } while (false)
135

    
136
#define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value) \
137
  do {                                                     \
138
    if ((call).is_null()) {                                \
139
      ASSERT((isolate)->has_pending_exception());          \
140
      return (value);                                      \
141
    }                                                      \
142
  } while (false)
143

    
144
#define CHECK_NOT_EMPTY_HANDLE(isolate, call)     \
145
  do {                                            \
146
    ASSERT(!(isolate)->has_pending_exception());  \
147
    CHECK(!(call).is_null());                     \
148
    CHECK(!(isolate)->has_pending_exception());   \
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
class ThreadLocalTop BASE_EMBEDDED {
211
 public:
212
  // Does early low-level initialization that does not depend on the
213
  // isolate being present.
214
  ThreadLocalTop();
215

    
216
  // Initialize the thread data.
217
  void Initialize();
218

    
219
  // Get the top C++ try catch handler or NULL if none are registered.
220
  //
221
  // This method is not guarenteed to return an address that can be
222
  // used for comparison with addresses into the JS stack.  If such an
223
  // address is needed, use try_catch_handler_address.
224
  v8::TryCatch* TryCatchHandler();
225

    
226
  // Get the address of the top C++ try catch handler or NULL if
227
  // none are registered.
228
  //
229
  // This method always returns an address that can be compared to
230
  // pointers into the JavaScript stack.  When running on actual
231
  // hardware, try_catch_handler_address and TryCatchHandler return
232
  // the same pointer.  When running on a simulator with a separate JS
233
  // stack, try_catch_handler_address returns a JS stack address that
234
  // corresponds to the place on the JS stack where the C++ handler
235
  // would have been if the stack were not separate.
236
  inline Address try_catch_handler_address() {
237
    return try_catch_handler_address_;
238
  }
239

    
240
  // Set the address of the top C++ try catch handler.
241
  inline void set_try_catch_handler_address(Address address) {
242
    try_catch_handler_address_ = address;
243
  }
244

    
245
  void Free() {
246
    ASSERT(!has_pending_message_);
247
    ASSERT(!external_caught_exception_);
248
    ASSERT(try_catch_handler_address_ == NULL);
249
  }
250

    
251
  Isolate* isolate_;
252
  // The context where the current execution method is created and for variable
253
  // lookups.
254
  Context* context_;
255
  ThreadId thread_id_;
256
  MaybeObject* pending_exception_;
257
  bool has_pending_message_;
258
  bool rethrowing_message_;
259
  Object* pending_message_obj_;
260
  Object* pending_message_script_;
261
  int pending_message_start_pos_;
262
  int pending_message_end_pos_;
263
  // Use a separate value for scheduled exceptions to preserve the
264
  // invariants that hold about pending_exception.  We may want to
265
  // unify them later.
266
  MaybeObject* scheduled_exception_;
267
  bool external_caught_exception_;
268
  SaveContext* save_context_;
269
  v8::TryCatch* catcher_;
270

    
271
  // Stack.
272
  Address c_entry_fp_;  // the frame pointer of the top c entry frame
273
  Address handler_;   // try-blocks are chained through the stack
274

    
275
#ifdef USE_SIMULATOR
276
  Simulator* simulator_;
277
#endif
278

    
279
  Address js_entry_sp_;  // the stack pointer of the bottom JS entry frame
280
  // the external callback we're currently in
281
  ExternalCallbackScope* external_callback_scope_;
282
  StateTag current_vm_state_;
283

    
284
  // Generated code scratch locations.
285
  int32_t formal_count_;
286

    
287
  // Call back function to report unsafe JS accesses.
288
  v8::FailedAccessCheckCallback failed_access_check_callback_;
289

    
290
  // Head of the list of live LookupResults.
291
  LookupResult* top_lookup_result_;
292

    
293
  // Whether out of memory exceptions should be ignored.
294
  bool ignore_out_of_memory_;
295

    
296
 private:
297
  void InitializeInternal();
298

    
299
  Address try_catch_handler_address_;
300
};
301

    
302

    
303
class SystemThreadManager {
304
 public:
305
  enum ParallelSystemComponent {
306
    PARALLEL_SWEEPING,
307
    CONCURRENT_SWEEPING,
308
    PARALLEL_RECOMPILATION
309
  };
310

    
311
  static int NumberOfParallelSystemThreads(ParallelSystemComponent type);
312

    
313
  static const int kMaxThreads = 4;
314
};
315

    
316

    
317
#ifdef ENABLE_DEBUGGER_SUPPORT
318

    
319
#define ISOLATE_DEBUGGER_INIT_LIST(V)                                          \
320
  V(DebuggerAgent*, debugger_agent_instance, NULL)
321
#else
322

    
323
#define ISOLATE_DEBUGGER_INIT_LIST(V)
324

    
325
#endif
326

    
327
#ifdef DEBUG
328

    
329
#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)                                       \
330
  V(CommentStatistic, paged_space_comments_statistics,                         \
331
      CommentStatistic::kMaxComments + 1)
332
#else
333

    
334
#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
335

    
336
#endif
337

    
338
#define ISOLATE_INIT_ARRAY_LIST(V)                                             \
339
  /* SerializerDeserializer state. */                                          \
340
  V(int32_t, jsregexp_static_offsets_vector, kJSRegexpStaticOffsetsVectorSize) \
341
  V(int, bad_char_shift_table, kUC16AlphabetSize)                              \
342
  V(int, good_suffix_shift_table, (kBMMaxShift + 1))                           \
343
  V(int, suffix_table, (kBMMaxShift + 1))                                      \
344
  V(uint32_t, private_random_seed, 2)                                          \
345
  ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
346

    
347
typedef List<HeapObject*, PreallocatedStorageAllocationPolicy> DebugObjectCache;
348

    
349
#define ISOLATE_INIT_LIST(V)                                                   \
350
  /* SerializerDeserializer state. */                                          \
351
  V(int, serialize_partial_snapshot_cache_length, 0)                           \
352
  V(int, serialize_partial_snapshot_cache_capacity, 0)                         \
353
  V(Object**, serialize_partial_snapshot_cache, NULL)                          \
354
  /* Assembler state. */                                                       \
355
  /* A previously allocated buffer of kMinimalBufferSize bytes, or NULL. */    \
356
  V(byte*, assembler_spare_buffer, NULL)                                       \
357
  V(FatalErrorCallback, exception_behavior, NULL)                              \
358
  V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, NULL)     \
359
  /* To distinguish the function templates, so that we can find them in the */ \
360
  /* function cache of the native context. */                                  \
361
  V(int, next_serial_number, 0)                                                \
362
  V(ExternalReferenceRedirectorPointer*, external_reference_redirector, NULL)  \
363
  V(bool, always_allow_natives_syntax, false)                                  \
364
  /* Part of the state of liveedit. */                                         \
365
  V(FunctionInfoListener*, active_function_info_listener, NULL)                \
366
  /* State for Relocatable. */                                                 \
367
  V(Relocatable*, relocatable_top, NULL)                                       \
368
  V(DebugObjectCache*, string_stream_debug_object_cache, NULL)                 \
369
  V(Object*, string_stream_current_security_token, NULL)                       \
370
  /* TODO(isolates): Release this on destruction? */                           \
371
  V(int*, irregexp_interpreter_backtrack_stack_cache, NULL)                    \
372
  /* Serializer state. */                                                      \
373
  V(ExternalReferenceTable*, external_reference_table, NULL)                   \
374
  /* AstNode state. */                                                         \
375
  V(int, ast_node_id, 0)                                                       \
376
  V(unsigned, ast_node_count, 0)                                               \
377
  V(bool, observer_delivery_pending, false)                                    \
378
  V(HStatistics*, hstatistics, NULL)                                           \
379
  V(HTracer*, htracer, NULL)                                                   \
380
  ISOLATE_DEBUGGER_INIT_LIST(V)
381

    
382
class Isolate {
383
  // These forward declarations are required to make the friend declarations in
384
  // PerIsolateThreadData work on some older versions of gcc.
385
  class ThreadDataTable;
386
  class EntryStackItem;
387
 public:
388
  ~Isolate();
389

    
390
  // A thread has a PerIsolateThreadData instance for each isolate that it has
391
  // entered. That instance is allocated when the isolate is initially entered
392
  // and reused on subsequent entries.
393
  class PerIsolateThreadData {
394
   public:
395
    PerIsolateThreadData(Isolate* isolate, ThreadId thread_id)
396
        : isolate_(isolate),
397
          thread_id_(thread_id),
398
          stack_limit_(0),
399
          thread_state_(NULL),
400
#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
401
    !defined(__mips__) && V8_TARGET_ARCH_MIPS
402
          simulator_(NULL),
403
#endif
404
          next_(NULL),
405
          prev_(NULL) { }
406
    Isolate* isolate() const { return isolate_; }
407
    ThreadId thread_id() const { return thread_id_; }
408
    void set_stack_limit(uintptr_t value) { stack_limit_ = value; }
409
    uintptr_t stack_limit() const { return stack_limit_; }
410
    ThreadState* thread_state() const { return thread_state_; }
411
    void set_thread_state(ThreadState* value) { thread_state_ = value; }
412

    
413
#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
414
    !defined(__mips__) && V8_TARGET_ARCH_MIPS
415
    Simulator* simulator() const { return simulator_; }
416
    void set_simulator(Simulator* simulator) {
417
      simulator_ = simulator;
418
    }
419
#endif
420

    
421
    bool Matches(Isolate* isolate, ThreadId thread_id) const {
422
      return isolate_ == isolate && thread_id_.Equals(thread_id);
423
    }
424

    
425
   private:
426
    Isolate* isolate_;
427
    ThreadId thread_id_;
428
    uintptr_t stack_limit_;
429
    ThreadState* thread_state_;
430

    
431
#if !defined(__arm__) && V8_TARGET_ARCH_ARM || \
432
    !defined(__mips__) && V8_TARGET_ARCH_MIPS
433
    Simulator* simulator_;
434
#endif
435

    
436
    PerIsolateThreadData* next_;
437
    PerIsolateThreadData* prev_;
438

    
439
    friend class Isolate;
440
    friend class ThreadDataTable;
441
    friend class EntryStackItem;
442

    
443
    DISALLOW_COPY_AND_ASSIGN(PerIsolateThreadData);
444
  };
445

    
446

    
447
  enum AddressId {
448
#define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address,
449
    FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM)
450
#undef DECLARE_ENUM
451
    kIsolateAddressCount
452
  };
453

    
454
  // Returns the PerIsolateThreadData for the current thread (or NULL if one is
455
  // not currently set).
456
  static PerIsolateThreadData* CurrentPerIsolateThreadData() {
457
    return reinterpret_cast<PerIsolateThreadData*>(
458
        Thread::GetThreadLocal(per_isolate_thread_data_key_));
459
  }
460

    
461
  // Returns the isolate inside which the current thread is running.
462
  INLINE(static Isolate* Current()) {
463
    Isolate* isolate = reinterpret_cast<Isolate*>(
464
        Thread::GetExistingThreadLocal(isolate_key_));
465
    ASSERT(isolate != NULL);
466
    return isolate;
467
  }
468

    
469
  INLINE(static Isolate* UncheckedCurrent()) {
470
    return reinterpret_cast<Isolate*>(Thread::GetThreadLocal(isolate_key_));
471
  }
472

    
473
  // Usually called by Init(), but can be called early e.g. to allow
474
  // testing components that require logging but not the whole
475
  // isolate.
476
  //
477
  // Safe to call more than once.
478
  void InitializeLoggingAndCounters();
479

    
480
  bool Init(Deserializer* des);
481

    
482
  bool IsInitialized() { return state_ == INITIALIZED; }
483

    
484
  // True if at least one thread Enter'ed this isolate.
485
  bool IsInUse() { return entry_stack_ != NULL; }
486

    
487
  // Destroys the non-default isolates.
488
  // Sets default isolate into "has_been_disposed" state rather then destroying,
489
  // for legacy API reasons.
490
  void TearDown();
491

    
492
  static void GlobalTearDown();
493

    
494
  bool IsDefaultIsolate() const { return this == default_isolate_; }
495

    
496
  static void SetCrashIfDefaultIsolateInitialized();
497
  // Ensures that process-wide resources and the default isolate have been
498
  // allocated. It is only necessary to call this method in rare cases, for
499
  // example if you are using V8 from within the body of a static initializer.
500
  // Safe to call multiple times.
501
  static void EnsureDefaultIsolate();
502

    
503
  // Find the PerThread for this particular (isolate, thread) combination
504
  // If one does not yet exist, return null.
505
  PerIsolateThreadData* FindPerThreadDataForThisThread();
506

    
507
  // Find the PerThread for given (isolate, thread) combination
508
  // If one does not yet exist, return null.
509
  PerIsolateThreadData* FindPerThreadDataForThread(ThreadId thread_id);
510

    
511
#ifdef ENABLE_DEBUGGER_SUPPORT
512
  // Get the debugger from the default isolate. Preinitializes the
513
  // default isolate if needed.
514
  static Debugger* GetDefaultIsolateDebugger();
515
#endif
516

    
517
  // Get the stack guard from the default isolate. Preinitializes the
518
  // default isolate if needed.
519
  static StackGuard* GetDefaultIsolateStackGuard();
520

    
521
  // Returns the key used to store the pointer to the current isolate.
522
  // Used internally for V8 threads that do not execute JavaScript but still
523
  // are part of the domain of an isolate (like the context switcher).
524
  static Thread::LocalStorageKey isolate_key() {
525
    return isolate_key_;
526
  }
527

    
528
  // Returns the key used to store process-wide thread IDs.
529
  static Thread::LocalStorageKey thread_id_key() {
530
    return thread_id_key_;
531
  }
532

    
533
  static Thread::LocalStorageKey per_isolate_thread_data_key();
534

    
535
  // If a client attempts to create a Locker without specifying an isolate,
536
  // we assume that the client is using legacy behavior. Set up the current
537
  // thread to be inside the implicit isolate (or fail a check if we have
538
  // switched to non-legacy behavior).
539
  static void EnterDefaultIsolate();
540

    
541
  // Mutex for serializing access to break control structures.
542
  RecursiveMutex* break_access() { return &break_access_; }
543

    
544
  // Mutex for serializing access to debugger.
545
  RecursiveMutex* debugger_access() { return &debugger_access_; }
546

    
547
  Address get_address_from_id(AddressId id);
548

    
549
  // Access to top context (where the current function object was created).
550
  Context* context() { return thread_local_top_.context_; }
551
  void set_context(Context* context) {
552
    ASSERT(context == NULL || context->IsContext());
553
    thread_local_top_.context_ = context;
554
  }
555
  Context** context_address() { return &thread_local_top_.context_; }
556

    
557
  SaveContext* save_context() { return thread_local_top_.save_context_; }
558
  void set_save_context(SaveContext* save) {
559
    thread_local_top_.save_context_ = save;
560
  }
561

    
562
  // Access to current thread id.
563
  ThreadId thread_id() { return thread_local_top_.thread_id_; }
564
  void set_thread_id(ThreadId id) { thread_local_top_.thread_id_ = id; }
565

    
566
  // Interface to pending exception.
567
  MaybeObject* pending_exception() {
568
    ASSERT(has_pending_exception());
569
    return thread_local_top_.pending_exception_;
570
  }
571
  bool external_caught_exception() {
572
    return thread_local_top_.external_caught_exception_;
573
  }
574
  void set_external_caught_exception(bool value) {
575
    thread_local_top_.external_caught_exception_ = value;
576
  }
577
  void set_pending_exception(MaybeObject* exception) {
578
    thread_local_top_.pending_exception_ = exception;
579
  }
580
  void clear_pending_exception() {
581
    thread_local_top_.pending_exception_ = heap_.the_hole_value();
582
  }
583
  MaybeObject** pending_exception_address() {
584
    return &thread_local_top_.pending_exception_;
585
  }
586
  bool has_pending_exception() {
587
    return !thread_local_top_.pending_exception_->IsTheHole();
588
  }
589
  void clear_pending_message() {
590
    thread_local_top_.has_pending_message_ = false;
591
    thread_local_top_.pending_message_obj_ = heap_.the_hole_value();
592
    thread_local_top_.pending_message_script_ = heap_.the_hole_value();
593
  }
594
  v8::TryCatch* try_catch_handler() {
595
    return thread_local_top_.TryCatchHandler();
596
  }
597
  Address try_catch_handler_address() {
598
    return thread_local_top_.try_catch_handler_address();
599
  }
600
  bool* external_caught_exception_address() {
601
    return &thread_local_top_.external_caught_exception_;
602
  }
603
  v8::TryCatch* catcher() {
604
    return thread_local_top_.catcher_;
605
  }
606
  void set_catcher(v8::TryCatch* catcher) {
607
    thread_local_top_.catcher_ = catcher;
608
  }
609

    
610
  MaybeObject** scheduled_exception_address() {
611
    return &thread_local_top_.scheduled_exception_;
612
  }
613

    
614
  Address pending_message_obj_address() {
615
    return reinterpret_cast<Address>(&thread_local_top_.pending_message_obj_);
616
  }
617

    
618
  Address has_pending_message_address() {
619
    return reinterpret_cast<Address>(&thread_local_top_.has_pending_message_);
620
  }
621

    
622
  Address pending_message_script_address() {
623
    return reinterpret_cast<Address>(
624
        &thread_local_top_.pending_message_script_);
625
  }
626

    
627
  MaybeObject* scheduled_exception() {
628
    ASSERT(has_scheduled_exception());
629
    return thread_local_top_.scheduled_exception_;
630
  }
631
  bool has_scheduled_exception() {
632
    return thread_local_top_.scheduled_exception_ != heap_.the_hole_value();
633
  }
634
  void clear_scheduled_exception() {
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->IsOutOfMemory()) &&
642
        (exception != heap()->termination_exception());
643
  }
644

    
645
  // Serializer.
646
  void PushToPartialSnapshotCache(Object* obj);
647

    
648
  // JS execution stack (see frames.h).
649
  static Address c_entry_fp(ThreadLocalTop* thread) {
650
    return thread->c_entry_fp_;
651
  }
652
  static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
653

    
654
  inline Address* c_entry_fp_address() {
655
    return &thread_local_top_.c_entry_fp_;
656
  }
657
  inline Address* handler_address() { return &thread_local_top_.handler_; }
658

    
659
  // Bottom JS entry.
660
  Address js_entry_sp() {
661
    return thread_local_top_.js_entry_sp_;
662
  }
663
  inline Address* js_entry_sp_address() {
664
    return &thread_local_top_.js_entry_sp_;
665
  }
666

    
667
  // Generated code scratch locations.
668
  void* formal_count_address() { return &thread_local_top_.formal_count_; }
669

    
670
  // Returns the global object of the current context. It could be
671
  // a builtin object, or a JS global object.
672
  Handle<GlobalObject> global_object() {
673
    return Handle<GlobalObject>(context()->global_object());
674
  }
675

    
676
  // Returns the global proxy object of the current context.
677
  Object* global_proxy() {
678
    return context()->global_proxy();
679
  }
680

    
681
  Handle<JSBuiltinsObject> js_builtins_object() {
682
    return Handle<JSBuiltinsObject>(thread_local_top_.context_->builtins());
683
  }
684

    
685
  static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
686
  void FreeThreadResources() { thread_local_top_.Free(); }
687

    
688
  // This method is called by the api after operations that may throw
689
  // exceptions.  If an exception was thrown and not handled by an external
690
  // handler the exception is scheduled to be rethrown when we return to running
691
  // JavaScript code.  If an exception is scheduled true is returned.
692
  bool OptionalRescheduleException(bool is_bottom_call);
693

    
694
  class ExceptionScope {
695
   public:
696
    explicit ExceptionScope(Isolate* isolate) :
697
      // Scope currently can only be used for regular exceptions, not
698
      // failures like OOM or termination exception.
699
      isolate_(isolate),
700
      pending_exception_(isolate_->pending_exception()->ToObjectUnchecked(),
701
                         isolate_),
702
      catcher_(isolate_->catcher())
703
    { }
704

    
705
    ~ExceptionScope() {
706
      isolate_->set_catcher(catcher_);
707
      isolate_->set_pending_exception(*pending_exception_);
708
    }
709

    
710
   private:
711
    Isolate* isolate_;
712
    Handle<Object> pending_exception_;
713
    v8::TryCatch* catcher_;
714
  };
715

    
716
  void SetCaptureStackTraceForUncaughtExceptions(
717
      bool capture,
718
      int frame_limit,
719
      StackTrace::StackTraceOptions options);
720

    
721
  // Tells whether the current context has experienced an out of memory
722
  // exception.
723
  bool is_out_of_memory();
724
  bool ignore_out_of_memory() {
725
    return thread_local_top_.ignore_out_of_memory_;
726
  }
727
  void set_ignore_out_of_memory(bool value) {
728
    thread_local_top_.ignore_out_of_memory_ = value;
729
  }
730

    
731
  void PrintCurrentStackTrace(FILE* out);
732
  void PrintStackTrace(FILE* out, char* thread_data);
733
  void PrintStack(StringStream* accumulator);
734
  void PrintStack(FILE* out);
735
  void PrintStack();
736
  Handle<String> StackTraceString();
737
  NO_INLINE(void PushStackTraceAndDie(unsigned int magic,
738
                                      Object* object,
739
                                      Map* map,
740
                                      unsigned int magic2));
741
  Handle<JSArray> CaptureCurrentStackTrace(
742
      int frame_limit,
743
      StackTrace::StackTraceOptions options);
744

    
745
  Handle<JSArray> CaptureSimpleStackTrace(Handle<JSObject> error_object,
746
                                          Handle<Object> caller,
747
                                          int limit);
748
  void CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object);
749

    
750
  // Returns if the top context may access the given global object. If
751
  // the result is false, the pending exception is guaranteed to be
752
  // set.
753

    
754
  // TODO(yangguo): temporary wrappers
755
  bool MayNamedAccessWrapper(Handle<JSObject> receiver,
756
                             Handle<Object> key,
757
                             v8::AccessType type) {
758
    return MayNamedAccess(*receiver, *key, type);
759
  }
760
  bool MayIndexedAccessWrapper(Handle<JSObject> receiver,
761
                               uint32_t index,
762
                               v8::AccessType type) {
763
    return MayIndexedAccess(*receiver, index, type);
764
  }
765

    
766
  bool MayNamedAccess(JSObject* receiver,
767
                      Object* key,
768
                      v8::AccessType type);
769
  bool MayIndexedAccess(JSObject* receiver,
770
                        uint32_t index,
771
                        v8::AccessType type);
772

    
773
  void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
774
  void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
775

    
776
  // Exception throwing support. The caller should use the result
777
  // of Throw() as its return value.
778
  Failure* Throw(Object* exception, MessageLocation* location = NULL);
779
  // Re-throw an exception.  This involves no error reporting since
780
  // error reporting was handled when the exception was thrown
781
  // originally.
782
  Failure* ReThrow(MaybeObject* exception);
783
  void ScheduleThrow(Object* exception);
784
  // Re-set pending message, script and positions reported to the TryCatch
785
  // back to the TLS for re-use when rethrowing.
786
  void RestorePendingMessageFromTryCatch(v8::TryCatch* handler);
787
  void ReportPendingMessages();
788
  // Return pending location if any or unfilled structure.
789
  MessageLocation GetMessageLocation();
790
  Failure* ThrowIllegalOperation();
791

    
792
  // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
793
  Failure* PromoteScheduledException();
794
  void DoThrow(Object* exception, MessageLocation* location);
795
  // Checks if exception should be reported and finds out if it's
796
  // caught externally.
797
  bool ShouldReportException(bool* can_be_caught_externally,
798
                             bool catchable_by_javascript);
799

    
800
  // Attempts to compute the current source location, storing the
801
  // result in the target out parameter.
802
  void ComputeLocation(MessageLocation* target);
803

    
804
  // Override command line flag.
805
  void TraceException(bool flag);
806

    
807
  // Out of resource exception helpers.
808
  Failure* StackOverflow();
809
  Failure* TerminateExecution();
810
  void CancelTerminateExecution();
811

    
812
  // Administration
813
  void Iterate(ObjectVisitor* v);
814
  void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
815
  char* Iterate(ObjectVisitor* v, char* t);
816
  void IterateThread(ThreadVisitor* v, char* t);
817

    
818

    
819
  // Returns the current native and global context.
820
  Handle<Context> native_context();
821
  Handle<Context> global_context();
822

    
823
  // Returns the native context of the calling JavaScript code.  That
824
  // is, the native context of the top-most JavaScript frame.
825
  Handle<Context> GetCallingNativeContext();
826

    
827
  void RegisterTryCatchHandler(v8::TryCatch* that);
828
  void UnregisterTryCatchHandler(v8::TryCatch* that);
829

    
830
  char* ArchiveThread(char* to);
831
  char* RestoreThread(char* from);
832

    
833
  static const char* const kStackOverflowMessage;
834

    
835
  static const int kUC16AlphabetSize = 256;  // See StringSearchBase.
836
  static const int kBMMaxShift = 250;        // See StringSearchBase.
837

    
838
  // Accessors.
839
#define GLOBAL_ACCESSOR(type, name, initialvalue)                       \
840
  inline type name() const {                                            \
841
    ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
842
    return name##_;                                                     \
843
  }                                                                     \
844
  inline void set_##name(type value) {                                  \
845
    ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
846
    name##_ = value;                                                    \
847
  }
848
  ISOLATE_INIT_LIST(GLOBAL_ACCESSOR)
849
#undef GLOBAL_ACCESSOR
850

    
851
#define GLOBAL_ARRAY_ACCESSOR(type, name, length)                       \
852
  inline type* name() {                                                 \
853
    ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
854
    return &(name##_)[0];                                               \
855
  }
856
  ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR)
857
#undef GLOBAL_ARRAY_ACCESSOR
858

    
859
#define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name)            \
860
  Handle<type> name() {                                             \
861
    return Handle<type>(context()->native_context()->name(), this); \
862
  }                                                                 \
863
  bool is_##name(type* value) {                                     \
864
    return context()->native_context()->is_##name(value);           \
865
  }
866
  NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR)
867
#undef NATIVE_CONTEXT_FIELD_ACCESSOR
868

    
869
  Bootstrapper* bootstrapper() { return bootstrapper_; }
870
  Counters* counters() {
871
    // Call InitializeLoggingAndCounters() if logging is needed before
872
    // the isolate is fully initialized.
873
    ASSERT(counters_ != NULL);
874
    return counters_;
875
  }
876
  CodeRange* code_range() { return code_range_; }
877
  RuntimeProfiler* runtime_profiler() { return runtime_profiler_; }
878
  CompilationCache* compilation_cache() { return compilation_cache_; }
879
  Logger* logger() {
880
    // Call InitializeLoggingAndCounters() if logging is needed before
881
    // the isolate is fully initialized.
882
    ASSERT(logger_ != NULL);
883
    return logger_;
884
  }
885
  StackGuard* stack_guard() { return &stack_guard_; }
886
  Heap* heap() { return &heap_; }
887
  StatsTable* stats_table();
888
  StubCache* stub_cache() { return stub_cache_; }
889
  DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
890
  ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
891

    
892
  TranscendentalCache* transcendental_cache() const {
893
    return transcendental_cache_;
894
  }
895

    
896
  MemoryAllocator* memory_allocator() {
897
    return memory_allocator_;
898
  }
899

    
900
  KeyedLookupCache* keyed_lookup_cache() {
901
    return keyed_lookup_cache_;
902
  }
903

    
904
  ContextSlotCache* context_slot_cache() {
905
    return context_slot_cache_;
906
  }
907

    
908
  DescriptorLookupCache* descriptor_lookup_cache() {
909
    return descriptor_lookup_cache_;
910
  }
911

    
912
  v8::ImplementationUtilities::HandleScopeData* handle_scope_data() {
913
    return &handle_scope_data_;
914
  }
915
  HandleScopeImplementer* handle_scope_implementer() {
916
    ASSERT(handle_scope_implementer_);
917
    return handle_scope_implementer_;
918
  }
919
  Zone* runtime_zone() { return &runtime_zone_; }
920

    
921
  UnicodeCache* unicode_cache() {
922
    return unicode_cache_;
923
  }
924

    
925
  InnerPointerToCodeCache* inner_pointer_to_code_cache() {
926
    return inner_pointer_to_code_cache_;
927
  }
928

    
929
  ConsStringIteratorOp* write_iterator() { return write_iterator_; }
930

    
931
  GlobalHandles* global_handles() { return global_handles_; }
932

    
933
  EternalHandles* eternal_handles() { return eternal_handles_; }
934

    
935
  ThreadManager* thread_manager() { return thread_manager_; }
936

    
937
  ContextSwitcher* context_switcher() { return context_switcher_; }
938

    
939
  void set_context_switcher(ContextSwitcher* switcher) {
940
    context_switcher_ = switcher;
941
  }
942

    
943
  StringTracker* string_tracker() { return string_tracker_; }
944

    
945
  unibrow::Mapping<unibrow::Ecma262UnCanonicalize>* jsregexp_uncanonicalize() {
946
    return &jsregexp_uncanonicalize_;
947
  }
948

    
949
  unibrow::Mapping<unibrow::CanonicalizationRange>* jsregexp_canonrange() {
950
    return &jsregexp_canonrange_;
951
  }
952

    
953
  ConsStringIteratorOp* objects_string_compare_iterator_a() {
954
    return &objects_string_compare_iterator_a_;
955
  }
956

    
957
  ConsStringIteratorOp* objects_string_compare_iterator_b() {
958
    return &objects_string_compare_iterator_b_;
959
  }
960

    
961
  StaticResource<ConsStringIteratorOp>* objects_string_iterator() {
962
    return &objects_string_iterator_;
963
  }
964

    
965
  RuntimeState* runtime_state() { return &runtime_state_; }
966

    
967
  void set_fp_stubs_generated(bool value) {
968
    fp_stubs_generated_ = value;
969
  }
970

    
971
  bool fp_stubs_generated() { return fp_stubs_generated_; }
972

    
973
  Builtins* builtins() { return &builtins_; }
974

    
975
  void NotifyExtensionInstalled() {
976
    has_installed_extensions_ = true;
977
  }
978

    
979
  bool has_installed_extensions() { return has_installed_extensions_; }
980

    
981
  unibrow::Mapping<unibrow::Ecma262Canonicalize>*
982
      regexp_macro_assembler_canonicalize() {
983
    return &regexp_macro_assembler_canonicalize_;
984
  }
985

    
986
  RegExpStack* regexp_stack() { return regexp_stack_; }
987

    
988
  unibrow::Mapping<unibrow::Ecma262Canonicalize>*
989
      interp_canonicalize_mapping() {
990
    return &interp_canonicalize_mapping_;
991
  }
992

    
993
  void* PreallocatedStorageNew(size_t size);
994
  void PreallocatedStorageDelete(void* p);
995
  void PreallocatedStorageInit(size_t size);
996

    
997
  inline bool IsCodePreAgingActive();
998

    
999
#ifdef ENABLE_DEBUGGER_SUPPORT
1000
  Debugger* debugger() {
1001
    if (!NoBarrier_Load(&debugger_initialized_)) InitializeDebugger();
1002
    return debugger_;
1003
  }
1004
  Debug* debug() {
1005
    if (!NoBarrier_Load(&debugger_initialized_)) InitializeDebugger();
1006
    return debug_;
1007
  }
1008
#endif
1009

    
1010
  inline bool IsDebuggerActive();
1011
  inline bool DebuggerHasBreakPoints();
1012

    
1013
  CpuProfiler* cpu_profiler() const { return cpu_profiler_; }
1014
  HeapProfiler* heap_profiler() const { return heap_profiler_; }
1015

    
1016
#ifdef DEBUG
1017
  HistogramInfo* heap_histograms() { return heap_histograms_; }
1018

    
1019
  JSObject::SpillInformation* js_spill_information() {
1020
    return &js_spill_information_;
1021
  }
1022

    
1023
  int* code_kind_statistics() { return code_kind_statistics_; }
1024
#endif
1025

    
1026
#if V8_TARGET_ARCH_ARM && !defined(__arm__) || \
1027
    V8_TARGET_ARCH_MIPS && !defined(__mips__)
1028
  bool simulator_initialized() { return simulator_initialized_; }
1029
  void set_simulator_initialized(bool initialized) {
1030
    simulator_initialized_ = initialized;
1031
  }
1032

    
1033
  HashMap* simulator_i_cache() { return simulator_i_cache_; }
1034
  void set_simulator_i_cache(HashMap* hash_map) {
1035
    simulator_i_cache_ = hash_map;
1036
  }
1037

    
1038
  Redirection* simulator_redirection() {
1039
    return simulator_redirection_;
1040
  }
1041
  void set_simulator_redirection(Redirection* redirection) {
1042
    simulator_redirection_ = redirection;
1043
  }
1044
#endif
1045

    
1046
  Factory* factory() { return reinterpret_cast<Factory*>(this); }
1047

    
1048
  static const int kJSRegexpStaticOffsetsVectorSize = 128;
1049

    
1050
  ExternalCallbackScope* external_callback_scope() {
1051
    return thread_local_top_.external_callback_scope_;
1052
  }
1053
  void set_external_callback_scope(ExternalCallbackScope* scope) {
1054
    thread_local_top_.external_callback_scope_ = scope;
1055
  }
1056

    
1057
  StateTag current_vm_state() {
1058
    return thread_local_top_.current_vm_state_;
1059
  }
1060

    
1061
  void set_current_vm_state(StateTag state) {
1062
    thread_local_top_.current_vm_state_ = state;
1063
  }
1064

    
1065
  void SetData(void* data) { embedder_data_ = data; }
1066
  void* GetData() { return embedder_data_; }
1067

    
1068
  LookupResult* top_lookup_result() {
1069
    return thread_local_top_.top_lookup_result_;
1070
  }
1071
  void SetTopLookupResult(LookupResult* top) {
1072
    thread_local_top_.top_lookup_result_ = top;
1073
  }
1074

    
1075
  bool IsDead() { return has_fatal_error_; }
1076
  void SignalFatalError() { has_fatal_error_ = true; }
1077

    
1078
  bool use_crankshaft() const { return use_crankshaft_; }
1079

    
1080
  bool initialized_from_snapshot() { return initialized_from_snapshot_; }
1081

    
1082
  double time_millis_since_init() {
1083
    return OS::TimeCurrentMillis() - time_millis_at_init_;
1084
  }
1085

    
1086
  DateCache* date_cache() {
1087
    return date_cache_;
1088
  }
1089

    
1090
  void set_date_cache(DateCache* date_cache) {
1091
    if (date_cache != date_cache_) {
1092
      delete date_cache_;
1093
    }
1094
    date_cache_ = date_cache;
1095
  }
1096

    
1097
  Map* get_initial_js_array_map(ElementsKind kind);
1098

    
1099
  bool IsFastArrayConstructorPrototypeChainIntact();
1100

    
1101
  CodeStubInterfaceDescriptor*
1102
      code_stub_interface_descriptor(int index);
1103

    
1104
  void IterateDeferredHandles(ObjectVisitor* visitor);
1105
  void LinkDeferredHandles(DeferredHandles* deferred_handles);
1106
  void UnlinkDeferredHandles(DeferredHandles* deferred_handles);
1107

    
1108
#ifdef DEBUG
1109
  bool IsDeferredHandle(Object** location);
1110
#endif  // DEBUG
1111

    
1112
  OptimizingCompilerThread* optimizing_compiler_thread() {
1113
    return optimizing_compiler_thread_;
1114
  }
1115

    
1116
  // PreInits and returns a default isolate. Needed when a new thread tries
1117
  // to create a Locker for the first time (the lock itself is in the isolate).
1118
  // TODO(svenpanne) This method is on death row...
1119
  static v8::Isolate* GetDefaultIsolateForLocking();
1120

    
1121
  SweeperThread** sweeper_threads() {
1122
    return sweeper_thread_;
1123
  }
1124

    
1125
  int id() const { return static_cast<int>(id_); }
1126

    
1127
  HStatistics* GetHStatistics();
1128
  HTracer* GetHTracer();
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
  State state_;  // Will be padded to kApiPointerSize.
1157
  void* embedder_data_;
1158
  Heap heap_;
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 PreallocatedMemoryThreadStart();
1235
  void PreallocatedMemoryThreadStop();
1236
  void InitializeThreadLocal();
1237

    
1238
  void PrintStackTrace(FILE* out, ThreadLocalTop* thread);
1239
  void MarkCompactPrologue(bool is_compacting,
1240
                           ThreadLocalTop* archived_thread_data);
1241
  void MarkCompactEpilogue(bool is_compacting,
1242
                           ThreadLocalTop* archived_thread_data);
1243

    
1244
  void FillCache();
1245

    
1246
  void PropagatePendingExceptionToExternalTryCatch();
1247

    
1248
  void InitializeDebugger();
1249

    
1250
  // Traverse prototype chain to find out whether the object is derived from
1251
  // the Error object.
1252
  bool IsErrorObject(Handle<Object> obj);
1253

    
1254
  Atomic32 id_;
1255
  EntryStackItem* entry_stack_;
1256
  int stack_trace_nesting_level_;
1257
  StringStream* incomplete_message_;
1258
  // The preallocated memory thread singleton.
1259
  PreallocatedMemoryThread* preallocated_memory_thread_;
1260
  Address isolate_addresses_[kIsolateAddressCount + 1];  // NOLINT
1261
  NoAllocationStringAllocator* preallocated_message_space_;
1262
  Bootstrapper* bootstrapper_;
1263
  RuntimeProfiler* runtime_profiler_;
1264
  CompilationCache* compilation_cache_;
1265
  Counters* counters_;
1266
  CodeRange* code_range_;
1267
  RecursiveMutex break_access_;
1268
  Atomic32 debugger_initialized_;
1269
  RecursiveMutex debugger_access_;
1270
  Logger* logger_;
1271
  StackGuard stack_guard_;
1272
  StatsTable* stats_table_;
1273
  StubCache* stub_cache_;
1274
  DeoptimizerData* deoptimizer_data_;
1275
  ThreadLocalTop thread_local_top_;
1276
  bool capture_stack_trace_for_uncaught_exceptions_;
1277
  int stack_trace_for_uncaught_exceptions_frame_limit_;
1278
  StackTrace::StackTraceOptions stack_trace_for_uncaught_exceptions_options_;
1279
  TranscendentalCache* transcendental_cache_;
1280
  MemoryAllocator* memory_allocator_;
1281
  KeyedLookupCache* keyed_lookup_cache_;
1282
  ContextSlotCache* context_slot_cache_;
1283
  DescriptorLookupCache* descriptor_lookup_cache_;
1284
  v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
1285
  HandleScopeImplementer* handle_scope_implementer_;
1286
  UnicodeCache* unicode_cache_;
1287
  Zone runtime_zone_;
1288
  PreallocatedStorage in_use_list_;
1289
  PreallocatedStorage free_list_;
1290
  bool preallocated_storage_preallocated_;
1291
  InnerPointerToCodeCache* inner_pointer_to_code_cache_;
1292
  ConsStringIteratorOp* write_iterator_;
1293
  GlobalHandles* global_handles_;
1294
  EternalHandles* eternal_handles_;
1295
  ContextSwitcher* context_switcher_;
1296
  ThreadManager* thread_manager_;
1297
  RuntimeState runtime_state_;
1298
  bool fp_stubs_generated_;
1299
  Builtins builtins_;
1300
  bool has_installed_extensions_;
1301
  StringTracker* string_tracker_;
1302
  unibrow::Mapping<unibrow::Ecma262UnCanonicalize> jsregexp_uncanonicalize_;
1303
  unibrow::Mapping<unibrow::CanonicalizationRange> jsregexp_canonrange_;
1304
  ConsStringIteratorOp objects_string_compare_iterator_a_;
1305
  ConsStringIteratorOp objects_string_compare_iterator_b_;
1306
  StaticResource<ConsStringIteratorOp> objects_string_iterator_;
1307
  unibrow::Mapping<unibrow::Ecma262Canonicalize>
1308
      regexp_macro_assembler_canonicalize_;
1309
  RegExpStack* regexp_stack_;
1310
  DateCache* date_cache_;
1311
  unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
1312
  CodeStubInterfaceDescriptor* code_stub_interface_descriptors_;
1313
  RandomNumberGenerator* random_number_generator_;
1314

    
1315
  // True if fatal error has been signaled for this isolate.
1316
  bool has_fatal_error_;
1317

    
1318
  // True if we are using the Crankshaft optimizing compiler.
1319
  bool use_crankshaft_;
1320

    
1321
  // True if this isolate was initialized from a snapshot.
1322
  bool initialized_from_snapshot_;
1323

    
1324
  // Time stamp at initialization.
1325
  double time_millis_at_init_;
1326

    
1327
#if V8_TARGET_ARCH_ARM && !defined(__arm__) || \
1328
    V8_TARGET_ARCH_MIPS && !defined(__mips__)
1329
  bool simulator_initialized_;
1330
  HashMap* simulator_i_cache_;
1331
  Redirection* simulator_redirection_;
1332
#endif
1333

    
1334
#ifdef DEBUG
1335
  // A static array of histogram info for each type.
1336
  HistogramInfo heap_histograms_[LAST_TYPE + 1];
1337
  JSObject::SpillInformation js_spill_information_;
1338
  int code_kind_statistics_[Code::NUMBER_OF_KINDS];
1339
#endif
1340

    
1341
#ifdef ENABLE_DEBUGGER_SUPPORT
1342
  Debugger* debugger_;
1343
  Debug* debug_;
1344
#endif
1345
  CpuProfiler* cpu_profiler_;
1346
  HeapProfiler* heap_profiler_;
1347
  FunctionEntryHook function_entry_hook_;
1348

    
1349
#define GLOBAL_BACKING_STORE(type, name, initialvalue)                         \
1350
  type name##_;
1351
  ISOLATE_INIT_LIST(GLOBAL_BACKING_STORE)
1352
#undef GLOBAL_BACKING_STORE
1353

    
1354
#define GLOBAL_ARRAY_BACKING_STORE(type, name, length)                         \
1355
  type name##_[length];
1356
  ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_BACKING_STORE)
1357
#undef GLOBAL_ARRAY_BACKING_STORE
1358

    
1359
#ifdef DEBUG
1360
  // This class is huge and has a number of fields controlled by
1361
  // preprocessor defines. Make sure the offsets of these fields agree
1362
  // between compilation units.
1363
#define ISOLATE_FIELD_OFFSET(type, name, ignored)                              \
1364
  static const intptr_t name##_debug_offset_;
1365
  ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
1366
  ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
1367
#undef ISOLATE_FIELD_OFFSET
1368
#endif
1369

    
1370
  DeferredHandles* deferred_handles_head_;
1371
  OptimizingCompilerThread* optimizing_compiler_thread_;
1372
  SweeperThread** sweeper_thread_;
1373

    
1374
  // Counts deopt points if deopt_every_n_times is enabled.
1375
  unsigned int stress_deopt_count_;
1376

    
1377
  friend class ExecutionAccess;
1378
  friend class HandleScopeImplementer;
1379
  friend class IsolateInitializer;
1380
  friend class OptimizingCompilerThread;
1381
  friend class SweeperThread;
1382
  friend class ThreadManager;
1383
  friend class Simulator;
1384
  friend class StackGuard;
1385
  friend class ThreadId;
1386
  friend class TestMemoryAllocatorScope;
1387
  friend class TestCodeRangeScope;
1388
  friend class v8::Isolate;
1389
  friend class v8::Locker;
1390
  friend class v8::Unlocker;
1391

    
1392
  DISALLOW_COPY_AND_ASSIGN(Isolate);
1393
};
1394

    
1395

    
1396
// If the GCC version is 4.1.x or 4.2.x an additional field is added to the
1397
// class as a work around for a bug in the generated code found with these
1398
// versions of GCC. See V8 issue 122 for details.
1399
class SaveContext BASE_EMBEDDED {
1400
 public:
1401
  inline explicit SaveContext(Isolate* isolate);
1402

    
1403
  ~SaveContext() {
1404
    isolate_->set_context(context_.is_null() ? NULL : *context_);
1405
    isolate_->set_save_context(prev_);
1406
  }
1407

    
1408
  Handle<Context> context() { return context_; }
1409
  SaveContext* prev() { return prev_; }
1410

    
1411
  // Returns true if this save context is below a given JavaScript frame.
1412
  bool IsBelowFrame(JavaScriptFrame* frame) {
1413
    return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp());
1414
  }
1415

    
1416
 private:
1417
  Isolate* isolate_;
1418
  Handle<Context> context_;
1419
  SaveContext* prev_;
1420
  Address c_entry_fp_;
1421
};
1422

    
1423

    
1424
class AssertNoContextChange BASE_EMBEDDED {
1425
#ifdef DEBUG
1426
 public:
1427
  explicit AssertNoContextChange(Isolate* isolate)
1428
    : isolate_(isolate),
1429
      context_(isolate->context(), isolate) { }
1430
  ~AssertNoContextChange() {
1431
    ASSERT(isolate_->context() == *context_);
1432
  }
1433

    
1434
 private:
1435
  Isolate* isolate_;
1436
  Handle<Context> context_;
1437
#else
1438
 public:
1439
  explicit AssertNoContextChange(Isolate* isolate) { }
1440
#endif
1441
};
1442

    
1443

    
1444
class ExecutionAccess BASE_EMBEDDED {
1445
 public:
1446
  explicit ExecutionAccess(Isolate* isolate) : isolate_(isolate) {
1447
    Lock(isolate);
1448
  }
1449
  ~ExecutionAccess() { Unlock(isolate_); }
1450

    
1451
  static void Lock(Isolate* isolate) { isolate->break_access()->Lock(); }
1452
  static void Unlock(Isolate* isolate) { isolate->break_access()->Unlock(); }
1453

    
1454
  static bool TryLock(Isolate* isolate) {
1455
    return isolate->break_access()->TryLock();
1456
  }
1457

    
1458
 private:
1459
  Isolate* isolate_;
1460
};
1461

    
1462

    
1463
// Support for checking for stack-overflows in C++ code.
1464
class StackLimitCheck BASE_EMBEDDED {
1465
 public:
1466
  explicit StackLimitCheck(Isolate* isolate) : isolate_(isolate) { }
1467

    
1468
  bool HasOverflowed() const {
1469
    StackGuard* stack_guard = isolate_->stack_guard();
1470
    return (reinterpret_cast<uintptr_t>(this) < stack_guard->real_climit());
1471
  }
1472
 private:
1473
  Isolate* isolate_;
1474
};
1475

    
1476

    
1477
// Support for temporarily postponing interrupts. When the outermost
1478
// postpone scope is left the interrupts will be re-enabled and any
1479
// interrupts that occurred while in the scope will be taken into
1480
// account.
1481
class PostponeInterruptsScope BASE_EMBEDDED {
1482
 public:
1483
  explicit PostponeInterruptsScope(Isolate* isolate)
1484
      : stack_guard_(isolate->stack_guard()) {
1485
    stack_guard_->thread_local_.postpone_interrupts_nesting_++;
1486
    stack_guard_->DisableInterrupts();
1487
  }
1488

    
1489
  ~PostponeInterruptsScope() {
1490
    if (--stack_guard_->thread_local_.postpone_interrupts_nesting_ == 0) {
1491
      stack_guard_->EnableInterrupts();
1492
    }
1493
  }
1494
 private:
1495
  StackGuard* stack_guard_;
1496
};
1497

    
1498

    
1499
// Tells whether the native context is marked with out of memory.
1500
inline bool Context::has_out_of_memory() {
1501
  return native_context()->out_of_memory()->IsTrue();
1502
}
1503

    
1504

    
1505
// Mark the native context with out of memory.
1506
inline void Context::mark_out_of_memory() {
1507
  native_context()->set_out_of_memory(GetIsolate()->heap()->true_value());
1508
}
1509

    
1510

    
1511
} }  // namespace v8::internal
1512

    
1513
#endif  // V8_ISOLATE_H_