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 @ 530af9cb

History | View | Annotate | Download (48.9 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 "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"
44
#include "optimizing-compiler-thread.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
class CodeGenerator;
55
class CodeRange;
56
class CompilationCache;
57
class ContextSlotCache;
58
class ContextSwitcher;
59
class Counters;
60
class CpuFeatures;
61
class CpuProfiler;
62
class DeoptimizerData;
63
class Deserializer;
64
class EmptyStatement;
65
class ExternalReferenceTable;
66
class Factory;
67
class FunctionInfoListener;
68
class HandleScopeImplementer;
69
class HeapProfiler;
70
class InlineRuntimeFunctionsTable;
71
class NoAllocationStringAllocator;
72
class InnerPointerToCodeCache;
73
class PreallocatedMemoryThread;
74
class RegExpStack;
75
class SaveContext;
76
class UnicodeCache;
77
class StringInputBuffer;
78
class StringTracker;
79
class StubCache;
80
class ThreadManager;
81
class ThreadState;
82
class ThreadVisitor;  // Defined in v8threads.h
83
class VMState;
84

    
85
// 'void function pointer', used to roundtrip the
86
// ExternalReference::ExternalReferenceRedirector since we can not include
87
// assembler.h, where it is defined, here.
88
typedef void* ExternalReferenceRedirectorPointer();
89

    
90

    
91
#ifdef ENABLE_DEBUGGER_SUPPORT
92
class Debug;
93
class Debugger;
94
class DebuggerAgent;
95
#endif
96

    
97
#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
98
    !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
99
class Redirection;
100
class Simulator;
101
#endif
102

    
103

    
104
// Static indirection table for handles to constants.  If a frame
105
// element represents a constant, the data contains an index into
106
// this table of handles to the actual constants.
107
// Static indirection table for handles to constants.  If a Result
108
// represents a constant, the data contains an index into this table
109
// of handles to the actual constants.
110
typedef ZoneList<Handle<Object> > ZoneObjectList;
111

    
112
#define RETURN_IF_SCHEDULED_EXCEPTION(isolate)            \
113
  do {                                                    \
114
    Isolate* __isolate__ = (isolate);                     \
115
    if (__isolate__->has_scheduled_exception()) {         \
116
      return __isolate__->PromoteScheduledException();    \
117
    }                                                     \
118
  } while (false)
119

    
120
#define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value) \
121
  do {                                                     \
122
    if ((call).is_null()) {                                \
123
      ASSERT((isolate)->has_pending_exception());          \
124
      return (value);                                      \
125
    }                                                      \
126
  } while (false)
127

    
128
#define CHECK_NOT_EMPTY_HANDLE(isolate, call)     \
129
  do {                                            \
130
    ASSERT(!(isolate)->has_pending_exception());  \
131
    CHECK(!(call).is_null());                     \
132
    CHECK(!(isolate)->has_pending_exception());   \
133
  } while (false)
134

    
135
#define RETURN_IF_EMPTY_HANDLE(isolate, call)                       \
136
  RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception())
137

    
138
#define FOR_EACH_ISOLATE_ADDRESS_NAME(C)                \
139
  C(Handler, handler)                                   \
140
  C(CEntryFP, c_entry_fp)                               \
141
  C(Context, context)                                   \
142
  C(PendingException, pending_exception)                \
143
  C(ExternalCaughtException, external_caught_exception) \
144
  C(JSEntrySP, js_entry_sp)
145

    
146

    
147
// Platform-independent, reliable thread identifier.
148
class ThreadId {
149
 public:
150
  // Creates an invalid ThreadId.
151
  ThreadId() : id_(kInvalidId) {}
152

    
153
  // Returns ThreadId for current thread.
154
  static ThreadId Current() { return ThreadId(GetCurrentThreadId()); }
155

    
156
  // Returns invalid ThreadId (guaranteed not to be equal to any thread).
157
  static ThreadId Invalid() { return ThreadId(kInvalidId); }
158

    
159
  // Compares ThreadIds for equality.
160
  INLINE(bool Equals(const ThreadId& other) const) {
161
    return id_ == other.id_;
162
  }
163

    
164
  // Checks whether this ThreadId refers to any thread.
165
  INLINE(bool IsValid() const) {
166
    return id_ != kInvalidId;
167
  }
168

    
169
  // Converts ThreadId to an integer representation
170
  // (required for public API: V8::V8::GetCurrentThreadId).
171
  int ToInteger() const { return id_; }
172

    
173
  // Converts ThreadId to an integer representation
174
  // (required for public API: V8::V8::TerminateExecution).
175
  static ThreadId FromInteger(int id) { return ThreadId(id); }
176

    
177
 private:
178
  static const int kInvalidId = -1;
179

    
180
  explicit ThreadId(int id) : id_(id) {}
181

    
182
  static int AllocateThreadId();
183

    
184
  static int GetCurrentThreadId();
185

    
186
  int id_;
187

    
188
  static Atomic32 highest_thread_id_;
189

    
190
  friend class Isolate;
191
};
192

    
193

    
194
class ThreadLocalTop BASE_EMBEDDED {
195
 public:
196
  // Does early low-level initialization that does not depend on the
197
  // isolate being present.
198
  ThreadLocalTop();
199

    
200
  // Initialize the thread data.
201
  void Initialize();
202

    
203
  // Get the top C++ try catch handler or NULL if none are registered.
204
  //
205
  // This method is not guarenteed to return an address that can be
206
  // used for comparison with addresses into the JS stack.  If such an
207
  // address is needed, use try_catch_handler_address.
208
  v8::TryCatch* TryCatchHandler();
209

    
210
  // Get the address of the top C++ try catch handler or NULL if
211
  // none are registered.
212
  //
213
  // This method always returns an address that can be compared to
214
  // pointers into the JavaScript stack.  When running on actual
215
  // hardware, try_catch_handler_address and TryCatchHandler return
216
  // the same pointer.  When running on a simulator with a separate JS
217
  // stack, try_catch_handler_address returns a JS stack address that
218
  // corresponds to the place on the JS stack where the C++ handler
219
  // would have been if the stack were not separate.
220
  inline Address try_catch_handler_address() {
221
    return try_catch_handler_address_;
222
  }
223

    
224
  // Set the address of the top C++ try catch handler.
225
  inline void set_try_catch_handler_address(Address address) {
226
    try_catch_handler_address_ = address;
227
  }
228

    
229
  void Free() {
230
    ASSERT(!has_pending_message_);
231
    ASSERT(!external_caught_exception_);
232
    ASSERT(try_catch_handler_address_ == NULL);
233
  }
234

    
235
  Isolate* isolate_;
236
  // The context where the current execution method is created and for variable
237
  // lookups.
238
  Context* context_;
239
  ThreadId thread_id_;
240
  MaybeObject* pending_exception_;
241
  bool has_pending_message_;
242
  Object* pending_message_obj_;
243
  Script* pending_message_script_;
244
  int pending_message_start_pos_;
245
  int pending_message_end_pos_;
246
  // Use a separate value for scheduled exceptions to preserve the
247
  // invariants that hold about pending_exception.  We may want to
248
  // unify them later.
249
  MaybeObject* scheduled_exception_;
250
  bool external_caught_exception_;
251
  SaveContext* save_context_;
252
  v8::TryCatch* catcher_;
253

    
254
  // Stack.
255
  Address c_entry_fp_;  // the frame pointer of the top c entry frame
256
  Address handler_;   // try-blocks are chained through the stack
257

    
258
#ifdef USE_SIMULATOR
259
#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
260
  Simulator* simulator_;
261
#endif
262
#endif  // USE_SIMULATOR
263

    
264
  Address js_entry_sp_;  // the stack pointer of the bottom JS entry frame
265
  Address external_callback_;  // the external callback we're currently in
266
  StateTag current_vm_state_;
267

    
268
  // Generated code scratch locations.
269
  int32_t formal_count_;
270

    
271
  // Call back function to report unsafe JS accesses.
272
  v8::FailedAccessCheckCallback failed_access_check_callback_;
273

    
274
  // Head of the list of live LookupResults.
275
  LookupResult* top_lookup_result_;
276

    
277
  // Whether out of memory exceptions should be ignored.
278
  bool ignore_out_of_memory_;
279

    
280
 private:
281
  void InitializeInternal();
282

    
283
  Address try_catch_handler_address_;
284
};
285

    
286

    
287
#ifdef ENABLE_DEBUGGER_SUPPORT
288

    
289
#define ISOLATE_DEBUGGER_INIT_LIST(V)                                          \
290
  V(v8::Debug::EventCallback, debug_event_callback, NULL)                      \
