blob: 03a4866f4572febf0dde2af6194257bb609a94a5 [file] [log] [blame]
Steve Block44f0eee2011-05-26 01:26:41 +01001// Copyright 2010 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 "global-handles.h"
40#include "handles.h"
41#include "heap.h"
42#include "regexp-stack.h"
43#include "runtime-profiler.h"
44#include "runtime.h"
45#include "zone.h"
46
47namespace v8 {
48namespace internal {
49
50class AstSentinels;
51class Bootstrapper;
52class CodeGenerator;
53class CodeRange;
54class CompilationCache;
55class ContextSlotCache;
56class ContextSwitcher;
57class Counters;
58class CpuFeatures;
59class CpuProfiler;
60class DeoptimizerData;
61class Deserializer;
62class EmptyStatement;
63class ExternalReferenceTable;
64class Factory;
65class FunctionInfoListener;
66class HandleScopeImplementer;
67class HeapProfiler;
68class InlineRuntimeFunctionsTable;
69class NoAllocationStringAllocator;
70class PcToCodeCache;
71class PreallocatedMemoryThread;
72class ProducerHeapProfile;
73class RegExpStack;
74class SaveContext;
75class ScannerConstants;
76class StringInputBuffer;
77class StringTracker;
78class StubCache;
79class ThreadManager;
80class ThreadState;
81class ThreadVisitor; // Defined in v8threads.h
82class VMState;
83
84// 'void function pointer', used to roundtrip the
85// ExternalReference::ExternalReferenceRedirector since we can not include
86// assembler.h, where it is defined, here.
87typedef void* ExternalReferenceRedirectorPointer();
88
89
90#ifdef ENABLE_DEBUGGER_SUPPORT
91class Debug;
92class Debugger;
93class DebuggerAgent;
94#endif
95
96#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
97 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
98class Redirection;
99class Simulator;
100#endif
101
102
103// Static indirection table for handles to constants. If a frame
104// element represents a constant, the data contains an index into
105// this table of handles to the actual constants.
106// Static indirection table for handles to constants. If a Result
107// represents a constant, the data contains an index into this table
108// of handles to the actual constants.
109typedef ZoneList<Handle<Object> > ZoneObjectList;
110
111#define RETURN_IF_SCHEDULED_EXCEPTION(isolate) \
112 if (isolate->has_scheduled_exception()) \
113 return isolate->PromoteScheduledException()
114
115#define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value) \
116 if (call.is_null()) { \
117 ASSERT(isolate->has_pending_exception()); \
118 return value; \
119 }
120
121#define RETURN_IF_EMPTY_HANDLE(isolate, call) \
122 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception())
123
124#define ISOLATE_ADDRESS_LIST(C) \
125 C(handler_address) \
126 C(c_entry_fp_address) \
127 C(context_address) \
128 C(pending_exception_address) \
129 C(external_caught_exception_address)
130
131#ifdef ENABLE_LOGGING_AND_PROFILING
132#define ISOLATE_ADDRESS_LIST_PROF(C) \
133 C(js_entry_sp_address)
134#else
135#define ISOLATE_ADDRESS_LIST_PROF(C)
136#endif
137
138
139class ThreadLocalTop BASE_EMBEDDED {
140 public:
141 // Initialize the thread data.
142 void Initialize();
143
144 // Get the top C++ try catch handler or NULL if none are registered.
145 //
146 // This method is not guarenteed to return an address that can be
147 // used for comparison with addresses into the JS stack. If such an
148 // address is needed, use try_catch_handler_address.
149 v8::TryCatch* TryCatchHandler();
150
151 // Get the address of the top C++ try catch handler or NULL if
152 // none are registered.
153 //
154 // This method always returns an address that can be compared to
155 // pointers into the JavaScript stack. When running on actual
156 // hardware, try_catch_handler_address and TryCatchHandler return
157 // the same pointer. When running on a simulator with a separate JS
158 // stack, try_catch_handler_address returns a JS stack address that
159 // corresponds to the place on the JS stack where the C++ handler
160 // would have been if the stack were not separate.
161 inline Address try_catch_handler_address() {
162 return try_catch_handler_address_;
163 }
164
165 // Set the address of the top C++ try catch handler.
166 inline void set_try_catch_handler_address(Address address) {
167 try_catch_handler_address_ = address;
168 }
169
170 void Free() {
171 ASSERT(!has_pending_message_);
172 ASSERT(!external_caught_exception_);
173 ASSERT(try_catch_handler_address_ == NULL);
174 }
175
176 // The context where the current execution method is created and for variable
177 // lookups.
178 Context* context_;
179 int thread_id_;
180 MaybeObject* pending_exception_;
181 bool has_pending_message_;
182 const char* pending_message_;
183 Object* pending_message_obj_;
184 Script* pending_message_script_;
185 int pending_message_start_pos_;
186 int pending_message_end_pos_;
187 // Use a separate value for scheduled exceptions to preserve the
188 // invariants that hold about pending_exception. We may want to
189 // unify them later.
190 MaybeObject* scheduled_exception_;
191 bool external_caught_exception_;
192 SaveContext* save_context_;
193 v8::TryCatch* catcher_;
194
195 // Stack.
196 Address c_entry_fp_; // the frame pointer of the top c entry frame
197 Address handler_; // try-blocks are chained through the stack
198
199#ifdef USE_SIMULATOR
200#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
201 Simulator* simulator_;
202#endif
203#endif // USE_SIMULATOR
204
205#ifdef ENABLE_LOGGING_AND_PROFILING
206 Address js_entry_sp_; // the stack pointer of the bottom js entry frame
207 Address external_callback_; // the external callback we're currently in
208#endif
209
210#ifdef ENABLE_VMSTATE_TRACKING
211 StateTag current_vm_state_;
212#endif
213
214 // Generated code scratch locations.
215 int32_t formal_count_;
216
217 // Call back function to report unsafe JS accesses.
218 v8::FailedAccessCheckCallback failed_access_check_callback_;
219
220 private:
221 Address try_catch_handler_address_;
222};
223
224#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
225
226#define ISOLATE_PLATFORM_INIT_LIST(V) \
227 /* VirtualFrame::SpilledScope state */ \
228 V(bool, is_virtual_frame_in_spilled_scope, false) \
229 /* CodeGenerator::EmitNamedStore state */ \
230 V(int, inlined_write_barrier_size, -1)
231
232#if !defined(__arm__) && !defined(__mips__)
233class HashMap;
234#endif
235
236#else
237
238#define ISOLATE_PLATFORM_INIT_LIST(V)
239
240#endif
241
242#ifdef ENABLE_DEBUGGER_SUPPORT
243
244#define ISOLATE_DEBUGGER_INIT_LIST(V) \
245 V(v8::Debug::EventCallback, debug_event_callback, NULL) \
246 V(DebuggerAgent*, debugger_agent_instance, NULL)
247#else
248
249#define ISOLATE_DEBUGGER_INIT_LIST(V)
250
251#endif
252
253#ifdef DEBUG
254
255#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V) \
256 V(CommentStatistic, paged_space_comments_statistics, \
257 CommentStatistic::kMaxComments + 1)
258#else
259
260#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
261
262#endif
263
264#ifdef ENABLE_LOGGING_AND_PROFILING
265
266#define ISOLATE_LOGGING_INIT_LIST(V) \
267 V(CpuProfiler*, cpu_profiler, NULL) \
268 V(HeapProfiler*, heap_profiler, NULL)
269
270#else
271
272#define ISOLATE_LOGGING_INIT_LIST(V)
273
274#endif
275
276#define ISOLATE_INIT_ARRAY_LIST(V) \
277 /* SerializerDeserializer state. */ \
278 V(Object*, serialize_partial_snapshot_cache, kPartialSnapshotCacheCapacity) \
279 V(int, jsregexp_static_offsets_vector, kJSRegexpStaticOffsetsVectorSize) \
280 V(int, bad_char_shift_table, kUC16AlphabetSize) \
281 V(int, good_suffix_shift_table, (kBMMaxShift + 1)) \
282 V(int, suffix_table, (kBMMaxShift + 1)) \
283 ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
284
285typedef List<HeapObject*, PreallocatedStorage> DebugObjectCache;
286
287#define ISOLATE_INIT_LIST(V) \
288 /* AssertNoZoneAllocation state. */ \
289 V(bool, zone_allow_allocation, true) \
290 /* SerializerDeserializer state. */ \
291 V(int, serialize_partial_snapshot_cache_length, 0) \
292 /* Assembler state. */ \
293 /* A previously allocated buffer of kMinimalBufferSize bytes, or NULL. */ \
294 V(byte*, assembler_spare_buffer, NULL) \
295 V(FatalErrorCallback, exception_behavior, NULL) \
296 V(v8::Debug::MessageHandler, message_handler, NULL) \
297 /* To distinguish the function templates, so that we can find them in the */ \
298 /* function cache of the global context. */ \
299 V(int, next_serial_number, 0) \
300 V(ExternalReferenceRedirectorPointer*, external_reference_redirector, NULL) \
301 V(bool, always_allow_natives_syntax, false) \
302 /* Part of the state of liveedit. */ \
303 V(FunctionInfoListener*, active_function_info_listener, NULL) \
304 /* State for Relocatable. */ \
305 V(Relocatable*, relocatable_top, NULL) \
306 /* State for CodeEntry in profile-generator. */ \
307 V(CodeGenerator*, current_code_generator, NULL) \
308 V(bool, jump_target_compiling_deferred_code, false) \
309 V(DebugObjectCache*, string_stream_debug_object_cache, NULL) \
310 V(Object*, string_stream_current_security_token, NULL) \
311 /* TODO(isolates): Release this on destruction? */ \
312 V(int*, irregexp_interpreter_backtrack_stack_cache, NULL) \
313 /* Serializer state. */ \
314 V(ExternalReferenceTable*, external_reference_table, NULL) \
315 /* AstNode state. */ \
316 V(unsigned, ast_node_id, 0) \
317 V(unsigned, ast_node_count, 0) \
318 ISOLATE_PLATFORM_INIT_LIST(V) \
319 ISOLATE_LOGGING_INIT_LIST(V) \
320 ISOLATE_DEBUGGER_INIT_LIST(V)
321
322class Isolate {
323 // These forward declarations are required to make the friend declarations in
324 // PerIsolateThreadData work on some older versions of gcc.
325 class ThreadDataTable;
326 class EntryStackItem;
327 public:
328 ~Isolate();
329
330 typedef int ThreadId;
331
332 // A thread has a PerIsolateThreadData instance for each isolate that it has
333 // entered. That instance is allocated when the isolate is initially entered
334 // and reused on subsequent entries.
335 class PerIsolateThreadData {
336 public:
337 PerIsolateThreadData(Isolate* isolate, ThreadId thread_id)
338 : isolate_(isolate),
339 thread_id_(thread_id),
340 stack_limit_(0),
341 thread_state_(NULL),
342#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
343 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
344 simulator_(NULL),
345#endif
346 next_(NULL),
347 prev_(NULL) { }
348 Isolate* isolate() const { return isolate_; }
349 ThreadId thread_id() const { return thread_id_; }
350 void set_stack_limit(uintptr_t value) { stack_limit_ = value; }
351 uintptr_t stack_limit() const { return stack_limit_; }
352 ThreadState* thread_state() const { return thread_state_; }
353 void set_thread_state(ThreadState* value) { thread_state_ = value; }
354
355#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
356 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
357 Simulator* simulator() const { return simulator_; }
358 void set_simulator(Simulator* simulator) {
359 simulator_ = simulator;
360 }
361#endif
362
363 bool Matches(Isolate* isolate, ThreadId thread_id) const {
364 return isolate_ == isolate && thread_id_ == thread_id;
365 }
366
367 private:
368 Isolate* isolate_;
369 ThreadId thread_id_;
370 uintptr_t stack_limit_;
371 ThreadState* thread_state_;
372
373#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
374 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
375 Simulator* simulator_;
376#endif
377
378 PerIsolateThreadData* next_;
379 PerIsolateThreadData* prev_;
380
381 friend class Isolate;
382 friend class ThreadDataTable;
383 friend class EntryStackItem;
384
385 DISALLOW_COPY_AND_ASSIGN(PerIsolateThreadData);
386 };
387
388
389 enum AddressId {
390#define C(name) k_##name,
391 ISOLATE_ADDRESS_LIST(C)
392 ISOLATE_ADDRESS_LIST_PROF(C)
393#undef C
394 k_isolate_address_count
395 };
396
397 // Returns the PerIsolateThreadData for the current thread (or NULL if one is
398 // not currently set).
399 static PerIsolateThreadData* CurrentPerIsolateThreadData() {
400 return reinterpret_cast<PerIsolateThreadData*>(
401 Thread::GetThreadLocal(per_isolate_thread_data_key_));
402 }
403
404 // Returns the isolate inside which the current thread is running.
405 INLINE(static Isolate* Current()) {
406 Isolate* isolate = reinterpret_cast<Isolate*>(
407 Thread::GetExistingThreadLocal(isolate_key_));
408 ASSERT(isolate != NULL);
409 return isolate;
410 }
411
412 INLINE(static Isolate* UncheckedCurrent()) {
413 return reinterpret_cast<Isolate*>(Thread::GetThreadLocal(isolate_key_));
414 }
415
416 bool Init(Deserializer* des);
417
418 bool IsInitialized() { return state_ == INITIALIZED; }
419
420 // True if at least one thread Enter'ed this isolate.
421 bool IsInUse() { return entry_stack_ != NULL; }
422
423 // Destroys the non-default isolates.
424 // Sets default isolate into "has_been_disposed" state rather then destroying,
425 // for legacy API reasons.
426 void TearDown();
427
428 bool IsDefaultIsolate() const { return this == default_isolate_; }
429
430 // Ensures that process-wide resources and the default isolate have been
431 // allocated. It is only necessary to call this method in rare casses, for
432 // example if you are using V8 from within the body of a static initializer.
433 // Safe to call multiple times.
434 static void EnsureDefaultIsolate();
435
436 // Get the debugger from the default isolate. Preinitializes the
437 // default isolate if needed.
438 static Debugger* GetDefaultIsolateDebugger();
439
440 // Get the stack guard from the default isolate. Preinitializes the
441 // default isolate if needed.
442 static StackGuard* GetDefaultIsolateStackGuard();
443
444 // Returns the key used to store the pointer to the current isolate.
445 // Used internally for V8 threads that do not execute JavaScript but still
446 // are part of the domain of an isolate (like the context switcher).
447 static Thread::LocalStorageKey isolate_key() {
448 return isolate_key_;
449 }
450
451 // Returns the key used to store process-wide thread IDs.
452 static Thread::LocalStorageKey thread_id_key() {
453 return thread_id_key_;
454 }
455
456 // Atomically allocates a new thread ID.
457 static ThreadId AllocateThreadId();
458
459 // If a client attempts to create a Locker without specifying an isolate,
460 // we assume that the client is using legacy behavior. Set up the current
461 // thread to be inside the implicit isolate (or fail a check if we have
462 // switched to non-legacy behavior).
463 static void EnterDefaultIsolate();
464
465 // Debug.
466 // Mutex for serializing access to break control structures.
467 Mutex* break_access() { return break_access_; }
468
469 Address get_address_from_id(AddressId id);
470
471 // Access to top context (where the current function object was created).
472 Context* context() { return thread_local_top_.context_; }
473 void set_context(Context* context) {
474 thread_local_top_.context_ = context;
475 }
476 Context** context_address() { return &thread_local_top_.context_; }
477
478 SaveContext* save_context() {return thread_local_top_.save_context_; }
479 void set_save_context(SaveContext* save) {
480 thread_local_top_.save_context_ = save;
481 }
482
483 // Access to current thread id.
484 int thread_id() { return thread_local_top_.thread_id_; }
485 void set_thread_id(int id) { thread_local_top_.thread_id_ = id; }
486
487 // Interface to pending exception.
488 MaybeObject* pending_exception() {
489 ASSERT(has_pending_exception());
490 return thread_local_top_.pending_exception_;
491 }
492 bool external_caught_exception() {
493 return thread_local_top_.external_caught_exception_;
494 }
495 void set_pending_exception(MaybeObject* exception) {
496 thread_local_top_.pending_exception_ = exception;
497 }
498 void clear_pending_exception() {
499 thread_local_top_.pending_exception_ = heap_.the_hole_value();
500 }
501 MaybeObject** pending_exception_address() {
502 return &thread_local_top_.pending_exception_;
503 }
504 bool has_pending_exception() {
505 return !thread_local_top_.pending_exception_->IsTheHole();
506 }
507 void clear_pending_message() {
508 thread_local_top_.has_pending_message_ = false;
509 thread_local_top_.pending_message_ = NULL;
510 thread_local_top_.pending_message_obj_ = heap_.the_hole_value();
511 thread_local_top_.pending_message_script_ = NULL;
512 }
513 v8::TryCatch* try_catch_handler() {
514 return thread_local_top_.TryCatchHandler();
515 }
516 Address try_catch_handler_address() {
517 return thread_local_top_.try_catch_handler_address();
518 }
519 bool* external_caught_exception_address() {
520 return &thread_local_top_.external_caught_exception_;
521 }
522
523 MaybeObject** scheduled_exception_address() {
524 return &thread_local_top_.scheduled_exception_;
525 }
526 MaybeObject* scheduled_exception() {
527 ASSERT(has_scheduled_exception());
528 return thread_local_top_.scheduled_exception_;
529 }
530 bool has_scheduled_exception() {
531 return !thread_local_top_.scheduled_exception_->IsTheHole();
532 }
533 void clear_scheduled_exception() {
534 thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
535 }
536
537 bool IsExternallyCaught();
538
539 bool is_catchable_by_javascript(MaybeObject* exception) {
540 return (exception != Failure::OutOfMemoryException()) &&
541 (exception != heap()->termination_exception());
542 }
543
544 // JS execution stack (see frames.h).
545 static Address c_entry_fp(ThreadLocalTop* thread) {
546 return thread->c_entry_fp_;
547 }
548 static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
549
550 inline Address* c_entry_fp_address() {
551 return &thread_local_top_.c_entry_fp_;
552 }
553 inline Address* handler_address() { return &thread_local_top_.handler_; }
554
555#ifdef ENABLE_LOGGING_AND_PROFILING
556 // Bottom JS entry (see StackTracer::Trace in log.cc).
557 static Address js_entry_sp(ThreadLocalTop* thread) {
558 return thread->js_entry_sp_;
559 }
560 inline Address* js_entry_sp_address() {
561 return &thread_local_top_.js_entry_sp_;
562 }
563#endif
564
565 // Generated code scratch locations.
566 void* formal_count_address() { return &thread_local_top_.formal_count_; }
567
568 // Returns the global object of the current context. It could be
569 // a builtin object, or a js global object.
570 Handle<GlobalObject> global() {
571 return Handle<GlobalObject>(context()->global());
572 }
573
574 // Returns the global proxy object of the current context.
575 Object* global_proxy() {
576 return context()->global_proxy();
577 }
578
579 Handle<JSBuiltinsObject> js_builtins_object() {
580 return Handle<JSBuiltinsObject>(thread_local_top_.context_->builtins());
581 }
582
583 static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
584 void FreeThreadResources() { thread_local_top_.Free(); }
585
586 // This method is called by the api after operations that may throw
587 // exceptions. If an exception was thrown and not handled by an external
588 // handler the exception is scheduled to be rethrown when we return to running
589 // JavaScript code. If an exception is scheduled true is returned.
590 bool OptionalRescheduleException(bool is_bottom_call);
591
592 void SetCaptureStackTraceForUncaughtExceptions(
593 bool capture,
594 int frame_limit,
595 StackTrace::StackTraceOptions options);
596
597 // Tells whether the current context has experienced an out of memory
598 // exception.
599 bool is_out_of_memory();
600
601 void PrintCurrentStackTrace(FILE* out);
602 void PrintStackTrace(FILE* out, char* thread_data);
603 void PrintStack(StringStream* accumulator);
604 void PrintStack();
605 Handle<String> StackTraceString();
606 Handle<JSArray> CaptureCurrentStackTrace(
607 int frame_limit,
608 StackTrace::StackTraceOptions options);
609
610 // Returns if the top context may access the given global object. If
611 // the result is false, the pending exception is guaranteed to be
612 // set.
613 bool MayNamedAccess(JSObject* receiver,
614 Object* key,
615 v8::AccessType type);
616 bool MayIndexedAccess(JSObject* receiver,
617 uint32_t index,
618 v8::AccessType type);
619
620 void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
621 void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
622
623 // Exception throwing support. The caller should use the result
624 // of Throw() as its return value.
625 Failure* Throw(Object* exception, MessageLocation* location = NULL);
626 // Re-throw an exception. This involves no error reporting since
627 // error reporting was handled when the exception was thrown
628 // originally.
629 Failure* ReThrow(MaybeObject* exception, MessageLocation* location = NULL);
630 void ScheduleThrow(Object* exception);
631 void ReportPendingMessages();
632 Failure* ThrowIllegalOperation();
633
634 // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
635 Failure* PromoteScheduledException();
636 void DoThrow(MaybeObject* exception,
637 MessageLocation* location,
638 const char* message);
639 // Checks if exception should be reported and finds out if it's
640 // caught externally.
641 bool ShouldReportException(bool* can_be_caught_externally,
642 bool catchable_by_javascript);
643
644 // Attempts to compute the current source location, storing the
645 // result in the target out parameter.
646 void ComputeLocation(MessageLocation* target);
647
648 // Override command line flag.
649 void TraceException(bool flag);
650
651 // Out of resource exception helpers.
652 Failure* StackOverflow();
653 Failure* TerminateExecution();
654
655 // Administration
656 void Iterate(ObjectVisitor* v);
657 void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
658 char* Iterate(ObjectVisitor* v, char* t);
659 void IterateThread(ThreadVisitor* v);
660 void IterateThread(ThreadVisitor* v, char* t);
661
662
663 // Returns the current global context.
664 Handle<Context> global_context();
665
666 // Returns the global context of the calling JavaScript code. That
667 // is, the global context of the top-most JavaScript frame.
668 Handle<Context> GetCallingGlobalContext();
669
670 void RegisterTryCatchHandler(v8::TryCatch* that);
671 void UnregisterTryCatchHandler(v8::TryCatch* that);
672
673 char* ArchiveThread(char* to);
674 char* RestoreThread(char* from);
675
676 static const char* const kStackOverflowMessage;
677
678 static const int kUC16AlphabetSize = 256; // See StringSearchBase.
679 static const int kBMMaxShift = 250; // See StringSearchBase.
680
681 // Accessors.
682#define GLOBAL_ACCESSOR(type, name, initialvalue) \
683 inline type name() const { \
684 ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \
685 return name##_; \
686 } \
687 inline void set_##name(type value) { \
688 ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \
689 name##_ = value; \
690 }
691 ISOLATE_INIT_LIST(GLOBAL_ACCESSOR)
692#undef GLOBAL_ACCESSOR
693
694#define GLOBAL_ARRAY_ACCESSOR(type, name, length) \
695 inline type* name() { \
696 ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \
697 return &(name##_)[0]; \
698 }
699 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR)
700#undef GLOBAL_ARRAY_ACCESSOR
701
702#define GLOBAL_CONTEXT_FIELD_ACCESSOR(index, type, name) \
703 Handle<type> name() { \
704 return Handle<type>(context()->global_context()->name()); \
705 }
706 GLOBAL_CONTEXT_FIELDS(GLOBAL_CONTEXT_FIELD_ACCESSOR)
707#undef GLOBAL_CONTEXT_FIELD_ACCESSOR
708
709 Bootstrapper* bootstrapper() { return bootstrapper_; }
710 Counters* counters() { return counters_; }
711 // TODO(isolates): Having CPU features per isolate is probably too
712 // flexible. We only really need to have the set of currently
713 // enabled features for asserts in DEBUG builds.
714 CpuFeatures* cpu_features() { return cpu_features_; }
715 CodeRange* code_range() { return code_range_; }
716 RuntimeProfiler* runtime_profiler() { return runtime_profiler_; }
717 CompilationCache* compilation_cache() { return compilation_cache_; }
718 Logger* logger() { return logger_; }
719 StackGuard* stack_guard() { return &stack_guard_; }
720 Heap* heap() { return &heap_; }
721 StatsTable* stats_table() { return stats_table_; }
722 StubCache* stub_cache() { return stub_cache_; }
723 DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
724 ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
725
726 TranscendentalCache* transcendental_cache() const {
727 return transcendental_cache_;
728 }
729
730 MemoryAllocator* memory_allocator() {
731 return memory_allocator_;
732 }
733
734 KeyedLookupCache* keyed_lookup_cache() {
735 return keyed_lookup_cache_;
736 }
737
738 ContextSlotCache* context_slot_cache() {
739 return context_slot_cache_;
740 }
741
742 DescriptorLookupCache* descriptor_lookup_cache() {
743 return descriptor_lookup_cache_;
744 }
745
746 v8::ImplementationUtilities::HandleScopeData* handle_scope_data() {
747 return &handle_scope_data_;
748 }
749 HandleScopeImplementer* handle_scope_implementer() {
750 ASSERT(handle_scope_implementer_);
751 return handle_scope_implementer_;
752 }
753 Zone* zone() { return &zone_; }
754
755 ScannerConstants* scanner_constants() {
756 return scanner_constants_;
757 }
758
759 PcToCodeCache* pc_to_code_cache() { return pc_to_code_cache_; }
760
761 StringInputBuffer* write_input_buffer() { return write_input_buffer_; }
762
763 GlobalHandles* global_handles() { return global_handles_; }
764
765 ThreadManager* thread_manager() { return thread_manager_; }
766
767 ContextSwitcher* context_switcher() { return context_switcher_; }
768
769 void set_context_switcher(ContextSwitcher* switcher) {
770 context_switcher_ = switcher;
771 }
772
773 StringTracker* string_tracker() { return string_tracker_; }
774
775 unibrow::Mapping<unibrow::Ecma262UnCanonicalize>* jsregexp_uncanonicalize() {
776 return &jsregexp_uncanonicalize_;
777 }
778
779 unibrow::Mapping<unibrow::CanonicalizationRange>* jsregexp_canonrange() {
780 return &jsregexp_canonrange_;
781 }
782
783 StringInputBuffer* objects_string_compare_buffer_a() {
784 return &objects_string_compare_buffer_a_;
785 }
786
787 StringInputBuffer* objects_string_compare_buffer_b() {
788 return &objects_string_compare_buffer_b_;
789 }
790
791 StaticResource<StringInputBuffer>* objects_string_input_buffer() {
792 return &objects_string_input_buffer_;
793 }
794
795 AstSentinels* ast_sentinels() { return ast_sentinels_; }
796
797 RuntimeState* runtime_state() { return &runtime_state_; }
798
799 StringInputBuffer* liveedit_compare_substrings_buf1() {
800 return &liveedit_compare_substrings_buf1_;
801 }
802
803 StringInputBuffer* liveedit_compare_substrings_buf2() {
804 return &liveedit_compare_substrings_buf2_;
805 }
806
807 StaticResource<SafeStringInputBuffer>* compiler_safe_string_input_buffer() {
808 return &compiler_safe_string_input_buffer_;
809 }
810
811 Builtins* builtins() { return &builtins_; }
812
813 unibrow::Mapping<unibrow::Ecma262Canonicalize>*
814 regexp_macro_assembler_canonicalize() {
815 return &regexp_macro_assembler_canonicalize_;
816 }
817
818 RegExpStack* regexp_stack() { return regexp_stack_; }
819
820 unibrow::Mapping<unibrow::Ecma262Canonicalize>*
821 interp_canonicalize_mapping() {
822 return &interp_canonicalize_mapping_;
823 }
824
825 ZoneObjectList* frame_element_constant_list() {
826 return &frame_element_constant_list_;
827 }
828
829 ZoneObjectList* result_constant_list() {
830 return &result_constant_list_;
831 }
832
833 void* PreallocatedStorageNew(size_t size);
834 void PreallocatedStorageDelete(void* p);
835 void PreallocatedStorageInit(size_t size);
836
837#ifdef ENABLE_DEBUGGER_SUPPORT
838 Debugger* debugger() { return debugger_; }
839 Debug* debug() { return debug_; }
840#endif
841
842#ifdef ENABLE_LOGGING_AND_PROFILING
843 ProducerHeapProfile* producer_heap_profile() {
844 return producer_heap_profile_;
845 }
846#endif
847
848#ifdef DEBUG
849 HistogramInfo* heap_histograms() { return heap_histograms_; }
850
851 JSObject::SpillInformation* js_spill_information() {
852 return &js_spill_information_;
853 }
854
855 int* code_kind_statistics() { return code_kind_statistics_; }
856#endif
857
858#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
859 defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
860 bool simulator_initialized() { return simulator_initialized_; }
861 void set_simulator_initialized(bool initialized) {
862 simulator_initialized_ = initialized;
863 }
864
865 HashMap* simulator_i_cache() { return simulator_i_cache_; }
866 void set_simulator_i_cache(HashMap* hash_map) {
867 simulator_i_cache_ = hash_map;
868 }
869
870 Redirection* simulator_redirection() {
871 return simulator_redirection_;
872 }
873 void set_simulator_redirection(Redirection* redirection) {
874 simulator_redirection_ = redirection;
875 }
876#endif
877
878 Factory* factory() { return reinterpret_cast<Factory*>(this); }
879
880 // SerializerDeserializer state.
881 static const int kPartialSnapshotCacheCapacity = 1400;
882
883 static const int kJSRegexpStaticOffsetsVectorSize = 50;
884
885#ifdef ENABLE_LOGGING_AND_PROFILING
886 Address external_callback() {
887 return thread_local_top_.external_callback_;
888 }
889 void set_external_callback(Address callback) {
890 thread_local_top_.external_callback_ = callback;
891 }
892#endif
893
894#ifdef ENABLE_VMSTATE_TRACKING
895 StateTag current_vm_state() {
896 return thread_local_top_.current_vm_state_;
897 }
898
899 void SetCurrentVMState(StateTag state) {
900 if (RuntimeProfiler::IsEnabled()) {
901 if (state == JS) {
902 // JS or non-JS -> JS transition.
903 RuntimeProfiler::IsolateEnteredJS(this);
904 } else if (thread_local_top_.current_vm_state_ == JS) {
905 // JS -> non-JS transition.
906 ASSERT(RuntimeProfiler::IsSomeIsolateInJS());
907 RuntimeProfiler::IsolateExitedJS(this);
908 }
909 }
910 thread_local_top_.current_vm_state_ = state;
911 }
912#endif
913
914 void ResetEagerOptimizingData();
915
916 private:
917 Isolate();
918
919 // The per-process lock should be acquired before the ThreadDataTable is
920 // modified.
921 class ThreadDataTable {
922 public:
923 ThreadDataTable();
924 ~ThreadDataTable();
925
926 PerIsolateThreadData* Lookup(Isolate* isolate, ThreadId thread_id);
927 void Insert(PerIsolateThreadData* data);
928 void Remove(Isolate* isolate, ThreadId thread_id);
929 void Remove(PerIsolateThreadData* data);
930
931 private:
932 PerIsolateThreadData* list_;
933 };
934
935 // These items form a stack synchronously with threads Enter'ing and Exit'ing
936 // the Isolate. The top of the stack points to a thread which is currently
937 // running the Isolate. When the stack is empty, the Isolate is considered
938 // not entered by any thread and can be Disposed.
939 // If the same thread enters the Isolate more then once, the entry_count_
940 // is incremented rather then a new item pushed to the stack.
941 class EntryStackItem {
942 public:
943 EntryStackItem(PerIsolateThreadData* previous_thread_data,
944 Isolate* previous_isolate,
945 EntryStackItem* previous_item)
946 : entry_count(1),
947 previous_thread_data(previous_thread_data),
948 previous_isolate(previous_isolate),
949 previous_item(previous_item) { }
950
951 int entry_count;
952 PerIsolateThreadData* previous_thread_data;
953 Isolate* previous_isolate;
954 EntryStackItem* previous_item;
955
956 DISALLOW_COPY_AND_ASSIGN(EntryStackItem);
957 };
958
959 // This mutex protects highest_thread_id_, thread_data_table_ and
960 // default_isolate_.
961 static Mutex* process_wide_mutex_;
962
963 static Thread::LocalStorageKey per_isolate_thread_data_key_;
964 static Thread::LocalStorageKey isolate_key_;
965 static Thread::LocalStorageKey thread_id_key_;
966 static Isolate* default_isolate_;
967 static ThreadDataTable* thread_data_table_;
968 static ThreadId highest_thread_id_;
969
970 bool PreInit();
971
972 void Deinit();
973
974 static void SetIsolateThreadLocals(Isolate* isolate,
975 PerIsolateThreadData* data);
976
977 enum State {
978 UNINITIALIZED, // Some components may not have been allocated.
979 PREINITIALIZED, // Components have been allocated but not initialized.
980 INITIALIZED // All components are fully initialized.
981 };
982
983 State state_;
984 EntryStackItem* entry_stack_;
985
986 // Allocate and insert PerIsolateThreadData into the ThreadDataTable
987 // (regardless of whether such data already exists).
988 PerIsolateThreadData* AllocatePerIsolateThreadData(ThreadId thread_id);
989
990 // Find the PerThread for this particular (isolate, thread) combination.
991 // If one does not yet exist, allocate a new one.
992 PerIsolateThreadData* FindOrAllocatePerThreadDataForThisThread();
993
994 // PreInits and returns a default isolate. Needed when a new thread tries
995 // to create a Locker for the first time (the lock itself is in the isolate).
996 static Isolate* GetDefaultIsolateForLocking();
997
998 // Initializes the current thread to run this Isolate.
999 // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
1000 // at the same time, this should be prevented using external locking.
1001 void Enter();
1002
1003 // Exits the current thread. The previosuly entered Isolate is restored
1004 // for the thread.
1005 // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
1006 // at the same time, this should be prevented using external locking.
1007 void Exit();
1008
1009 void PreallocatedMemoryThreadStart();
1010 void PreallocatedMemoryThreadStop();
1011 void InitializeThreadLocal();
1012
1013 void PrintStackTrace(FILE* out, ThreadLocalTop* thread);
1014 void MarkCompactPrologue(bool is_compacting,
1015 ThreadLocalTop* archived_thread_data);
1016 void MarkCompactEpilogue(bool is_compacting,
1017 ThreadLocalTop* archived_thread_data);
1018
1019 void FillCache();
1020
1021 int stack_trace_nesting_level_;
1022 StringStream* incomplete_message_;
1023 // The preallocated memory thread singleton.
1024 PreallocatedMemoryThread* preallocated_memory_thread_;
1025 Address isolate_addresses_[k_isolate_address_count + 1]; // NOLINT
1026 NoAllocationStringAllocator* preallocated_message_space_;
1027
1028 Bootstrapper* bootstrapper_;
1029 RuntimeProfiler* runtime_profiler_;
1030 CompilationCache* compilation_cache_;
1031 Counters* counters_;
1032 CpuFeatures* cpu_features_;
1033 CodeRange* code_range_;
1034 Mutex* break_access_;
1035 Heap heap_;
1036 Logger* logger_;
1037 StackGuard stack_guard_;
1038 StatsTable* stats_table_;
1039 StubCache* stub_cache_;
1040 DeoptimizerData* deoptimizer_data_;
1041 ThreadLocalTop thread_local_top_;
1042 bool capture_stack_trace_for_uncaught_exceptions_;
1043 int stack_trace_for_uncaught_exceptions_frame_limit_;
1044 StackTrace::StackTraceOptions stack_trace_for_uncaught_exceptions_options_;
1045 TranscendentalCache* transcendental_cache_;
1046 MemoryAllocator* memory_allocator_;
1047 KeyedLookupCache* keyed_lookup_cache_;
1048 ContextSlotCache* context_slot_cache_;
1049 DescriptorLookupCache* descriptor_lookup_cache_;
1050 v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
1051 HandleScopeImplementer* handle_scope_implementer_;
1052 ScannerConstants* scanner_constants_;
1053 Zone zone_;
1054 PreallocatedStorage in_use_list_;
1055 PreallocatedStorage free_list_;
1056 bool preallocated_storage_preallocated_;
1057 PcToCodeCache* pc_to_code_cache_;
1058 StringInputBuffer* write_input_buffer_;
1059 GlobalHandles* global_handles_;
1060 ContextSwitcher* context_switcher_;
1061 ThreadManager* thread_manager_;
1062 AstSentinels* ast_sentinels_;
1063 RuntimeState runtime_state_;
1064 StringInputBuffer liveedit_compare_substrings_buf1_;
1065 StringInputBuffer liveedit_compare_substrings_buf2_;
1066 StaticResource<SafeStringInputBuffer> compiler_safe_string_input_buffer_;
1067 Builtins builtins_;
1068 StringTracker* string_tracker_;
1069 unibrow::Mapping<unibrow::Ecma262UnCanonicalize> jsregexp_uncanonicalize_;
1070 unibrow::Mapping<unibrow::CanonicalizationRange> jsregexp_canonrange_;
1071 StringInputBuffer objects_string_compare_buffer_a_;
1072 StringInputBuffer objects_string_compare_buffer_b_;
1073 StaticResource<StringInputBuffer> objects_string_input_buffer_;
1074 unibrow::Mapping<unibrow::Ecma262Canonicalize>
1075 regexp_macro_assembler_canonicalize_;
1076 RegExpStack* regexp_stack_;
1077 unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
1078 ZoneObjectList frame_element_constant_list_;
1079 ZoneObjectList result_constant_list_;
1080
1081#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
1082 defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
1083 bool simulator_initialized_;
1084 HashMap* simulator_i_cache_;
1085 Redirection* simulator_redirection_;
1086#endif
1087
1088#ifdef DEBUG
1089 // A static array of histogram info for each type.
1090 HistogramInfo heap_histograms_[LAST_TYPE + 1];
1091 JSObject::SpillInformation js_spill_information_;
1092 int code_kind_statistics_[Code::NUMBER_OF_KINDS];
1093#endif
1094
1095#ifdef ENABLE_DEBUGGER_SUPPORT
1096 Debugger* debugger_;
1097 Debug* debug_;
1098#endif
1099
1100#ifdef ENABLE_LOGGING_AND_PROFILING
1101 ProducerHeapProfile* producer_heap_profile_;
1102#endif
1103
1104#define GLOBAL_BACKING_STORE(type, name, initialvalue) \
1105 type name##_;
1106 ISOLATE_INIT_LIST(GLOBAL_BACKING_STORE)
1107#undef GLOBAL_BACKING_STORE
1108
1109#define GLOBAL_ARRAY_BACKING_STORE(type, name, length) \
1110 type name##_[length];
1111 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_BACKING_STORE)
1112#undef GLOBAL_ARRAY_BACKING_STORE
1113
1114#ifdef DEBUG
1115 // This class is huge and has a number of fields controlled by
1116 // preprocessor defines. Make sure the offsets of these fields agree
1117 // between compilation units.
1118#define ISOLATE_FIELD_OFFSET(type, name, ignored) \
1119 static const intptr_t name##_debug_offset_;
1120 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
1121 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
1122#undef ISOLATE_FIELD_OFFSET
1123#endif
1124
1125 friend class ExecutionAccess;
1126 friend class IsolateInitializer;
1127 friend class v8::Isolate;
1128 friend class v8::Locker;
1129
1130 DISALLOW_COPY_AND_ASSIGN(Isolate);
1131};
1132
1133
1134// If the GCC version is 4.1.x or 4.2.x an additional field is added to the
1135// class as a work around for a bug in the generated code found with these
1136// versions of GCC. See V8 issue 122 for details.
1137class SaveContext BASE_EMBEDDED {
1138 public:
1139 explicit SaveContext(Isolate* isolate) : prev_(isolate->save_context()) {
1140 if (isolate->context() != NULL) {
1141 context_ = Handle<Context>(isolate->context());
1142#if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
1143 dummy_ = Handle<Context>(isolate->context());
1144#endif
1145 }
1146 isolate->set_save_context(this);
1147
1148 // If there is no JS frame under the current C frame, use the value 0.
1149 JavaScriptFrameIterator it;
1150 js_sp_ = it.done() ? 0 : it.frame()->sp();
1151 }
1152
1153 ~SaveContext() {
1154 if (context_.is_null()) {
1155 Isolate* isolate = Isolate::Current();
1156 isolate->set_context(NULL);
1157 isolate->set_save_context(prev_);
1158 } else {
1159 Isolate* isolate = context_->GetIsolate();
1160 isolate->set_context(*context_);
1161 isolate->set_save_context(prev_);
1162 }
1163 }
1164
1165 Handle<Context> context() { return context_; }
1166 SaveContext* prev() { return prev_; }
1167
1168 // Returns true if this save context is below a given JavaScript frame.
1169 bool below(JavaScriptFrame* frame) {
1170 return (js_sp_ == 0) || (frame->sp() < js_sp_);
1171 }
1172
1173 private:
1174 Handle<Context> context_;
1175#if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
1176 Handle<Context> dummy_;
1177#endif
1178 SaveContext* prev_;
1179 Address js_sp_; // The top JS frame's sp when saving context.
1180};
1181
1182
1183class AssertNoContextChange BASE_EMBEDDED {
1184#ifdef DEBUG
1185 public:
1186 AssertNoContextChange() :
1187 scope_(Isolate::Current()),
1188 context_(Isolate::Current()->context(), Isolate::Current()) {
1189 }
1190
1191 ~AssertNoContextChange() {
1192 ASSERT(Isolate::Current()->context() == *context_);
1193 }
1194
1195 private:
1196 HandleScope scope_;
1197 Handle<Context> context_;
1198#else
1199 public:
1200 AssertNoContextChange() { }
1201#endif
1202};
1203
1204
1205class ExecutionAccess BASE_EMBEDDED {
1206 public:
1207 explicit ExecutionAccess(Isolate* isolate) : isolate_(isolate) {
1208 Lock(isolate);
1209 }
1210 ~ExecutionAccess() { Unlock(isolate_); }
1211
1212 static void Lock(Isolate* isolate) { isolate->break_access_->Lock(); }
1213 static void Unlock(Isolate* isolate) { isolate->break_access_->Unlock(); }
1214
1215 static bool TryLock(Isolate* isolate) {
1216 return isolate->break_access_->TryLock();
1217 }
1218
1219 private:
1220 Isolate* isolate_;
1221};
1222
1223
1224// Support for checking for stack-overflows in C++ code.
1225class StackLimitCheck BASE_EMBEDDED {
1226 public:
1227 explicit StackLimitCheck(Isolate* isolate) : isolate_(isolate) { }
1228
1229 bool HasOverflowed() const {
1230 StackGuard* stack_guard = isolate_->stack_guard();
1231 // Stack has overflowed in C++ code only if stack pointer exceeds the C++
1232 // stack guard and the limits are not set to interrupt values.
1233 // TODO(214): Stack overflows are ignored if a interrupt is pending. This
1234 // code should probably always use the initial C++ limit.
1235 return (reinterpret_cast<uintptr_t>(this) < stack_guard->climit()) &&
1236 stack_guard->IsStackOverflow();
1237 }
1238 private:
1239 Isolate* isolate_;
1240};
1241
1242
1243// Support for temporarily postponing interrupts. When the outermost
1244// postpone scope is left the interrupts will be re-enabled and any
1245// interrupts that occurred while in the scope will be taken into
1246// account.
1247class PostponeInterruptsScope BASE_EMBEDDED {
1248 public:
1249 explicit PostponeInterruptsScope(Isolate* isolate)
1250 : stack_guard_(isolate->stack_guard()) {
1251 stack_guard_->thread_local_.postpone_interrupts_nesting_++;
1252 stack_guard_->DisableInterrupts();
1253 }
1254
1255 ~PostponeInterruptsScope() {
1256 if (--stack_guard_->thread_local_.postpone_interrupts_nesting_ == 0) {
1257 stack_guard_->EnableInterrupts();
1258 }
1259 }
1260 private:
1261 StackGuard* stack_guard_;
1262};
1263
1264
1265// Temporary macros for accessing current isolate and its subobjects.
1266// They provide better readability, especially when used a lot in the code.
1267#define HEAP (v8::internal::Isolate::Current()->heap())
1268#define FACTORY (v8::internal::Isolate::Current()->factory())
1269#define ISOLATE (v8::internal::Isolate::Current())
1270#define ZONE (v8::internal::Isolate::Current()->zone())
1271#define LOGGER (v8::internal::Isolate::Current()->logger())
1272
1273
1274// Tells whether the global context is marked with out of memory.
1275inline bool Context::has_out_of_memory() {
1276 return global_context()->out_of_memory()->IsTrue();
1277}
1278
1279
1280// Mark the global context with out of memory.
1281inline void Context::mark_out_of_memory() {
1282 global_context()->set_out_of_memory(HEAP->true_value());
1283}
1284
1285
1286// Temporary macro to be used to flag definitions that are indeed static
1287// and not per-isolate. (It would be great to be able to grep for [static]!)
1288#define RLYSTC static
1289
1290
1291// Temporary macro to be used to flag classes that should be static.
1292#define STATIC_CLASS class
1293
1294
1295// Temporary macro to be used to flag classes that are completely converted
1296// to be isolate-friendly. Their mix of static/nonstatic methods/fields is
1297// correct.
1298#define ISOLATED_CLASS class
1299
1300} } // namespace v8::internal
1301
1302// TODO(isolates): Get rid of these -inl.h includes and place them only where
1303// they're needed.
1304#include "allocation-inl.h"
1305#include "zone-inl.h"
1306#include "frames-inl.h"
1307
1308#endif // V8_ISOLATE_H_