blob: df70ba9efd4b4198b7ee28b94da4b60287f5c1d3 [file] [log] [blame]
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00001// Copyright 2012 the V8 project authors. All rights reserved.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002// 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"
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +000039#include "date.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000040#include "global-handles.h"
41#include "handles.h"
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +000042#include "hashmap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "heap.h"
yangguo@chromium.org304cc332012-07-24 07:59:48 +000044#include "optimizing-compiler-thread.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000045#include "regexp-stack.h"
46#include "runtime-profiler.h"
47#include "runtime.h"
48#include "zone.h"
49
50namespace v8 {
51namespace internal {
52
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000053class Bootstrapper;
54class CodeGenerator;
55class CodeRange;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000056struct CodeStubInterfaceDescriptor;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000057class CompilationCache;
58class ContextSlotCache;
59class ContextSwitcher;
60class Counters;
61class CpuFeatures;
62class CpuProfiler;
63class DeoptimizerData;
64class Deserializer;
65class EmptyStatement;
66class ExternalReferenceTable;
67class Factory;
68class FunctionInfoListener;
69class HandleScopeImplementer;
70class HeapProfiler;
71class InlineRuntimeFunctionsTable;
72class NoAllocationStringAllocator;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000073class InnerPointerToCodeCache;
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +000074class MarkingThread;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000075class PreallocatedMemoryThread;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000076class RegExpStack;
77class SaveContext;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +000078class UnicodeCache;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +000079class ConsStringIteratorOp;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000080class StringTracker;
81class StubCache;
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +000082class SweeperThread;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000083class ThreadManager;
84class ThreadState;
85class ThreadVisitor; // Defined in v8threads.h
86class VMState;
87
88// 'void function pointer', used to roundtrip the
89// ExternalReference::ExternalReferenceRedirector since we can not include
90// assembler.h, where it is defined, here.
91typedef void* ExternalReferenceRedirectorPointer();
92
93
94#ifdef ENABLE_DEBUGGER_SUPPORT
95class Debug;
96class Debugger;
97class DebuggerAgent;
98#endif
99
lrn@chromium.org7516f052011-03-30 08:52:27 +0000100#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
101 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000102class Redirection;
103class Simulator;
104#endif
105
lrn@chromium.org7516f052011-03-30 08:52:27 +0000106
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000107// Static indirection table for handles to constants. If a frame
108// element represents a constant, the data contains an index into
109// this table of handles to the actual constants.
110// Static indirection table for handles to constants. If a Result
111// represents a constant, the data contains an index into this table
112// of handles to the actual constants.
113typedef ZoneList<Handle<Object> > ZoneObjectList;
114
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000115#define RETURN_IF_SCHEDULED_EXCEPTION(isolate) \
116 do { \
117 Isolate* __isolate__ = (isolate); \
118 if (__isolate__->has_scheduled_exception()) { \
119 return __isolate__->PromoteScheduledException(); \
120 } \
121 } while (false)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000122
123#define RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, value) \
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000124 do { \
125 if ((call).is_null()) { \
126 ASSERT((isolate)->has_pending_exception()); \
127 return (value); \
128 } \
129 } while (false)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000130
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000131#define CHECK_NOT_EMPTY_HANDLE(isolate, call) \
132 do { \
133 ASSERT(!(isolate)->has_pending_exception()); \
134 CHECK(!(call).is_null()); \
135 CHECK(!(isolate)->has_pending_exception()); \
136 } while (false)
137
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000138#define RETURN_IF_EMPTY_HANDLE(isolate, call) \
139 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception())
140
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000141#define FOR_EACH_ISOLATE_ADDRESS_NAME(C) \
142 C(Handler, handler) \
143 C(CEntryFP, c_entry_fp) \
144 C(Context, context) \
145 C(PendingException, pending_exception) \
146 C(ExternalCaughtException, external_caught_exception) \
147 C(JSEntrySP, js_entry_sp)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000148
149
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000150// Platform-independent, reliable thread identifier.
151class ThreadId {
152 public:
153 // Creates an invalid ThreadId.
154 ThreadId() : id_(kInvalidId) {}
155
156 // Returns ThreadId for current thread.
157 static ThreadId Current() { return ThreadId(GetCurrentThreadId()); }
158
159 // Returns invalid ThreadId (guaranteed not to be equal to any thread).
160 static ThreadId Invalid() { return ThreadId(kInvalidId); }
161
162 // Compares ThreadIds for equality.
163 INLINE(bool Equals(const ThreadId& other) const) {
164 return id_ == other.id_;
165 }
166
167 // Checks whether this ThreadId refers to any thread.
168 INLINE(bool IsValid() const) {
169 return id_ != kInvalidId;
170 }
171
172 // Converts ThreadId to an integer representation
173 // (required for public API: V8::V8::GetCurrentThreadId).
174 int ToInteger() const { return id_; }
175
176 // Converts ThreadId to an integer representation
177 // (required for public API: V8::V8::TerminateExecution).
178 static ThreadId FromInteger(int id) { return ThreadId(id); }
179
180 private:
181 static const int kInvalidId = -1;
182
183 explicit ThreadId(int id) : id_(id) {}
184
185 static int AllocateThreadId();
186
187 static int GetCurrentThreadId();
188
189 int id_;
190
191 static Atomic32 highest_thread_id_;
192
193 friend class Isolate;
194};
195
196
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000197class ThreadLocalTop BASE_EMBEDDED {
198 public:
vitalyr@chromium.org5523ec32011-04-15 21:42:52 +0000199 // Does early low-level initialization that does not depend on the
200 // isolate being present.
201 ThreadLocalTop();
202
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000203 // Initialize the thread data.
204 void Initialize();
205
206 // Get the top C++ try catch handler or NULL if none are registered.
207 //
208 // This method is not guarenteed to return an address that can be
209 // used for comparison with addresses into the JS stack. If such an
210 // address is needed, use try_catch_handler_address.
211 v8::TryCatch* TryCatchHandler();
212
213 // Get the address of the top C++ try catch handler or NULL if
214 // none are registered.
215 //
216 // This method always returns an address that can be compared to
217 // pointers into the JavaScript stack. When running on actual
218 // hardware, try_catch_handler_address and TryCatchHandler return
219 // the same pointer. When running on a simulator with a separate JS
220 // stack, try_catch_handler_address returns a JS stack address that
221 // corresponds to the place on the JS stack where the C++ handler
222 // would have been if the stack were not separate.
223 inline Address try_catch_handler_address() {
224 return try_catch_handler_address_;
225 }
226
227 // Set the address of the top C++ try catch handler.
228 inline void set_try_catch_handler_address(Address address) {
229 try_catch_handler_address_ = address;
230 }
231
232 void Free() {
233 ASSERT(!has_pending_message_);
234 ASSERT(!external_caught_exception_);
235 ASSERT(try_catch_handler_address_ == NULL);
236 }
237
lrn@chromium.org1c092762011-05-09 09:42:16 +0000238 Isolate* isolate_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000239 // The context where the current execution method is created and for variable
240 // lookups.
241 Context* context_;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000242 ThreadId thread_id_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000243 MaybeObject* pending_exception_;
244 bool has_pending_message_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000245 Object* pending_message_obj_;
246 Script* pending_message_script_;
247 int pending_message_start_pos_;
248 int pending_message_end_pos_;
249 // Use a separate value for scheduled exceptions to preserve the
250 // invariants that hold about pending_exception. We may want to
251 // unify them later.
252 MaybeObject* scheduled_exception_;
253 bool external_caught_exception_;
254 SaveContext* save_context_;
255 v8::TryCatch* catcher_;
256
257 // Stack.
258 Address c_entry_fp_; // the frame pointer of the top c entry frame
259 Address handler_; // try-blocks are chained through the stack
260
261#ifdef USE_SIMULATOR
lrn@chromium.org7516f052011-03-30 08:52:27 +0000262#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_MIPS)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000263 Simulator* simulator_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000264#endif
265#endif // USE_SIMULATOR
266
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000267 Address js_entry_sp_; // the stack pointer of the bottom JS entry frame
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000268 Address external_callback_; // the external callback we're currently in
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000269 StateTag current_vm_state_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000270
271 // Generated code scratch locations.
272 int32_t formal_count_;
273
274 // Call back function to report unsafe JS accesses.
275 v8::FailedAccessCheckCallback failed_access_check_callback_;
276
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000277 // Head of the list of live LookupResults.
278 LookupResult* top_lookup_result_;
279
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000280 // Whether out of memory exceptions should be ignored.
281 bool ignore_out_of_memory_;
282
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000283 private:
vitalyr@chromium.org5523ec32011-04-15 21:42:52 +0000284 void InitializeInternal();
285
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000286 Address try_catch_handler_address_;
287};
288
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000289
290#ifdef ENABLE_DEBUGGER_SUPPORT
291
292#define ISOLATE_DEBUGGER_INIT_LIST(V) \
293 V(v8::Debug::EventCallback, debug_event_callback, NULL) \
294 V(DebuggerAgent*, debugger_agent_instance, NULL)
295#else
296
297#define ISOLATE_DEBUGGER_INIT_LIST(V)
298
299#endif
300
301#ifdef DEBUG
302
303#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V) \
304 V(CommentStatistic, paged_space_comments_statistics, \
305 CommentStatistic::kMaxComments + 1)
306#else
307
308#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
309
310#endif
311
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000312#define ISOLATE_INIT_ARRAY_LIST(V) \
313 /* SerializerDeserializer state. */ \
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000314 V(int32_t, jsregexp_static_offsets_vector, kJSRegexpStaticOffsetsVectorSize) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000315 V(int, bad_char_shift_table, kUC16AlphabetSize) \
316 V(int, good_suffix_shift_table, (kBMMaxShift + 1)) \
317 V(int, suffix_table, (kBMMaxShift + 1)) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000318 V(uint32_t, private_random_seed, 2) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000319 ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
320
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000321typedef List<HeapObject*, PreallocatedStorageAllocationPolicy> DebugObjectCache;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000322
323#define ISOLATE_INIT_LIST(V) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000324 /* SerializerDeserializer state. */ \
325 V(int, serialize_partial_snapshot_cache_length, 0) \
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000326 V(int, serialize_partial_snapshot_cache_capacity, 0) \
327 V(Object**, serialize_partial_snapshot_cache, NULL) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000328 /* Assembler state. */ \
329 /* A previously allocated buffer of kMinimalBufferSize bytes, or NULL. */ \
330 V(byte*, assembler_spare_buffer, NULL) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000331 V(FatalErrorCallback, exception_behavior, NULL) \
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000332 V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, NULL) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000333 V(v8::Debug::MessageHandler, message_handler, NULL) \
334 /* To distinguish the function templates, so that we can find them in the */ \
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000335 /* function cache of the native context. */ \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000336 V(int, next_serial_number, 0) \
337 V(ExternalReferenceRedirectorPointer*, external_reference_redirector, NULL) \
338 V(bool, always_allow_natives_syntax, false) \
339 /* Part of the state of liveedit. */ \
340 V(FunctionInfoListener*, active_function_info_listener, NULL) \
341 /* State for Relocatable. */ \
342 V(Relocatable*, relocatable_top, NULL) \
343 /* State for CodeEntry in profile-generator. */ \
344 V(CodeGenerator*, current_code_generator, NULL) \
345 V(bool, jump_target_compiling_deferred_code, false) \
346 V(DebugObjectCache*, string_stream_debug_object_cache, NULL) \
347 V(Object*, string_stream_current_security_token, NULL) \
348 /* TODO(isolates): Release this on destruction? */ \
349 V(int*, irregexp_interpreter_backtrack_stack_cache, NULL) \
350 /* Serializer state. */ \
351 V(ExternalReferenceTable*, external_reference_table, NULL) \
352 /* AstNode state. */ \
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000353 V(int, ast_node_id, 0) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000354 V(unsigned, ast_node_count, 0) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000355 /* SafeStackFrameIterator activations count. */ \
356 V(int, safe_stack_iterator_counter, 0) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000357 V(uint64_t, enabled_cpu_features, 0) \
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000358 V(CpuProfiler*, cpu_profiler, NULL) \
359 V(HeapProfiler*, heap_profiler, NULL) \
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000360 V(bool, observer_delivery_pending, false) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000361 ISOLATE_DEBUGGER_INIT_LIST(V)
362
363class Isolate {
364 // These forward declarations are required to make the friend declarations in
365 // PerIsolateThreadData work on some older versions of gcc.
366 class ThreadDataTable;
367 class EntryStackItem;
368 public:
369 ~Isolate();
370
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000371 // A thread has a PerIsolateThreadData instance for each isolate that it has
372 // entered. That instance is allocated when the isolate is initially entered
373 // and reused on subsequent entries.
374 class PerIsolateThreadData {
375 public:
376 PerIsolateThreadData(Isolate* isolate, ThreadId thread_id)
377 : isolate_(isolate),
378 thread_id_(thread_id),
379 stack_limit_(0),
380 thread_state_(NULL),
lrn@chromium.org7516f052011-03-30 08:52:27 +0000381#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
382 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000383 simulator_(NULL),
384#endif
385 next_(NULL),
386 prev_(NULL) { }
387 Isolate* isolate() const { return isolate_; }
388 ThreadId thread_id() const { return thread_id_; }
389 void set_stack_limit(uintptr_t value) { stack_limit_ = value; }
390 uintptr_t stack_limit() const { return stack_limit_; }
391 ThreadState* thread_state() const { return thread_state_; }
392 void set_thread_state(ThreadState* value) { thread_state_ = value; }
393
lrn@chromium.org7516f052011-03-30 08:52:27 +0000394#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
395 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000396 Simulator* simulator() const { return simulator_; }
397 void set_simulator(Simulator* simulator) {
398 simulator_ = simulator;
399 }
400#endif
401
402 bool Matches(Isolate* isolate, ThreadId thread_id) const {
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000403 return isolate_ == isolate && thread_id_.Equals(thread_id);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000404 }
405
406 private:
407 Isolate* isolate_;
408 ThreadId thread_id_;
409 uintptr_t stack_limit_;
410 ThreadState* thread_state_;
411
lrn@chromium.org7516f052011-03-30 08:52:27 +0000412#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
413 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000414 Simulator* simulator_;
415#endif
416
417 PerIsolateThreadData* next_;
418 PerIsolateThreadData* prev_;
419
420 friend class Isolate;
421 friend class ThreadDataTable;
422 friend class EntryStackItem;
423
424 DISALLOW_COPY_AND_ASSIGN(PerIsolateThreadData);
425 };
426
427
428 enum AddressId {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000429#define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address,
430 FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM)
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +0000431#undef DECLARE_ENUM
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000432 kIsolateAddressCount
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000433 };
434
435 // Returns the PerIsolateThreadData for the current thread (or NULL if one is
436 // not currently set).
437 static PerIsolateThreadData* CurrentPerIsolateThreadData() {
438 return reinterpret_cast<PerIsolateThreadData*>(
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000439 Thread::GetThreadLocal(per_isolate_thread_data_key_));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000440 }
441
442 // Returns the isolate inside which the current thread is running.
443 INLINE(static Isolate* Current()) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000444 Isolate* isolate = reinterpret_cast<Isolate*>(
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000445 Thread::GetExistingThreadLocal(isolate_key_));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000446 ASSERT(isolate != NULL);
447 return isolate;
448 }
449
450 INLINE(static Isolate* UncheckedCurrent()) {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000451 return reinterpret_cast<Isolate*>(Thread::GetThreadLocal(isolate_key_));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000452 }
453
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000454 // Usually called by Init(), but can be called early e.g. to allow
455 // testing components that require logging but not the whole
456 // isolate.
457 //
458 // Safe to call more than once.
459 void InitializeLoggingAndCounters();
460
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000461 bool Init(Deserializer* des);
462
463 bool IsInitialized() { return state_ == INITIALIZED; }
464
465 // True if at least one thread Enter'ed this isolate.
466 bool IsInUse() { return entry_stack_ != NULL; }
467
468 // Destroys the non-default isolates.
469 // Sets default isolate into "has_been_disposed" state rather then destroying,
470 // for legacy API reasons.
471 void TearDown();
472
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000473 bool IsDefaultIsolate() const { return this == default_isolate_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000474
475 // Ensures that process-wide resources and the default isolate have been
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000476 // allocated. It is only necessary to call this method in rare cases, for
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000477 // example if you are using V8 from within the body of a static initializer.
478 // Safe to call multiple times.
479 static void EnsureDefaultIsolate();
480
lrn@chromium.org1c092762011-05-09 09:42:16 +0000481 // Find the PerThread for this particular (isolate, thread) combination
482 // If one does not yet exist, return null.
483 PerIsolateThreadData* FindPerThreadDataForThisThread();
484
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000485#ifdef ENABLE_DEBUGGER_SUPPORT
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000486 // Get the debugger from the default isolate. Preinitializes the
487 // default isolate if needed.
488 static Debugger* GetDefaultIsolateDebugger();
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000489#endif
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000490
491 // Get the stack guard from the default isolate. Preinitializes the
492 // default isolate if needed.
493 static StackGuard* GetDefaultIsolateStackGuard();
494
495 // Returns the key used to store the pointer to the current isolate.
496 // Used internally for V8 threads that do not execute JavaScript but still
497 // are part of the domain of an isolate (like the context switcher).
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000498 static Thread::LocalStorageKey isolate_key() {
499 return isolate_key_;
500 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000501
502 // Returns the key used to store process-wide thread IDs.
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000503 static Thread::LocalStorageKey thread_id_key() {
504 return thread_id_key_;
505 }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000506
507 static Thread::LocalStorageKey per_isolate_thread_data_key();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000508
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000509 // If a client attempts to create a Locker without specifying an isolate,
510 // we assume that the client is using legacy behavior. Set up the current
511 // thread to be inside the implicit isolate (or fail a check if we have
512 // switched to non-legacy behavior).
513 static void EnterDefaultIsolate();
514
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000515 // Mutex for serializing access to break control structures.
516 Mutex* break_access() { return break_access_; }
517
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000518 // Mutex for serializing access to debugger.
519 Mutex* debugger_access() { return debugger_access_; }
520
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000521 Address get_address_from_id(AddressId id);
522
523 // Access to top context (where the current function object was created).
524 Context* context() { return thread_local_top_.context_; }
525 void set_context(Context* context) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000526 ASSERT(context == NULL || context->IsContext());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000527 thread_local_top_.context_ = context;
528 }
529 Context** context_address() { return &thread_local_top_.context_; }
530
531 SaveContext* save_context() {return thread_local_top_.save_context_; }
532 void set_save_context(SaveContext* save) {
533 thread_local_top_.save_context_ = save;
534 }
535
536 // Access to current thread id.
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000537 ThreadId thread_id() { return thread_local_top_.thread_id_; }
538 void set_thread_id(ThreadId id) { thread_local_top_.thread_id_ = id; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000539
540 // Interface to pending exception.
541 MaybeObject* pending_exception() {
542 ASSERT(has_pending_exception());
543 return thread_local_top_.pending_exception_;
544 }
545 bool external_caught_exception() {
546 return thread_local_top_.external_caught_exception_;
547 }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000548 void set_external_caught_exception(bool value) {
549 thread_local_top_.external_caught_exception_ = value;
550 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000551 void set_pending_exception(MaybeObject* exception) {
552 thread_local_top_.pending_exception_ = exception;
553 }
554 void clear_pending_exception() {
555 thread_local_top_.pending_exception_ = heap_.the_hole_value();
556 }
557 MaybeObject** pending_exception_address() {
558 return &thread_local_top_.pending_exception_;
559 }
560 bool has_pending_exception() {
561 return !thread_local_top_.pending_exception_->IsTheHole();
562 }
563 void clear_pending_message() {
564 thread_local_top_.has_pending_message_ = false;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000565 thread_local_top_.pending_message_obj_ = heap_.the_hole_value();
566 thread_local_top_.pending_message_script_ = NULL;
567 }
568 v8::TryCatch* try_catch_handler() {
569 return thread_local_top_.TryCatchHandler();
570 }
571 Address try_catch_handler_address() {
572 return thread_local_top_.try_catch_handler_address();
573 }
574 bool* external_caught_exception_address() {
575 return &thread_local_top_.external_caught_exception_;
576 }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000577 v8::TryCatch* catcher() {
578 return thread_local_top_.catcher_;
579 }
580 void set_catcher(v8::TryCatch* catcher) {
581 thread_local_top_.catcher_ = catcher;
582 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000583
584 MaybeObject** scheduled_exception_address() {
585 return &thread_local_top_.scheduled_exception_;
586 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000587
588 Address pending_message_obj_address() {
589 return reinterpret_cast<Address>(&thread_local_top_.pending_message_obj_);
590 }
591
592 Address has_pending_message_address() {
593 return reinterpret_cast<Address>(&thread_local_top_.has_pending_message_);
594 }
595
596 Address pending_message_script_address() {
597 return reinterpret_cast<Address>(
598 &thread_local_top_.pending_message_script_);
599 }
600
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000601 MaybeObject* scheduled_exception() {
602 ASSERT(has_scheduled_exception());
603 return thread_local_top_.scheduled_exception_;
604 }
605 bool has_scheduled_exception() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000606 return thread_local_top_.scheduled_exception_ != heap_.the_hole_value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000607 }
608 void clear_scheduled_exception() {
609 thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
610 }
611
612 bool IsExternallyCaught();
613
614 bool is_catchable_by_javascript(MaybeObject* exception) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000615 return (!exception->IsOutOfMemory()) &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000616 (exception != heap()->termination_exception());
617 }
618
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000619 // Serializer.
620 void PushToPartialSnapshotCache(Object* obj);
621
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000622 // JS execution stack (see frames.h).
623 static Address c_entry_fp(ThreadLocalTop* thread) {
624 return thread->c_entry_fp_;
625 }
626 static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
627
628 inline Address* c_entry_fp_address() {
629 return &thread_local_top_.c_entry_fp_;
630 }
631 inline Address* handler_address() { return &thread_local_top_.handler_; }
632
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000633 // Bottom JS entry (see StackTracer::Trace in log.cc).
634 static Address js_entry_sp(ThreadLocalTop* thread) {
635 return thread->js_entry_sp_;
636 }
637 inline Address* js_entry_sp_address() {
638 return &thread_local_top_.js_entry_sp_;
639 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000640
641 // Generated code scratch locations.
642 void* formal_count_address() { return &thread_local_top_.formal_count_; }
643
644 // Returns the global object of the current context. It could be
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000645 // a builtin object, or a JS global object.
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000646 Handle<GlobalObject> global_object() {
647 return Handle<GlobalObject>(context()->global_object());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000648 }
649
650 // Returns the global proxy object of the current context.
651 Object* global_proxy() {
652 return context()->global_proxy();
653 }
654
655 Handle<JSBuiltinsObject> js_builtins_object() {
656 return Handle<JSBuiltinsObject>(thread_local_top_.context_->builtins());
657 }
658
659 static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
660 void FreeThreadResources() { thread_local_top_.Free(); }
661
662 // This method is called by the api after operations that may throw
663 // exceptions. If an exception was thrown and not handled by an external
664 // handler the exception is scheduled to be rethrown when we return to running
665 // JavaScript code. If an exception is scheduled true is returned.
666 bool OptionalRescheduleException(bool is_bottom_call);
667
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000668 class ExceptionScope {
669 public:
670 explicit ExceptionScope(Isolate* isolate) :
671 // Scope currently can only be used for regular exceptions, not
672 // failures like OOM or termination exception.
673 isolate_(isolate),
674 pending_exception_(isolate_->pending_exception()->ToObjectUnchecked()),
675 catcher_(isolate_->catcher())
676 { }
677
678 ~ExceptionScope() {
679 isolate_->set_catcher(catcher_);
680 isolate_->set_pending_exception(*pending_exception_);
681 }
682
683 private:
684 Isolate* isolate_;
685 Handle<Object> pending_exception_;
686 v8::TryCatch* catcher_;
687 };
688
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000689 void SetCaptureStackTraceForUncaughtExceptions(
690 bool capture,
691 int frame_limit,
692 StackTrace::StackTraceOptions options);
693
694 // Tells whether the current context has experienced an out of memory
695 // exception.
696 bool is_out_of_memory();
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000697 bool ignore_out_of_memory() {
698 return thread_local_top_.ignore_out_of_memory_;
699 }
700 void set_ignore_out_of_memory(bool value) {
701 thread_local_top_.ignore_out_of_memory_ = value;
702 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000703
704 void PrintCurrentStackTrace(FILE* out);
705 void PrintStackTrace(FILE* out, char* thread_data);
706 void PrintStack(StringStream* accumulator);
707 void PrintStack();
708 Handle<String> StackTraceString();
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000709 NO_INLINE(void PushStackTraceAndDie(unsigned int magic,
710 Object* object,
711 Map* map,
712 unsigned int magic2));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000713 Handle<JSArray> CaptureCurrentStackTrace(
714 int frame_limit,
715 StackTrace::StackTraceOptions options);
716
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000717 Handle<JSArray> CaptureSimpleStackTrace(Handle<JSObject> error_object,
718 Handle<Object> caller,
719 int limit);
720 void CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object);
jkummerow@chromium.orgab7dad42012-02-07 12:07:34 +0000721
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000722 // Returns if the top context may access the given global object. If
723 // the result is false, the pending exception is guaranteed to be
724 // set.
725 bool MayNamedAccess(JSObject* receiver,
726 Object* key,
727 v8::AccessType type);
728 bool MayIndexedAccess(JSObject* receiver,
729 uint32_t index,
730 v8::AccessType type);
731
732 void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
733 void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
734
735 // Exception throwing support. The caller should use the result
736 // of Throw() as its return value.
737 Failure* Throw(Object* exception, MessageLocation* location = NULL);
738 // Re-throw an exception. This involves no error reporting since
739 // error reporting was handled when the exception was thrown
740 // originally.
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000741 Failure* ReThrow(MaybeObject* exception);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000742 void ScheduleThrow(Object* exception);
743 void ReportPendingMessages();
mmassi@chromium.org49a44672012-12-04 13:52:03 +0000744 // Return pending location if any or unfilled structure.
745 MessageLocation GetMessageLocation();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000746 Failure* ThrowIllegalOperation();
747
748 // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
749 Failure* PromoteScheduledException();
jkummerow@chromium.orgab7dad42012-02-07 12:07:34 +0000750 void DoThrow(Object* exception, MessageLocation* location);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000751 // Checks if exception should be reported and finds out if it's
752 // caught externally.
753 bool ShouldReportException(bool* can_be_caught_externally,
754 bool catchable_by_javascript);
755
756 // Attempts to compute the current source location, storing the
757 // result in the target out parameter.
758 void ComputeLocation(MessageLocation* target);
759
760 // Override command line flag.
761 void TraceException(bool flag);
762
763 // Out of resource exception helpers.
764 Failure* StackOverflow();
765 Failure* TerminateExecution();
766
767 // Administration
768 void Iterate(ObjectVisitor* v);
769 void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
770 char* Iterate(ObjectVisitor* v, char* t);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771 void IterateThread(ThreadVisitor* v, char* t);
772
773
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000774 // Returns the current native and global context.
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000775 Handle<Context> native_context();
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000776 Handle<Context> global_context();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000777
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000778 // Returns the native context of the calling JavaScript code. That
779 // is, the native context of the top-most JavaScript frame.
780 Handle<Context> GetCallingNativeContext();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781
782 void RegisterTryCatchHandler(v8::TryCatch* that);
783 void UnregisterTryCatchHandler(v8::TryCatch* that);
784
785 char* ArchiveThread(char* to);
786 char* RestoreThread(char* from);
787
788 static const char* const kStackOverflowMessage;
789
790 static const int kUC16AlphabetSize = 256; // See StringSearchBase.
791 static const int kBMMaxShift = 250; // See StringSearchBase.
792
793 // Accessors.
794#define GLOBAL_ACCESSOR(type, name, initialvalue) \
795 inline type name() const { \
796 ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \
797 return name##_; \
798 } \
799 inline void set_##name(type value) { \
800 ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \
801 name##_ = value; \
802 }
803 ISOLATE_INIT_LIST(GLOBAL_ACCESSOR)
804#undef GLOBAL_ACCESSOR
805
806#define GLOBAL_ARRAY_ACCESSOR(type, name, length) \
807 inline type* name() { \
808 ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \
809 return &(name##_)[0]; \
810 }
811 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR)
812#undef GLOBAL_ARRAY_ACCESSOR
813
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000814#define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000815 Handle<type> name() { \
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000816 return Handle<type>(context()->native_context()->name()); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000817 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000818 NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR)
819#undef NATIVE_CONTEXT_FIELD_ACCESSOR
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000820
821 Bootstrapper* bootstrapper() { return bootstrapper_; }
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000822 Counters* counters() {
823 // Call InitializeLoggingAndCounters() if logging is needed before
824 // the isolate is fully initialized.
825 ASSERT(counters_ != NULL);
826 return counters_;
827 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000828 CodeRange* code_range() { return code_range_; }
829 RuntimeProfiler* runtime_profiler() { return runtime_profiler_; }
830 CompilationCache* compilation_cache() { return compilation_cache_; }
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000831 Logger* logger() {
832 // Call InitializeLoggingAndCounters() if logging is needed before
833 // the isolate is fully initialized.
834 ASSERT(logger_ != NULL);
835 return logger_;
836 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000837 StackGuard* stack_guard() { return &stack_guard_; }
838 Heap* heap() { return &heap_; }
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000839 StatsTable* stats_table();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000840 StubCache* stub_cache() { return stub_cache_; }
841 DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
842 ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
843
844 TranscendentalCache* transcendental_cache() const {
845 return transcendental_cache_;
846 }
847
848 MemoryAllocator* memory_allocator() {
849 return memory_allocator_;
850 }
851
852 KeyedLookupCache* keyed_lookup_cache() {
853 return keyed_lookup_cache_;
854 }
855
856 ContextSlotCache* context_slot_cache() {
857 return context_slot_cache_;
858 }
859
860 DescriptorLookupCache* descriptor_lookup_cache() {
861 return descriptor_lookup_cache_;
862 }
863
864 v8::ImplementationUtilities::HandleScopeData* handle_scope_data() {
865 return &handle_scope_data_;
866 }
867 HandleScopeImplementer* handle_scope_implementer() {
868 ASSERT(handle_scope_implementer_);
869 return handle_scope_implementer_;
870 }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000871 Zone* runtime_zone() { return &runtime_zone_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000872
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000873 UnicodeCache* unicode_cache() {
874 return unicode_cache_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000875 }
876
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000877 InnerPointerToCodeCache* inner_pointer_to_code_cache() {
878 return inner_pointer_to_code_cache_;
879 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000880
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +0000881 ConsStringIteratorOp* write_iterator() { return write_iterator_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000882
883 GlobalHandles* global_handles() { return global_handles_; }
884
885 ThreadManager* thread_manager() { return thread_manager_; }
886
887 ContextSwitcher* context_switcher() { return context_switcher_; }
888
889 void set_context_switcher(ContextSwitcher* switcher) {
890 context_switcher_ = switcher;
891 }
892
893 StringTracker* string_tracker() { return string_tracker_; }
894
895 unibrow::Mapping<unibrow::Ecma262UnCanonicalize>* jsregexp_uncanonicalize() {
896 return &jsregexp_uncanonicalize_;
897 }
898
899 unibrow::Mapping<unibrow::CanonicalizationRange>* jsregexp_canonrange() {
900 return &jsregexp_canonrange_;
901 }
902
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +0000903 ConsStringIteratorOp* objects_string_compare_iterator_a() {
904 return &objects_string_compare_iterator_a_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000905 }
906
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +0000907 ConsStringIteratorOp* objects_string_compare_iterator_b() {
908 return &objects_string_compare_iterator_b_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000909 }
910
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +0000911 StaticResource<ConsStringIteratorOp>* objects_string_iterator() {
912 return &objects_string_iterator_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000913 }
914
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000915 RuntimeState* runtime_state() { return &runtime_state_; }
916
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000917 void set_fp_stubs_generated(bool value) {
918 fp_stubs_generated_ = value;
919 }
920
921 bool fp_stubs_generated() { return fp_stubs_generated_; }
922
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000923 Builtins* builtins() { return &builtins_; }
924
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000925 void NotifyExtensionInstalled() {
926 has_installed_extensions_ = true;
927 }
928
929 bool has_installed_extensions() { return has_installed_extensions_; }
930
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000931 unibrow::Mapping<unibrow::Ecma262Canonicalize>*
932 regexp_macro_assembler_canonicalize() {
933 return &regexp_macro_assembler_canonicalize_;
934 }
935
936 RegExpStack* regexp_stack() { return regexp_stack_; }
937
938 unibrow::Mapping<unibrow::Ecma262Canonicalize>*
939 interp_canonicalize_mapping() {
940 return &interp_canonicalize_mapping_;
941 }
942
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000943 void* PreallocatedStorageNew(size_t size);
944 void PreallocatedStorageDelete(void* p);
945 void PreallocatedStorageInit(size_t size);
946
947#ifdef ENABLE_DEBUGGER_SUPPORT
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000948 Debugger* debugger() {
949 if (!NoBarrier_Load(&debugger_initialized_)) InitializeDebugger();
950 return debugger_;
951 }
952 Debug* debug() {
953 if (!NoBarrier_Load(&debugger_initialized_)) InitializeDebugger();
954 return debug_;
955 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000956#endif
957
danno@chromium.org88aa0582012-03-23 15:11:57 +0000958 inline bool IsDebuggerActive();
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000959 inline bool DebuggerHasBreakPoints();
960
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000961#ifdef DEBUG
962 HistogramInfo* heap_histograms() { return heap_histograms_; }
963
964 JSObject::SpillInformation* js_spill_information() {
965 return &js_spill_information_;
966 }
967
968 int* code_kind_statistics() { return code_kind_statistics_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000969
970 bool allow_handle_deref() { return allow_handle_deref_; }
971 void set_allow_handle_deref(bool allow) { allow_handle_deref_ = allow; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000972#endif
973
lrn@chromium.org7516f052011-03-30 08:52:27 +0000974#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
975 defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000976 bool simulator_initialized() { return simulator_initialized_; }
977 void set_simulator_initialized(bool initialized) {
978 simulator_initialized_ = initialized;
979 }
980
981 HashMap* simulator_i_cache() { return simulator_i_cache_; }
982 void set_simulator_i_cache(HashMap* hash_map) {
983 simulator_i_cache_ = hash_map;
984 }
985
986 Redirection* simulator_redirection() {
987 return simulator_redirection_;
988 }
989 void set_simulator_redirection(Redirection* redirection) {
990 simulator_redirection_ = redirection;
991 }
992#endif
993
994 Factory* factory() { return reinterpret_cast<Factory*>(this); }
995
mstarzinger@chromium.org15613d02012-05-23 12:04:37 +0000996 static const int kJSRegexpStaticOffsetsVectorSize = 128;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000997
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000998 Address external_callback() {
999 return thread_local_top_.external_callback_;
1000 }
1001 void set_external_callback(Address callback) {
1002 thread_local_top_.external_callback_ = callback;
1003 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001004
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001005 StateTag current_vm_state() {
1006 return thread_local_top_.current_vm_state_;
1007 }
1008
1009 void SetCurrentVMState(StateTag state) {
1010 if (RuntimeProfiler::IsEnabled()) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001011 // Make sure thread local top is initialized.
1012 ASSERT(thread_local_top_.isolate_ == this);
vitalyr@chromium.orgb803dc22011-04-07 21:57:01 +00001013 StateTag current_state = thread_local_top_.current_vm_state_;
1014 if (current_state != JS && state == JS) {
1015 // Non-JS -> JS transition.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001016 RuntimeProfiler::IsolateEnteredJS(this);
vitalyr@chromium.orgb803dc22011-04-07 21:57:01 +00001017 } else if (current_state == JS && state != JS) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001018 // JS -> non-JS transition.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001019 RuntimeProfiler::IsolateExitedJS(this);
vitalyr@chromium.orgb803dc22011-04-07 21:57:01 +00001020 } else {
1021 // Other types of state transitions are not interesting to the
1022 // runtime profiler, because they don't affect whether we're
1023 // in JS or not.
1024 ASSERT((current_state == JS) == (state == JS));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001025 }
1026 }
1027 thread_local_top_.current_vm_state_ = state;
1028 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001029
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001030 void SetData(void* data) { embedder_data_ = data; }
1031 void* GetData() { return embedder_data_; }
1032
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001033 LookupResult* top_lookup_result() {
1034 return thread_local_top_.top_lookup_result_;
1035 }
1036 void SetTopLookupResult(LookupResult* top) {
1037 thread_local_top_.top_lookup_result_ = top;
1038 }
1039
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001040 bool context_exit_happened() {
1041 return context_exit_happened_;
1042 }
1043 void set_context_exit_happened(bool context_exit_happened) {
1044 context_exit_happened_ = context_exit_happened;
1045 }
1046
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001047 double time_millis_since_init() {
1048 return OS::TimeCurrentMillis() - time_millis_at_init_;
1049 }
1050
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001051 DateCache* date_cache() {
1052 return date_cache_;
1053 }
1054
1055 void set_date_cache(DateCache* date_cache) {
1056 if (date_cache != date_cache_) {
1057 delete date_cache_;
1058 }
1059 date_cache_ = date_cache;
1060 }
1061
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001062 CodeStubInterfaceDescriptor*
1063 code_stub_interface_descriptor(int index);
1064
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001065 void IterateDeferredHandles(ObjectVisitor* visitor);
1066 void LinkDeferredHandles(DeferredHandles* deferred_handles);
1067 void UnlinkDeferredHandles(DeferredHandles* deferred_handles);
1068
1069 OptimizingCompilerThread* optimizing_compiler_thread() {
1070 return &optimizing_compiler_thread_;
1071 }
1072
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00001073 // PreInits and returns a default isolate. Needed when a new thread tries
1074 // to create a Locker for the first time (the lock itself is in the isolate).
1075 // TODO(svenpanne) This method is on death row...
1076 static v8::Isolate* GetDefaultIsolateForLocking();
1077
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00001078 MarkingThread** marking_threads() {
1079 return marking_thread_;
1080 }
1081
1082 SweeperThread** sweeper_threads() {
1083 return sweeper_thread_;
1084 }
1085
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001086 private:
1087 Isolate();
1088
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00001089 friend struct GlobalState;
1090 friend struct InitializeGlobalState;
1091
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00001092 enum State {
1093 UNINITIALIZED, // Some components may not have been allocated.
1094 INITIALIZED // All components are fully initialized.
1095 };
1096
1097 // These fields are accessed through the API, offsets must be kept in sync
1098 // with v8::internal::Internals (in include/v8.h) constants. This is also
1099 // verified in Isolate::Init() using runtime checks.
1100 State state_; // Will be padded to kApiPointerSize.
1101 void* embedder_data_;
1102 Heap heap_;
1103
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001104 // The per-process lock should be acquired before the ThreadDataTable is
1105 // modified.
1106 class ThreadDataTable {
1107 public:
1108 ThreadDataTable();
1109 ~ThreadDataTable();
1110
1111 PerIsolateThreadData* Lookup(Isolate* isolate, ThreadId thread_id);
1112 void Insert(PerIsolateThreadData* data);
1113 void Remove(Isolate* isolate, ThreadId thread_id);
1114 void Remove(PerIsolateThreadData* data);
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001115 void RemoveAllThreads(Isolate* isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001116
1117 private:
1118 PerIsolateThreadData* list_;
1119 };
1120
1121 // These items form a stack synchronously with threads Enter'ing and Exit'ing
1122 // the Isolate. The top of the stack points to a thread which is currently
1123 // running the Isolate. When the stack is empty, the Isolate is considered
1124 // not entered by any thread and can be Disposed.
1125 // If the same thread enters the Isolate more then once, the entry_count_
1126 // is incremented rather then a new item pushed to the stack.
1127 class EntryStackItem {
1128 public:
1129 EntryStackItem(PerIsolateThreadData* previous_thread_data,
1130 Isolate* previous_isolate,
1131 EntryStackItem* previous_item)
1132 : entry_count(1),
1133 previous_thread_data(previous_thread_data),
1134 previous_isolate(previous_isolate),
1135 previous_item(previous_item) { }
1136
1137 int entry_count;
1138 PerIsolateThreadData* previous_thread_data;
1139 Isolate* previous_isolate;
1140 EntryStackItem* previous_item;
1141
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001142 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001143 DISALLOW_COPY_AND_ASSIGN(EntryStackItem);
1144 };
1145
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00001146 // This mutex protects highest_thread_id_, thread_data_table_ and
1147 // default_isolate_.
1148 static Mutex* process_wide_mutex_;
1149
1150 static Thread::LocalStorageKey per_isolate_thread_data_key_;
1151 static Thread::LocalStorageKey isolate_key_;
1152 static Thread::LocalStorageKey thread_id_key_;
1153 static Isolate* default_isolate_;
1154 static ThreadDataTable* thread_data_table_;
1155
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001156 void Deinit();
1157
1158 static void SetIsolateThreadLocals(Isolate* isolate,
1159 PerIsolateThreadData* data);
1160
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001161 // Allocate and insert PerIsolateThreadData into the ThreadDataTable
1162 // (regardless of whether such data already exists).
1163 PerIsolateThreadData* AllocatePerIsolateThreadData(ThreadId thread_id);
1164
1165 // Find the PerThread for this particular (isolate, thread) combination.
1166 // If one does not yet exist, allocate a new one.
1167 PerIsolateThreadData* FindOrAllocatePerThreadDataForThisThread();
1168
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001169 // Initializes the current thread to run this Isolate.
1170 // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
1171 // at the same time, this should be prevented using external locking.
1172 void Enter();
1173
1174 // Exits the current thread. The previosuly entered Isolate is restored
1175 // for the thread.
1176 // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
1177 // at the same time, this should be prevented using external locking.
1178 void Exit();
1179
1180 void PreallocatedMemoryThreadStart();
1181 void PreallocatedMemoryThreadStop();
1182 void InitializeThreadLocal();
1183
1184 void PrintStackTrace(FILE* out, ThreadLocalTop* thread);
1185 void MarkCompactPrologue(bool is_compacting,
1186 ThreadLocalTop* archived_thread_data);
1187 void MarkCompactEpilogue(bool is_compacting,
1188 ThreadLocalTop* archived_thread_data);
1189
1190 void FillCache();
1191
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001192 void PropagatePendingExceptionToExternalTryCatch();
1193
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001194 void InitializeDebugger();
1195
jkummerow@chromium.orgab7dad42012-02-07 12:07:34 +00001196 // Traverse prototype chain to find out whether the object is derived from
1197 // the Error object.
1198 bool IsErrorObject(Handle<Object> obj);
1199
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00001200 EntryStackItem* entry_stack_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001201 int stack_trace_nesting_level_;
1202 StringStream* incomplete_message_;
1203 // The preallocated memory thread singleton.
1204 PreallocatedMemoryThread* preallocated_memory_thread_;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001205 Address isolate_addresses_[kIsolateAddressCount + 1]; // NOLINT
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001206 NoAllocationStringAllocator* preallocated_message_space_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001207 Bootstrapper* bootstrapper_;
1208 RuntimeProfiler* runtime_profiler_;
1209 CompilationCache* compilation_cache_;
1210 Counters* counters_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001211 CodeRange* code_range_;
1212 Mutex* break_access_;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001213 Atomic32 debugger_initialized_;
1214 Mutex* debugger_access_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001215 Logger* logger_;
1216 StackGuard stack_guard_;
1217 StatsTable* stats_table_;
1218 StubCache* stub_cache_;
1219 DeoptimizerData* deoptimizer_data_;
1220 ThreadLocalTop thread_local_top_;
1221 bool capture_stack_trace_for_uncaught_exceptions_;
1222 int stack_trace_for_uncaught_exceptions_frame_limit_;
1223 StackTrace::StackTraceOptions stack_trace_for_uncaught_exceptions_options_;
1224 TranscendentalCache* transcendental_cache_;
1225 MemoryAllocator* memory_allocator_;
1226 KeyedLookupCache* keyed_lookup_cache_;
1227 ContextSlotCache* context_slot_cache_;
1228 DescriptorLookupCache* descriptor_lookup_cache_;
1229 v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
1230 HandleScopeImplementer* handle_scope_implementer_;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00001231 UnicodeCache* unicode_cache_;
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001232 Zone runtime_zone_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001233 PreallocatedStorage in_use_list_;
1234 PreallocatedStorage free_list_;
1235 bool preallocated_storage_preallocated_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001236 InnerPointerToCodeCache* inner_pointer_to_code_cache_;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001237 ConsStringIteratorOp* write_iterator_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001238 GlobalHandles* global_handles_;
1239 ContextSwitcher* context_switcher_;
1240 ThreadManager* thread_manager_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001241 RuntimeState runtime_state_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001242 bool fp_stubs_generated_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001243 Builtins builtins_;
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001244 bool has_installed_extensions_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001245 StringTracker* string_tracker_;
1246 unibrow::Mapping<unibrow::Ecma262UnCanonicalize> jsregexp_uncanonicalize_;
1247 unibrow::Mapping<unibrow::CanonicalizationRange> jsregexp_canonrange_;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001248 ConsStringIteratorOp objects_string_compare_iterator_a_;
1249 ConsStringIteratorOp objects_string_compare_iterator_b_;
1250 StaticResource<ConsStringIteratorOp> objects_string_iterator_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001251 unibrow::Mapping<unibrow::Ecma262Canonicalize>
1252 regexp_macro_assembler_canonicalize_;
1253 RegExpStack* regexp_stack_;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001254 DateCache* date_cache_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001255 unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001256 CodeStubInterfaceDescriptor* code_stub_interface_descriptors_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001257
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001258 // The garbage collector should be a little more aggressive when it knows
1259 // that a context was recently exited.
1260 bool context_exit_happened_;
1261
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001262 // Time stamp at initialization.
1263 double time_millis_at_init_;
1264
lrn@chromium.org7516f052011-03-30 08:52:27 +00001265#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
1266 defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001267 bool simulator_initialized_;
1268 HashMap* simulator_i_cache_;
1269 Redirection* simulator_redirection_;
1270#endif
1271
1272#ifdef DEBUG
1273 // A static array of histogram info for each type.
1274 HistogramInfo heap_histograms_[LAST_TYPE + 1];
1275 JSObject::SpillInformation js_spill_information_;
1276 int code_kind_statistics_[Code::NUMBER_OF_KINDS];
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001277
1278 bool allow_handle_deref_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001279#endif
1280
1281#ifdef ENABLE_DEBUGGER_SUPPORT
1282 Debugger* debugger_;
1283 Debug* debug_;
1284#endif
1285
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001286#define GLOBAL_BACKING_STORE(type, name, initialvalue) \
1287 type name##_;
1288 ISOLATE_INIT_LIST(GLOBAL_BACKING_STORE)
1289#undef GLOBAL_BACKING_STORE
1290
1291#define GLOBAL_ARRAY_BACKING_STORE(type, name, length) \
1292 type name##_[length];
1293 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_BACKING_STORE)
1294#undef GLOBAL_ARRAY_BACKING_STORE
1295
1296#ifdef DEBUG
1297 // This class is huge and has a number of fields controlled by
1298 // preprocessor defines. Make sure the offsets of these fields agree
1299 // between compilation units.
1300#define ISOLATE_FIELD_OFFSET(type, name, ignored) \
1301 static const intptr_t name##_debug_offset_;
1302 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
1303 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
1304#undef ISOLATE_FIELD_OFFSET
1305#endif
1306
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001307 DeferredHandles* deferred_handles_head_;
1308 OptimizingCompilerThread optimizing_compiler_thread_;
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00001309 MarkingThread** marking_thread_;
1310 SweeperThread** sweeper_thread_;
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001311
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001312 friend class ExecutionAccess;
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001313 friend class HandleScopeImplementer;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001314 friend class IsolateInitializer;
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00001315 friend class MarkingThread;
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001316 friend class OptimizingCompilerThread;
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00001317 friend class SweeperThread;
lrn@chromium.org1c092762011-05-09 09:42:16 +00001318 friend class ThreadManager;
1319 friend class Simulator;
1320 friend class StackGuard;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00001321 friend class ThreadId;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001322 friend class TestMemoryAllocatorScope;
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00001323 friend class TestCodeRangeScope;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001324 friend class v8::Isolate;
1325 friend class v8::Locker;
lrn@chromium.org1c092762011-05-09 09:42:16 +00001326 friend class v8::Unlocker;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001327
1328 DISALLOW_COPY_AND_ASSIGN(Isolate);
1329};
1330
1331
1332// If the GCC version is 4.1.x or 4.2.x an additional field is added to the
1333// class as a work around for a bug in the generated code found with these
1334// versions of GCC. See V8 issue 122 for details.
1335class SaveContext BASE_EMBEDDED {
1336 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001337 inline explicit SaveContext(Isolate* isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001338
1339 ~SaveContext() {
1340 if (context_.is_null()) {
1341 Isolate* isolate = Isolate::Current();
1342 isolate->set_context(NULL);
1343 isolate->set_save_context(prev_);
1344 } else {
1345 Isolate* isolate = context_->GetIsolate();
1346 isolate->set_context(*context_);
1347 isolate->set_save_context(prev_);
1348 }
1349 }
1350
1351 Handle<Context> context() { return context_; }
1352 SaveContext* prev() { return prev_; }
1353
1354 // Returns true if this save context is below a given JavaScript frame.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001355 bool IsBelowFrame(JavaScriptFrame* frame) {
1356 return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001357 }
1358
1359 private:
1360 Handle<Context> context_;
1361#if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
1362 Handle<Context> dummy_;
1363#endif
1364 SaveContext* prev_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001365 Address c_entry_fp_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001366};
1367
1368
1369class AssertNoContextChange BASE_EMBEDDED {
1370#ifdef DEBUG
1371 public:
1372 AssertNoContextChange() :
1373 scope_(Isolate::Current()),
1374 context_(Isolate::Current()->context(), Isolate::Current()) {
1375 }
1376
1377 ~AssertNoContextChange() {
1378 ASSERT(Isolate::Current()->context() == *context_);
1379 }
1380
1381 private:
1382 HandleScope scope_;
1383 Handle<Context> context_;
1384#else
1385 public:
1386 AssertNoContextChange() { }
1387#endif
1388};
1389
1390
1391class ExecutionAccess BASE_EMBEDDED {
1392 public:
1393 explicit ExecutionAccess(Isolate* isolate) : isolate_(isolate) {
1394 Lock(isolate);
1395 }
1396 ~ExecutionAccess() { Unlock(isolate_); }
1397
1398 static void Lock(Isolate* isolate) { isolate->break_access_->Lock(); }
1399 static void Unlock(Isolate* isolate) { isolate->break_access_->Unlock(); }
1400
1401 static bool TryLock(Isolate* isolate) {
1402 return isolate->break_access_->TryLock();
1403 }
1404
1405 private:
1406 Isolate* isolate_;
1407};
1408
1409
1410// Support for checking for stack-overflows in C++ code.
1411class StackLimitCheck BASE_EMBEDDED {
1412 public:
1413 explicit StackLimitCheck(Isolate* isolate) : isolate_(isolate) { }
1414
1415 bool HasOverflowed() const {
1416 StackGuard* stack_guard = isolate_->stack_guard();
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00001417 return (reinterpret_cast<uintptr_t>(this) < stack_guard->real_climit());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001418 }
1419 private:
1420 Isolate* isolate_;
1421};
1422
1423
1424// Support for temporarily postponing interrupts. When the outermost
1425// postpone scope is left the interrupts will be re-enabled and any
1426// interrupts that occurred while in the scope will be taken into
1427// account.
1428class PostponeInterruptsScope BASE_EMBEDDED {
1429 public:
1430 explicit PostponeInterruptsScope(Isolate* isolate)
1431 : stack_guard_(isolate->stack_guard()) {
1432 stack_guard_->thread_local_.postpone_interrupts_nesting_++;
1433 stack_guard_->DisableInterrupts();
1434 }
1435
1436 ~PostponeInterruptsScope() {
1437 if (--stack_guard_->thread_local_.postpone_interrupts_nesting_ == 0) {
1438 stack_guard_->EnableInterrupts();
1439 }
1440 }
1441 private:
1442 StackGuard* stack_guard_;
1443};
1444
1445
1446// Temporary macros for accessing current isolate and its subobjects.
1447// They provide better readability, especially when used a lot in the code.
1448#define HEAP (v8::internal::Isolate::Current()->heap())
1449#define FACTORY (v8::internal::Isolate::Current()->factory())
1450#define ISOLATE (v8::internal::Isolate::Current())
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001451#define LOGGER (v8::internal::Isolate::Current()->logger())
1452
1453
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001454// Tells whether the native context is marked with out of memory.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001455inline bool Context::has_out_of_memory() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001456 return native_context()->out_of_memory()->IsTrue();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001457}
1458
1459
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001460// Mark the native context with out of memory.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001461inline void Context::mark_out_of_memory() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001462 native_context()->set_out_of_memory(HEAP->true_value());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001463}
1464
1465
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001466} } // namespace v8::internal
1467
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001468#endif // V8_ISOLATE_H_