291
  V(DebuggerAgent*, debugger_agent_instance, NULL)
292
#else
293

    
294
#define ISOLATE_DEBUGGER_INIT_LIST(V)
295

    
296
#endif
297

    
298
#ifdef DEBUG
299

    
300
#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)                                       \
301
  V(CommentStatistic, paged_space_comments_statistics,                         \
302
      CommentStatistic::kMaxComments + 1)
303
#else
304

    
305
#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
306

    
307
#endif
308

    
309
#define ISOLATE_INIT_ARRAY_LIST(V)                                             \
310
  /* SerializerDeserializer state. */                                          \
311
  V(int32_t, jsregexp_static_offsets_vector, kJSRegexpStaticOffsetsVectorSize) \
312
  V(int, bad_char_shift_table, kUC16AlphabetSize)                              \
313
  V(int, good_suffix_shift_table, (kBMMaxShift + 1))                           \
314
  V(int, suffix_table, (kBMMaxShift + 1))                                      \
315
  V(uint32_t, private_random_seed, 2)                                          \
316
  ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
317

    
318
typedef List<HeapObject*, PreallocatedStorageAllocationPolicy> DebugObjectCache;
319

    
320
#define ISOLATE_INIT_LIST(V)                                                   \
321
  /* SerializerDeserializer state. */                                          \
322
  V(int, serialize_partial_snapshot_cache_length, 0)                           \
323
  V(int, serialize_partial_snapshot_cache_capacity, 0)                         \
324
  V(Object**, serialize_partial_snapshot_cache, NULL)                          \
325
  /* Assembler state. */                                                       \
326
  /* A previously allocated buffer of kMinimalBufferSize bytes, or NULL. */    \
327
  V(byte*, assembler_spare_buffer, NULL)                                       \
328
  V(FatalErrorCallback, exception_behavior, NULL)                              \
329
  V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, NULL)     \
330
  V(v8::Debug::MessageHandler, message_handler, NULL)                          \
331
  /* To distinguish the function templates, so that we can find them in the */ \
332
  /* function cache of the native context. */                                  \
333
  V(int, next_serial_number, 0)                                                \
334
  V(ExternalReferenceRedirectorPointer*, external_reference_redirector, NULL)  \
335
  V(bool, always_allow_natives_syntax, false)                                  \
336
  /* Part of the state of liveedit. */                                         \
337
  V(FunctionInfoListener*, active_function_info_listener, NULL)                \
338
  /* State for Relocatable. */                                                 \
339
  V(Relocatable*, relocatable_top, NULL)                                       \
340
  /* State for CodeEntry in profile-generator. */                              \
341
  V(CodeGenerator*, current_code_generator, NULL)                              \
342
  V(bool, jump_target_compiling_deferred_code, false)                          \
343
  V(DebugObjectCache*, string_stream_debug_object_cache, NULL)                 \
344
  V(Object*, string_stream_current_security_token, NULL)                       \
345
  /* TODO(isolates): Release this on destruction? */                           \
346
  V(int*, irregexp_interpreter_backtrack_stack_cache, NULL)                    \
347
  /* Serializer state. */                                                      \
348
  V(ExternalReferenceTable*, external_reference_table, NULL)                   \
349
  /* AstNode state. */                                                         \
350
  V(int, ast_node_id, 0)                                                       \
351
  V(unsigned, ast_node_count, 0)                                               \
352
  /* SafeStackFrameIterator activations count. */                              \
353
  V(int, safe_stack_iterator_counter, 0)                                       \
354
  V(uint64_t, enabled_cpu_features, 0)                                         \
355
  V(CpuProfiler*, cpu_profiler, NULL)                                          \
356
  V(HeapProfiler*, heap_profiler, NULL)                                        \
357
  ISOLATE_DEBUGGER_INIT_LIST(V)
358

    
359
class Isolate {
360
  // These forward declarations are required to make the friend declarations in
361
  // PerIsolateThreadData work on some older versions of gcc.
362
  class ThreadDataTable;
363
  class EntryStackItem;
364
 public:
365
  ~Isolate();
366

    
367
  // A thread has a PerIsolateThreadData instance for each isolate that it has
368
  // entered. That instance is allocated when the isolate is initially entered
369
  // and reused on subsequent entries.
370
  class PerIsolateThreadData {
371
   public:
372
    PerIsolateThreadData(Isolate* isolate, ThreadId thread_id)
373
        : isolate_(isolate),
374
          thread_id_(thread_id),
375
          stack_limit_(0),
376
          thread_state_(NULL),
377
#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
378
    !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
379
          simulator_(NULL),
380
#endif
381
          next_(NULL),
382
          prev_(NULL) { }
383
    Isolate* isolate() const { return isolate_; }
384
    ThreadId thread_id() const { return thread_id_; }
385
    void set_stack_limit(uintptr_t value) { stack_limit_ = value; }
386
    uintptr_t stack_limit() const { return stack_limit_; }
387
    ThreadState* thread_state() const { return thread_state_; }
388
    void set_thread_state(ThreadState* value) { thread_state_ = value; }
389

    
390
#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
391
    !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
392
    Simulator* simulator() const { return simulator_; }
393
    void set_simulator(Simulator* simulator) {
394
      simulator_ = simulator;
395
    }
396
#endif
397

    
398
    bool Matches(Isolate* isolate, ThreadId thread_id) const {
399
      return isolate_ == isolate && thread_id_.Equals(thread_id);
400
    }
401

    
402
   private:
403
    Isolate* isolate_;
404
    ThreadId thread_id_;
405
    uintptr_t stack_limit_;
406
    ThreadState* thread_state_;
407

    
408
#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
409
    !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
410
    Simulator* simulator_;
411
#endif
412

    
413
    PerIsolateThreadData* next_;
414
    PerIsolateThreadData* prev_;
415

    
416
    friend class Isolate;
417
    friend class ThreadDataTable;
418
    friend class EntryStackItem;
419

    
420
    DISALLOW_COPY_AND_ASSIGN(PerIsolateThreadData);
421
  };
422

    
423

    
424
  enum AddressId {
425
#define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address,
426
    FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM)
427
#undef DECLARE_ENUM
428
    kIsolateAddressCount
429
  };
430

    
431
  // Returns the PerIsolateThreadData for the current thread (or NULL if one is
432
  // not currently set).
433
  static PerIsolateThreadData* CurrentPerIsolateThreadData() {
434
    return reinterpret_cast<PerIsolateThreadData*>(
435
        Thread::GetThreadLocal(per_isolate_thread_data_key_));
436
  }
437

    
438
  // Returns the isolate inside which the current thread is running.
439
  INLINE(static Isolate* Current()) {
440
    Isolate* isolate = reinterpret_cast<Isolate*>(
441
        Thread::GetExistingThreadLocal(isolate_key_));
442
    ASSERT(isolate != NULL);
443
    return isolate;
444
  }
445

    
446
  INLINE(static Isolate* UncheckedCurrent()) {
447
    return reinterpret_cast<Isolate*>(Thread::GetThreadLocal(isolate_key_));
448
  }
449

    
450
  // Usually called by Init(), but can be called early e.g. to allow
451
  // testing components that require logging but not the whole
452
  // isolate.
453
  //
454
  // Safe to call more than once.
455
  void InitializeLoggingAndCounters();
456

    
457
  bool Init(Deserializer* des);
458

    
459
  bool IsInitialized() { return state_ == INITIALIZED; }
460

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

    
464
  // Destroys the non-default isolates.
465
  // Sets default isolate into "has_been_disposed" state rather then destroying,
466
  // for legacy API reasons.
467
  void TearDown();
468

    
469
  bool IsDefaultIsolate() const { return this == default_isolate_; }
470

    
471
  // Ensures that process-wide resources and the default isolate have been
472
  // allocated. It is only necessary to call this method in rare cases, for
473
  // example if you are using V8 from within the body of a static initializer.
474
  // Safe to call multiple times.
475
  static void EnsureDefaultIsolate();
476

    
477
  // Find the PerThread for this particular (isolate, thread) combination
478
  // If one does not yet exist, return null.
479
  PerIsolateThreadData* FindPerThreadDataForThisThread();
480

    
481
#ifdef ENABLE_DEBUGGER_SUPPORT
482
  // Get the debugger from the default isolate. Preinitializes the
483
  // default isolate if needed.
484
  static Debugger* GetDefaultIsolateDebugger();
485
#endif
486

    
487
  // Get the stack guard from the default isolate. Preinitializes the
488
  // default isolate if needed.
489
  static StackGuard* GetDefaultIsolateStackGuard();
490

    
491
  // Returns the key used to store the pointer to the current isolate.
492
  // Used internally for V8 threads that do not execute JavaScript but still
493
  // are part of the domain of an isolate (like the context switcher).
494
  static Thread::LocalStorageKey isolate_key() {
495
    return isolate_key_;
496
  }
497

    
498
  // Returns the key used to store process-wide thread IDs.
499
  static Thread::LocalStorageKey thread_id_key() {
500
    return thread_id_key_;
501
  }
502

    
503
  static Thread::LocalStorageKey per_isolate_thread_data_key();
504

    
505
  // If a client attempts to create a Locker without specifying an isolate,
506
  // we assume that the client is using legacy behavior. Set up the current
507
  // thread to be inside the implicit isolate (or fail a check if we have
508
  // switched to non-legacy behavior).
509
  static void EnterDefaultIsolate();
510

    
511
  // Mutex for serializing access to break control structures.
512
  Mutex* break_access() { return break_access_; }
513

    
514
  // Mutex for serializing access to debugger.
515
  Mutex* debugger_access() { return debugger_access_; }
516

    
517
  Address get_address_from_id(AddressId id);
518

    
519
  // Access to top context (where the current function object was created).
520
  Context* context() { return thread_local_top_.context_; }
521
  void set_context(Context* context) {
522
    ASSERT(context == NULL || context->IsContext());
523
    thread_local_top_.context_ = context;
524
  }
525
  Context** context_address() { return &thread_local_top_.context_; }
526

    
527
  SaveContext* save_context() {return thread_local_top_.save_context_; }
528
  void set_save_context(SaveContext* save) {
529
    thread_local_top_.save_context_ = save;
530
  }
531

    
532
  // Access to the map of "new Object()".
533
  Map* empty_object_map() {
534
    return context()->native_context()->object_function()->map();
535
  }
536

    
537
  // Access to current thread id.
538
  ThreadId thread_id() { return thread_local_top_.thread_id_; }
539
  void set_thread_id(ThreadId id) { thread_local_top_.thread_id_ = id; }
540

    
541
  // Interface to pending exception.
542
  MaybeObject* pending_exception() {
543
    ASSERT(has_pending_exception());
544
    return thread_local_top_.pending_exception_;
545
  }
546
  bool external_caught_exception() {
547
    return thread_local_top_.external_caught_exception_;
548
  }
549
  void set_external_caught_exception(bool value) {
550
    thread_local_top_.external_caught_exception_ = value;
551
  }
552
  void set_pending_exception(MaybeObject* exception) {
553
    thread_local_top_.pending_exception_ = exception;
554
  }
555
  void clear_pending_exception() {
556
    thread_local_top_.pending_exception_ = heap_.the_hole_value();
557
  }
558
  MaybeObject** pending_exception_address() {
559
    return &thread_local_top_.pending_exception_;
560
  }
561
  bool has_pending_exception() {
562
    return !thread_local_top_.pending_exception_->IsTheHole();
563
  }
564
  void clear_pending_message() {
565
    thread_local_top_.has_pending_message_ = false;
566
    thread_local_top_.pending_message_obj_ = heap_.the_hole_value();
567
    thread_local_top_.pending_message_script_ = NULL;
568
  }
569
  v8::TryCatch* try_catch_handler() {
570
    return thread_local_top_.TryCatchHandler();
571
  }
572
  Address try_catch_handler_address() {
573
    return thread_local_top_.try_catch_handler_address();
574
  }
575
  bool* external_caught_exception_address() {
576
    return &thread_local_top_.external_caught_exception_;
577
  }
578
  v8::TryCatch* catcher() {
579
    return thread_local_top_.catcher_;
580
  }
581
  void set_catcher(v8::TryCatch* catcher) {
582
    thread_local_top_.catcher_ = catcher;
583
  }
584

    
585
  MaybeObject** scheduled_exception_address() {
586
    return &thread_local_top_.scheduled_exception_;
587
  }
588

    
589
  Address pending_message_obj_address() {
590
    return reinterpret_cast<Address>(&thread_local_top_.pending_message_obj_);
591
  }
592

    
593
  Address has_pending_message_address() {
594
    return reinterpret_cast<Address>(&thread_local_top_.has_pending_message_);
595
  }
596

    
597
  Address pending_message_script_address() {
598
    return reinterpret_cast<Address>(
599
        &thread_local_top_.pending_message_script_);
600
  }
601

    
602
  MaybeObject* scheduled_exception() {
603
    ASSERT(has_scheduled_exception());
604
    return thread_local_top_.scheduled_exception_;
605
  }
606
  bool has_scheduled_exception() {
607
    return thread_local_top_.scheduled_exception_ != heap_.the_hole_value();
608
  }
609
  void clear_scheduled_exception() {
610
    thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
611
  }
612

    
613
  bool IsExternallyCaught();
614

    
615
  bool is_catchable_by_javascript(MaybeObject* exception) {
616
    return (exception != Failure::OutOfMemoryException()) &&
617
        (exception != heap()->termination_exception());
618
  }
619

    
620
  // Serializer.
621
  void PushToPartialSnapshotCache(Object* obj);
622

    
623
  // JS execution stack (see frames.h).
624
  static Address c_entry_fp(ThreadLocalTop* thread) {
625
    return thread->c_entry_fp_;
626
  }
627
  static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
628

    
629
  inline Address* c_entry_fp_address() {
630
    return &thread_local_top_.c_entry_fp_;
631
  }
632
  inline Address* handler_address() { return &thread_local_top_.handler_; }
633

    
634
  // Bottom JS entry (see StackTracer::Trace in log.cc).
635
  static Address js_entry_sp(ThreadLocalTop* thread) {
636
    return thread->js_entry_sp_;
637
  }
638
  inline Address* js_entry_sp_address() {
639
    return &thread_local_top_.js_entry_sp_;
640
  }
641

    
642
  // Generated code scratch locations.
643
  void* formal_count_address() { return &thread_local_top_.formal_count_; }
644

    
645
  // Returns the global object of the current context. It could be
646
  // a builtin object, or a JS global object.
647
  Handle<GlobalObject> global_object() {
648
    return Handle<GlobalObject>(context()->global_object());
649
  }
650

    
651
  // Returns the global proxy object of the current context.
652
  Object* global_proxy() {
653
    return context()->global_proxy();
654
  }
655

    
656
  Handle<JSBuiltinsObject> js_builtins_object() {
657
    return Handle<JSBuiltinsObject>(thread_local_top_.context_->builtins());
658
  }
659

    
660
  static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
661
  void FreeThreadResources() { thread_local_top_.Free(); }
662

    
663
  // This method is called by the api after operations that may throw
664
  // exceptions.  If an exception was thrown and not handled by an external
665
  // handler the exception is scheduled to be rethrown when we return to running
666
  // JavaScript code.  If an exception is scheduled true is returned.
667
  bool OptionalRescheduleException(bool is_bottom_call);
668

    
669
  class ExceptionScope {
670
   public:
671
    explicit ExceptionScope(Isolate* isolate) :
672
      // Scope currently can only be used for regular exceptions, not
673
      // failures like OOM or termination exception.
674
      isolate_(isolate),
675
      pending_exception_(isolate_->pending_exception()->ToObjectUnchecked()),
676
      catcher_(isolate_->catcher())
677
    { }
678

    
679
    ~ExceptionScope() {
680
      isolate_->set_catcher(catcher_);
681
      isolate_->set_pending_exception(*pending_exception_);
682
    }
683

    
684
   private:
685
    Isolate* isolate_;
686
    Handle<Object> pending_exception_;
687
    v8::TryCatch* catcher_;
688
  };
689

    
690
  void SetCaptureStackTraceForUncaughtExceptions(
691
      bool capture,
692
      int frame_limit,
693
      StackTrace::StackTraceOptions options);
694

    
695
  // Tells whether the current context has experienced an out of memory
696
  // exception.
697
  bool is_out_of_memory();
698
  bool ignore_out_of_memory() {
699
    return thread_local_top_.ignore_out_of_memory_;
700
  }
701
  void set_ignore_out_of_memory(bool value) {
702
    thread_local_top_.ignore_out_of_memory_ = value;
703
  }
704

    
705
  void PrintCurrentStackTrace(FILE* out);
706
  void PrintStackTrace(FILE* out, char* thread_data);
707
  void PrintStack(StringStream* accumulator);
708
  void PrintStack();
709
  Handle<String> StackTraceString();
710
  NO_INLINE(void PushStackTraceAndDie(unsigned int magic,
711
                                      Object* object,
712
                                      Map* map,
713
                                      unsigned int magic2));
714
  Handle<JSArray> CaptureCurrentStackTrace(
715
      int frame_limit,
716
      StackTrace::StackTraceOptions options);
717

    
718
  void CaptureAndSetCurrentStackTraceFor(Handle<JSObject> error_object);
719

    
720
  // Returns if the top context may access the given global object. If
721
  // the result is false, the pending exception is guaranteed to be
722
  // set.
723
  bool MayNamedAccess(JSObject* receiver,
724
                      Object* key,
725
                      v8::AccessType type);
726
  bool MayIndexedAccess(JSObject* receiver,
727
                        uint32_t index,
728
                        v8::AccessType type);
729

    
730
  void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
731
  void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
732

    
733
  // Exception throwing support. The caller should use the result
734
  // of Throw() as its return value.
735
  Failure* Throw(Object* exception, MessageLocation* location = NULL);
736
  // Re-throw an exception.  This involves no error reporting since
737
  // error reporting was handled when the exception was thrown
738
  // originally.
739
  Failure* ReThrow(MaybeObject* exception);
740
  void ScheduleThrow(Object* exception);
741
  void ReportPendingMessages();
742
  Failure* ThrowIllegalOperation();
743

    
744
  // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
745
  Failure* PromoteScheduledException();
746
  void DoThrow(Object* exception, MessageLocation* location);
747
  // Checks if exception should be reported and finds out if it's
748
  // caught externally.
749
  bool ShouldReportException(bool* can_be_caught_externally,
750
                             bool catchable_by_javascript);
751

    
752
  // Attempts to compute the current source location, storing the
753
  // result in the target out parameter.
754
  void ComputeLocation(MessageLocation* target);
755

    
756
  // Override command line flag.
757
  void TraceException(bool flag);
758

    
759
  // Out of resource exception helpers.
760
  Failure* StackOverflow();
761
  Failure* TerminateExecution();
762

    
763
  // Administration
764
  void Iterate(ObjectVisitor* v);
765
  void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
766
  char* Iterate(ObjectVisitor* v, char* t);
767
  void IterateThread(ThreadVisitor* v);
768
  void IterateThread(ThreadVisitor* v, char* t);
769

    
770

    
771
  // Returns the current native and global context.
772
  Handle<Context> native_context();
773
  Handle<Context> global_context();
774

    
775
  // Returns the native context of the calling JavaScript code.  That
776
  // is, the native context of the top-most JavaScript frame.
777
  Handle<Context> GetCallingNativeContext();
778

    
779
  void RegisterTryCatchHandler(v8::TryCatch* that);
780
  void UnregisterTryCatchHandler(v8::TryCatch* that);
781

    
782
  char* ArchiveThread(char* to);
783
  char* RestoreThread(char* from);
784

    
785
  static const char* const kStackOverflowMessage;
786

    
787
  static const int kUC16AlphabetSize = 256;  // See StringSearchBase.
788
  static const int kBMMaxShift = 250;        // See StringSearchBase.
789

    
790
  // Accessors.
791
#define GLOBAL_ACCESSOR(type, name, initialvalue)                       \
792
  inline type name() const {                                            \
793
    ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
794
    return name##_;                                                     \
795
  }                                                                     \
796
  inline void set_##name(type value) {                                  \
797
    ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
798
    name##_ = value;                                                    \
799
  }
800
  ISOLATE_INIT_LIST(GLOBAL_ACCESSOR)
801
#undef GLOBAL_ACCESSOR
802

    
803
#define GLOBAL_ARRAY_ACCESSOR(type, name, length)                       \
804
  inline type* name() {                                                 \
805
    ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_);        \
806
    return &(name##_)[0];                                               \
807
  }
808
  ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR)
809
#undef GLOBAL_ARRAY_ACCESSOR
810

    
811
#define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name)      \
812
  Handle<type> name() {                                       \
813
    return Handle<type>(context()->native_context()->name()); \
814
  }
815
  NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR)
816
#undef NATIVE_CONTEXT_FIELD_ACCESSOR
817

    
818
  Bootstrapper* bootstrapper() { return bootstrapper_; }
819
  Counters* counters() {
820
    // Call InitializeLoggingAndCounters() if logging is needed before
821
    // the isolate is fully initialized.
822
    ASSERT(counters_ != NULL);
823
    return counters_;
824
  }
825
  CodeRange* code_range() { return code_range_; }
826
  RuntimeProfiler* runtime_profiler() { return runtime_profiler_; }
827
  CompilationCache* compilation_cache() { return compilation_cache_; }
828
  Logger* logger() {
829
    // Call InitializeLoggingAndCounters() if logging is needed before
830
    // the isolate is fully initialized.
831
    ASSERT(logger_ != NULL);
832
    return logger_;
833
  }
834
  StackGuard* stack_guard() { return &stack_guard_; }
835
  Heap* heap() { return &heap_; }
836
  StatsTable* stats_table();
837
  StubCache* stub_cache() { return stub_cache_; }
838
  DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
839
  ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
840

    
841
  TranscendentalCache* transcendental_cache() const {
842
    return transcendental_cache_;
843
  }
844

    
845
  MemoryAllocator* memory_allocator() {
846
    return memory_allocator_;
847
  }
848

    
849
  KeyedLookupCache* keyed_lookup_cache() {
850
    return keyed_lookup_cache_;
851
  }
852

    
853
  ContextSlotCache* context_slot_cache() {
854
    return context_slot_cache_;
855
  }
856

    
857
  DescriptorLookupCache* descriptor_lookup_cache() {
858
    return descriptor_lookup_cache_;
859
  }
860

    
861
  v8::ImplementationUtilities::HandleScopeData* handle_scope_data() {
862
    return &handle_scope_data_;
863
  }
864
  HandleScopeImplementer* handle_scope_implementer() {
865
    ASSERT(handle_scope_implementer_);
866
    return handle_scope_implementer_;
867
  }
868
  Zone* runtime_zone() { return &runtime_zone_; }
869

    
870
  UnicodeCache* unicode_cache() {
871
    return unicode_cache_;
872
  }
873

    
874
  InnerPointerToCodeCache* inner_pointer_to_code_cache() {
875
    return inner_pointer_to_code_cache_;
876
  }
877

    
878
  StringInputBuffer* write_input_buffer() { return write_input_buffer_; }
879

    
880
  GlobalHandles* global_handles() { return global_handles_; }
881

    
882
  ThreadManager* thread_manager() { return thread_manager_; }
883

    
884
  ContextSwitcher* context_switcher() { return context_switcher_; }
885

    
886
  void set_context_switcher(ContextSwitcher* switcher) {
887
    context_switcher_ = switcher;
888
  }
889

    
890
  StringTracker* string_tracker() { return string_tracker_; }
891

    
892
  unibrow::Mapping<unibrow::Ecma262UnCanonicalize>* jsregexp_uncanonicalize() {
893
    return &jsregexp_uncanonicalize_;
894
  }
895

    
896
  unibrow::Mapping<unibrow::CanonicalizationRange>* jsregexp_canonrange() {
897
    return &jsregexp_canonrange_;
898
  }
899

    
900
  StringInputBuffer* objects_string_compare_buffer_a() {
901
    return &objects_string_compare_buffer_a_;
902
  }
903

    
904
  StringInputBuffer* objects_string_compare_buffer_b() {
905
    return &objects_string_compare_buffer_b_;
906
  }
907

    
908
  StaticResource<StringInputBuffer>* objects_string_input_buffer() {
909
    return &objects_string_input_buffer_;
910
  }
911

    
912
  RuntimeState* runtime_state() { return &runtime_state_; }
913

    
914
  void set_fp_stubs_generated(bool value) {
915
    fp_stubs_generated_ = value;
916
  }
917

    
918
  bool fp_stubs_generated() { return fp_stubs_generated_; }
919

    
920
  StaticResource<SafeStringInputBuffer>* compiler_safe_string_input_buffer() {
921
    return &compiler_safe_string_input_buffer_;
922
  }
923

    
924
  Builtins* builtins() { return &builtins_; }
925

    
926
  void NotifyExtensionInstalled() {
927
    has_installed_extensions_ = true;
928
  }
929

    
930
  bool has_installed_extensions() { return has_installed_extensions_; }
931

    
932
  unibrow::Mapping<unibrow::Ecma262Canonicalize>*
933
      regexp_macro_assembler_canonicalize() {
934
    return &regexp_macro_assembler_canonicalize_;
935
  }
936

    
937
  RegExpStack* regexp_stack() { return regexp_stack_; }
938

    
939
  unibrow::Mapping<unibrow::Ecma262Canonicalize>*
940
      interp_canonicalize_mapping() {
941
    return &interp_canonicalize_mapping_;
942
  }
943

    
944
  void* PreallocatedStorageNew(size_t size);
945
  void PreallocatedStorageDelete(void* p);
946
  void PreallocatedStorageInit(size_t size);
947

    
948
#ifdef ENABLE_DEBUGGER_SUPPORT
949
  Debugger* debugger() {
950
    if (!NoBarrier_Load(&debugger_initialized_)) InitializeDebugger();
951
    return debugger_;
952
  }
953
  Debug* debug() {
954
    if (!NoBarrier_Load(&debugger_initialized_)) InitializeDebugger();
955
    return debug_;
956
  }
957
#endif
958

    
959
  inline bool IsDebuggerActive();
960
  inline bool DebuggerHasBreakPoints();
961

    
962
#ifdef DEBUG
963
  HistogramInfo* heap_histograms() { return heap_histograms_; }
964

    
965
  JSObject::SpillInformation* js_spill_information() {
966
    return &js_spill_information_;
967
  }
968

    
969
  int* code_kind_statistics() { return code_kind_statistics_; }
970
#endif
971

    
972
#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
973
    defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
974
  bool simulator_initialized() { return simulator_initialized_; }
975
  void set_simulator_initialized(bool initialized) {
976
    simulator_initialized_ = initialized;
977
  }
978

    
979
  HashMap* simulator_i_cache() { return simulator_i_cache_; }
980
  void set_simulator_i_cache(HashMap* hash_map) {
981
    simulator_i_cache_ = hash_map;
982
  }
983

    
984
  Redirection* simulator_redirection() {
985
    return simulator_redirection_;
986
  }
987
  void set_simulator_redirection(Redirection* redirection) {
988
    simulator_redirection_ = redirection;
989
  }
990
#endif
991

    
992
  Factory* factory() { return reinterpret_cast<Factory*>(this); }
993

    
994
  static const int kJSRegexpStaticOffsetsVectorSize = 128;
995

    
996
  Address external_callback() {
997
    return thread_local_top_.external_callback_;
998
  }
999
  void set_external_callback(Address callback) {
1000
    thread_local_top_.external_callback_ = callback;
1001
  }
1002

    
1003
  StateTag current_vm_state() {
1004
    return thread_local_top_.current_vm_state_;
1005
  }
1006

    
1007
  void SetCurrentVMState(StateTag state) {
1008
    if (RuntimeProfiler::IsEnabled()) {
1009
      // Make sure thread local top is initialized.
1010
      ASSERT(thread_local_top_.isolate_ == this);
1011
      StateTag current_state = thread_local_top_.current_vm_state_;
1012
      if (current_state != JS && state == JS) {
1013
        // Non-JS -> JS transition.
1014
        RuntimeProfiler::IsolateEnteredJS(this);
1015
      } else if (current_state == JS && state != JS) {
1016
        // JS -> non-JS transition.
1017
        ASSERT(RuntimeProfiler::IsSomeIsolateInJS());
1018
        RuntimeProfiler::IsolateExitedJS(this);
1019
      } else {
1020
        // Other types of state transitions are not interesting to the
1021
        // runtime profiler, because they don't affect whether we're
1022
        // in JS or not.
1023
        ASSERT((current_state == JS) == (state == JS));
1024
      }
1025
    }
1026
    thread_local_top_.current_vm_state_ = state;
1027
  }
1028

    
1029
  void SetData(void* data) { embedder_data_ = data; }
1030
  void* GetData() { return embedder_data_; }
1031

    
1032
  LookupResult* top_lookup_result() {
1033
    return thread_local_top_.top_lookup_result_;
1034
  }
1035
  void SetTopLookupResult(LookupResult* top) {
1036
    thread_local_top_.top_lookup_result_ = top;
1037
  }
1038

    
1039
  bool context_exit_happened() {
1040
    return context_exit_happened_;
1041
  }
1042
  void set_context_exit_happened(bool context_exit_happened) {
1043
    context_exit_happened_ = context_exit_happened;
1044
  }
1045

    
1046
  double time_millis_since_init() {
1047
    return OS::TimeCurrentMillis() - time_millis_at_init_;
1048
  }
1049

    
1050
  DateCache* date_cache() {
1051
    return date_cache_;
1052
  }
1053

    
1054
  void set_date_cache(DateCache* date_cache) {
1055
    if (date_cache != date_cache_) {
1056
      delete date_cache_;
1057
    }
1058
    date_cache_ = date_cache;
1059
  }
1060

    
1061
  void IterateDeferredHandles(ObjectVisitor* visitor);
1062
  void LinkDeferredHandles(DeferredHandles* deferred_handles);
1063
  void UnlinkDeferredHandles(DeferredHandles* deferred_handles);
1064

    
1065
  OptimizingCompilerThread* optimizing_compiler_thread() {
1066
    return &optimizing_compiler_thread_;
1067
  }
1068

    
1069
 private:
1070
  Isolate();
1071

    
1072
  friend struct GlobalState;
1073
  friend struct InitializeGlobalState;
1074

    
1075
  enum State {
1076
    UNINITIALIZED,    // Some components may not have been allocated.
1077
    INITIALIZED       // All components are fully initialized.
1078
  };
1079

    
1080
  // These fields are accessed through the API, offsets must be kept in sync
1081
  // with v8::internal::Internals (in include/v8.h) constants. This is also
1082
  // verified in Isolate::Init() using runtime checks.
1083
  State state_;  // Will be padded to kApiPointerSize.
1084
  void* embedder_data_;
1085
  Heap heap_;
1086

    
1087
  // The per-process lock should be acquired before the ThreadDataTable is
1088
  // modified.
1089
  class ThreadDataTable {
1090
   public:
1091
    ThreadDataTable();
1092
    ~ThreadDataTable();
1093

    
1094
    PerIsolateThreadData* Lookup(Isolate* isolate, ThreadId thread_id);
1095
    void Insert(PerIsolateThreadData* data);
1096
    void Remove(Isolate* isolate, ThreadId thread_id);
1097
    void Remove(PerIsolateThreadData* data);
1098
    void RemoveAllThreads(Isolate* isolate);
1099

    
1100
   private:
1101
    PerIsolateThreadData* list_;
1102
  };
1103

    
1104
  // These items form a stack synchronously with threads Enter'ing and Exit'ing
1105
  // the Isolate. The top of the stack points to a thread which is currently
1106
  // running the Isolate. When the stack is empty, the Isolate is considered
1107
  // not entered by any thread and can be Disposed.
1108
  // If the same thread enters the Isolate more then once, the entry_count_
1109
  // is incremented rather then a new item pushed to the stack.
1110
  class EntryStackItem {
1111
   public:
1112
    EntryStackItem(PerIsolateThreadData* previous_thread_data,
1113
                   Isolate* previous_isolate,
1114
                   EntryStackItem* previous_item)
1115
        : entry_count(1),
1116
          previous_thread_data(previous_thread_data),
1117
          previous_isolate(previous_isolate),
1118
          previous_item(previous_item) { }
1119

    
1120
    int entry_count;
1121
    PerIsolateThreadData* previous_thread_data;
1122
    Isolate* previous_isolate;
1123
    EntryStackItem* previous_item;
1124

    
1125
   private:
1126
    DISALLOW_COPY_AND_ASSIGN(EntryStackItem);
1127
  };
1128

    
1129
  // This mutex protects highest_thread_id_, thread_data_table_ and
1130
  // default_isolate_.
1131
  static Mutex* process_wide_mutex_;
1132

    
1133
  static Thread::LocalStorageKey per_isolate_thread_data_key_;
1134
  static Thread::LocalStorageKey isolate_key_;
1135
  static Thread::LocalStorageKey thread_id_key_;
1136
  static Isolate* default_isolate_;
1137
  static ThreadDataTable* thread_data_table_;
1138

    
1139
  void Deinit();
1140

    
1141
  static void SetIsolateThreadLocals(Isolate* isolate,
1142
                                     PerIsolateThreadData* data);
1143

    
1144
  // Allocate and insert PerIsolateThreadData into the ThreadDataTable
1145
  // (regardless of whether such data already exists).
1146
  PerIsolateThreadData* AllocatePerIsolateThreadData(ThreadId thread_id);
1147

    
1148
  // Find the PerThread for this particular (isolate, thread) combination.
1149
  // If one does not yet exist, allocate a new one.
1150
  PerIsolateThreadData* FindOrAllocatePerThreadDataForThisThread();
1151

    
1152
  // PreInits and returns a default isolate. Needed when a new thread tries
1153
  // to create a Locker for the first time (the lock itself is in the isolate).
1154
  static Isolate* GetDefaultIsolateForLocking();
1155

    
1156
  // Initializes the current thread to run this Isolate.
1157
  // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
1158
  // at the same time, this should be prevented using external locking.
1159
  void Enter();
1160

    
1161
  // Exits the current thread. The previosuly entered Isolate is restored
1162
  // for the thread.
1163
  // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
1164
  // at the same time, this should be prevented using external locking.
1165
  void Exit();
1166

    
1167
  void PreallocatedMemoryThreadStart();
1168
  void PreallocatedMemoryThreadStop();
1169
  void InitializeThreadLocal();
1170

    
1171
  void PrintStackTrace(FILE* out, ThreadLocalTop* thread);
1172
  void MarkCompactPrologue(bool is_compacting,
1173
                           ThreadLocalTop* archived_thread_data);
1174
  void MarkCompactEpilogue(bool is_compacting,
1175
                           ThreadLocalTop* archived_thread_data);
1176

    
1177
  void FillCache();
1178

    
1179
  void PropagatePendingExceptionToExternalTryCatch();
1180

    
1181
  void InitializeDebugger();
1182

    
1183
  // Traverse prototype chain to find out whether the object is derived from
1184
  // the Error object.
1185
  bool IsErrorObject(Handle<Object> obj);
1186

    
1187
  EntryStackItem* entry_stack_;
1188
  int stack_trace_nesting_level_;
1189
  StringStream* incomplete_message_;
1190
  // The preallocated memory thread singleton.
1191
  PreallocatedMemoryThread* preallocated_memory_thread_;
1192
  Address isolate_addresses_[kIsolateAddressCount + 1];  // NOLINT
1193
  NoAllocationStringAllocator* preallocated_message_space_;
1194
  Bootstrapper* bootstrapper_;
1195
  RuntimeProfiler* runtime_profiler_;
1196
  CompilationCache* compilation_cache_;
1197
  Counters* counters_;
1198
  CodeRange* code_range_;
1199
  Mutex* break_access_;
1200
  Atomic32 debugger_initialized_;
1201
  Mutex* debugger_access_;
1202
  Logger* logger_;
1203
  StackGuard stack_guard_;
1204
  StatsTable* stats_table_;
1205
  StubCache* stub_cache_;
1206
  DeoptimizerData* deoptimizer_data_;
1207
  ThreadLocalTop thread_local_top_;
1208
  bool capture_stack_trace_for_uncaught_exceptions_;
1209
  int stack_trace_for_uncaught_exceptions_frame_limit_;
1210
  StackTrace::StackTraceOptions stack_trace_for_uncaught_exceptions_options_;
1211
  TranscendentalCache* transcendental_cache_;
1212
  MemoryAllocator* memory_allocator_;
1213
  KeyedLookupCache* keyed_lookup_cache_;
1214
  ContextSlotCache* context_slot_cache_;
1215
  DescriptorLookupCache* descriptor_lookup_cache_;
1216
  v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
1217
  HandleScopeImplementer* handle_scope_implementer_;
1218
  UnicodeCache* unicode_cache_;
1219
  Zone runtime_zone_;
1220
  PreallocatedStorage in_use_list_;
1221
  PreallocatedStorage free_list_;
1222
  bool preallocated_storage_preallocated_;
1223
  InnerPointerToCodeCache* inner_pointer_to_code_cache_;
1224
  StringInputBuffer* write_input_buffer_;
1225
  GlobalHandles* global_handles_;
1226
  ContextSwitcher* context_switcher_;
1227
  ThreadManager* thread_manager_;
1228
  RuntimeState runtime_state_;
1229
  bool fp_stubs_generated_;
1230
  StaticResource<SafeStringInputBuffer> compiler_safe_string_input_buffer_;
1231
  Builtins builtins_;
1232
  bool has_installed_extensions_;
1233
  StringTracker* string_tracker_;
1234
  unibrow::Mapping<unibrow::Ecma262UnCanonicalize> jsregexp_uncanonicalize_;
1235
  unibrow::Mapping<unibrow::CanonicalizationRange> jsregexp_canonrange_;
1236
  StringInputBuffer objects_string_compare_buffer_a_;
1237
  StringInputBuffer objects_string_compare_buffer_b_;
1238
  StaticResource<StringInputBuffer> objects_string_input_buffer_;
1239
  unibrow::Mapping<unibrow::Ecma262Canonicalize>
1240
      regexp_macro_assembler_canonicalize_;
1241
  RegExpStack* regexp_stack_;
1242
  DateCache* date_cache_;
1243
  unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
1244

    
1245
  // The garbage collector should be a little more aggressive when it knows
1246
  // that a context was recently exited.
1247
  bool context_exit_happened_;
1248

    
1249
  // Time stamp at initialization.
1250
  double time_millis_at_init_;
1251

    
1252
#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
1253
    defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
1254
  bool simulator_initialized_;
1255
  HashMap* simulator_i_cache_;
1256
  Redirection* simulator_redirection_;
1257
#endif
1258

    
1259
#ifdef DEBUG
1260
  // A static array of histogram info for each type.
1261
  HistogramInfo heap_histograms_[LAST_TYPE + 1];
1262
  JSObject::SpillInformation js_spill_information_;
1263
  int code_kind_statistics_[Code::NUMBER_OF_KINDS];
1264
#endif
1265

    
1266
#ifdef ENABLE_DEBUGGER_SUPPORT
1267
  Debugger* debugger_;
1268
  Debug* debug_;
1269
#endif
1270

    
1271
#define GLOBAL_BACKING_STORE(type, name, initialvalue)                         \
1272
  type name##_;
1273
  ISOLATE_INIT_LIST(GLOBAL_BACKING_STORE)
1274
#undef GLOBAL_BACKING_STORE
1275

    
1276
#define GLOBAL_ARRAY_BACKING_STORE(type, name, length)                         \
1277
  type name##_[length];
1278
  ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_BACKING_STORE)
1279
#undef GLOBAL_ARRAY_BACKING_STORE
1280

    
1281
#ifdef DEBUG
1282
  // This class is huge and has a number of fields controlled by
1283
  // preprocessor defines. Make sure the offsets of these fields agree
1284
  // between compilation units.
1285
#define ISOLATE_FIELD_OFFSET(type, name, ignored)                              \
1286
  static const intptr_t name##_debug_offset_;
1287
  ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
1288
  ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
1289
#undef ISOLATE_FIELD_OFFSET
1290
#endif
1291

    
1292
  DeferredHandles* deferred_handles_head_;
1293
  OptimizingCompilerThread optimizing_compiler_thread_;
1294

    
1295
  friend class ExecutionAccess;
1296
  friend class HandleScopeImplementer;
1297
  friend class IsolateInitializer;
1298
  friend class OptimizingCompilerThread;
1299
  friend class ThreadManager;
1300
  friend class Simulator;
1301
  friend class StackGuard;
1302
  friend class ThreadId;
1303
  friend class TestMemoryAllocatorScope;
1304
  friend class v8::Isolate;
1305
  friend class v8::Locker;
1306
  friend class v8::Unlocker;
1307

    
1308
  DISALLOW_COPY_AND_ASSIGN(Isolate);
1309
};
1310

    
1311

    
1312
// If the GCC version is 4.1.x or 4.2.x an additional field is added to the
1313
// class as a work around for a bug in the generated code found with these
1314
// versions of GCC. See V8 issue 122 for details.
1315
class SaveContext BASE_EMBEDDED {
1316
 public:
1317
  inline explicit SaveContext(Isolate* isolate);
1318

    
1319
  ~SaveContext() {
1320
    if (context_.is_null()) {
1321
      Isolate* isolate = Isolate::Current();
1322
      isolate->set_context(NULL);
1323
      isolate->set_save_context(prev_);
1324
    } else {
1325
      Isolate* isolate = context_->GetIsolate();
1326
      isolate->set_context(*context_);
1327
      isolate->set_save_context(prev_);
1328
    }
1329
  }
1330

    
1331
  Handle<Context> context() { return context_; }
1332
  SaveContext* prev() { return prev_; }
1333

    
1334
  // Returns true if this save context is below a given JavaScript frame.
1335
  bool IsBelowFrame(JavaScriptFrame* frame) {
1336
    return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp());
1337
  }
1338

    
1339
 private:
1340
  Handle<Context> context_;
1341
#if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
1342
  Handle<Context> dummy_;
1343
#endif
1344
  SaveContext* prev_;
1345
  Address c_entry_fp_;
1346
};
1347

    
1348

    
1349
class AssertNoContextChange BASE_EMBEDDED {
1350
#ifdef DEBUG
1351
 public:
1352
  AssertNoContextChange() :
1353
      scope_(Isolate::Current()),
1354
      context_(Isolate::Current()->context(), Isolate::Current()) {
1355
  }
1356

    
1357
  ~AssertNoContextChange() {
1358
    ASSERT(Isolate::Current()->context() == *context_);
1359
  }
1360

    
1361
 private:
1362
  HandleScope scope_;
1363
  Handle<Context> context_;
1364
#else
1365
 public:
1366
  AssertNoContextChange() { }
1367
#endif
1368
};
1369

    
1370

    
1371
class ExecutionAccess BASE_EMBEDDED {
1372
 public:
1373
  explicit ExecutionAccess(Isolate* isolate) : isolate_(isolate) {
1374
    Lock(isolate);
1375
  }
1376
  ~ExecutionAccess() { Unlock(isolate_); }
1377

    
1378
  static void Lock(Isolate* isolate) { isolate->break_access_->Lock(); }
1379
  static void Unlock(Isolate* isolate) { isolate->break_access_->Unlock(); }
1380

    
1381
  static bool TryLock(Isolate* isolate) {
1382
    return isolate->break_access_->TryLock();
1383
  }
1384

    
1385
 private:
1386
  Isolate* isolate_;
1387
};
1388

    
1389

    
1390
// Support for checking for stack-overflows in C++ code.
1391
class StackLimitCheck BASE_EMBEDDED {
1392
 public:
1393
  explicit StackLimitCheck(Isolate* isolate) : isolate_(isolate) { }
1394

    
1395
  inline bool HasOverflowed() const {
1396
    StackGuard* stack_guard = isolate_->stack_guard();
1397
    return reinterpret_cast<uintptr_t>(this) < stack_guard->real_climit();
1398
  }
1399
 private:
1400
  Isolate* isolate_;
1401
};
1402

    
1403

    
1404
// Support for temporarily postponing interrupts. When the outermost
1405
// postpone scope is left the interrupts will be re-enabled and any
1406
// interrupts that occurred while in the scope will be taken into
1407
// account.
1408
class PostponeInterruptsScope BASE_EMBEDDED {
1409
 public:
1410
  explicit PostponeInterruptsScope(Isolate* isolate)
1411
      : stack_guard_(isolate->stack_guard()) {
1412
    stack_guard_->thread_local_.postpone_interrupts_nesting_++;
1413
    stack_guard_->DisableInterrupts();
1414
  }
1415

    
1416
  ~PostponeInterruptsScope() {
1417
    if (--stack_guard_->thread_local_.postpone_interrupts_nesting_ == 0) {
1418
      stack_guard_->EnableInterrupts();
1419
    }
1420
  }
1421
 private:
1422
  StackGuard* stack_guard_;
1423
};
1424

    
1425

    
1426
// Temporary macros for accessing current isolate and its subobjects.
1427
// They provide better readability, especially when used a lot in the code.
1428
#define HEAP (v8::internal::Isolate::Current()->heap())
1429
#define FACTORY (v8::internal::Isolate::Current()->factory())
1430
#define ISOLATE (v8::internal::Isolate::Current())
1431
#define LOGGER (v8::internal::Isolate::Current()->logger())
1432

    
1433

    
1434
// Tells whether the native context is marked with out of memory.
1435
inline bool Context::has_out_of_memory() {
1436
  return native_context()->out_of_memory()->IsTrue();
1437
}
1438

    
1439

    
1440
// Mark the native context with out of memory.
1441
inline void Context::mark_out_of_memory() {
1442
  native_context()->set_out_of_memory(HEAP->true_value());
1443
}
1444

    
1445

    
1446
} }  // namespace v8::internal
1447

    
1448
#endif  // V8_ISOLATE_H_