blob: 33e4d3edbaa735f0a5c447158e2db7e7a8718f2b [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
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000290class SystemThreadManager {
291 public:
292 enum ParallelSystemComponent {
293 PARALLEL_SWEEPING,
294 CONCURRENT_SWEEPING,
295 PARALLEL_MARKING
296 };
297
298 static int NumberOfParallelSystemThreads(ParallelSystemComponent type);
299
300 static const int kMaxThreads = 4;
301};
302
303
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000304#ifdef ENABLE_DEBUGGER_SUPPORT
305
306#define ISOLATE_DEBUGGER_INIT_LIST(V) \
307 V(v8::Debug::EventCallback, debug_event_callback, NULL) \
308 V(DebuggerAgent*, debugger_agent_instance, NULL)
309#else
310
311#define ISOLATE_DEBUGGER_INIT_LIST(V)
312
313#endif
314
315#ifdef DEBUG
316
317#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V) \
318 V(CommentStatistic, paged_space_comments_statistics, \
319 CommentStatistic::kMaxComments + 1)
320#else
321
322#define ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
323
324#endif
325
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000326#define ISOLATE_INIT_ARRAY_LIST(V) \
327 /* SerializerDeserializer state. */ \
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000328 V(int32_t, jsregexp_static_offsets_vector, kJSRegexpStaticOffsetsVectorSize) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000329 V(int, bad_char_shift_table, kUC16AlphabetSize) \
330 V(int, good_suffix_shift_table, (kBMMaxShift + 1)) \
331 V(int, suffix_table, (kBMMaxShift + 1)) \
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000332 V(uint32_t, private_random_seed, 2) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000333 ISOLATE_INIT_DEBUG_ARRAY_LIST(V)
334
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000335typedef List<HeapObject*, PreallocatedStorageAllocationPolicy> DebugObjectCache;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000336
337#define ISOLATE_INIT_LIST(V) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000338 /* SerializerDeserializer state. */ \
339 V(int, serialize_partial_snapshot_cache_length, 0) \
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000340 V(int, serialize_partial_snapshot_cache_capacity, 0) \
341 V(Object**, serialize_partial_snapshot_cache, NULL) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000342 /* Assembler state. */ \
343 /* A previously allocated buffer of kMinimalBufferSize bytes, or NULL. */ \
344 V(byte*, assembler_spare_buffer, NULL) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000345 V(FatalErrorCallback, exception_behavior, NULL) \
fschneider@chromium.orgfb144a02011-05-04 12:43:48 +0000346 V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, NULL) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000347 V(v8::Debug::MessageHandler, message_handler, NULL) \
348 /* To distinguish the function templates, so that we can find them in the */ \
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000349 /* function cache of the native context. */ \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000350 V(int, next_serial_number, 0) \
351 V(ExternalReferenceRedirectorPointer*, external_reference_redirector, NULL) \
352 V(bool, always_allow_natives_syntax, false) \
353 /* Part of the state of liveedit. */ \
354 V(FunctionInfoListener*, active_function_info_listener, NULL) \
355 /* State for Relocatable. */ \
356 V(Relocatable*, relocatable_top, NULL) \
357 /* State for CodeEntry in profile-generator. */ \
358 V(CodeGenerator*, current_code_generator, NULL) \
359 V(bool, jump_target_compiling_deferred_code, false) \
360 V(DebugObjectCache*, string_stream_debug_object_cache, NULL) \
361 V(Object*, string_stream_current_security_token, NULL) \
362 /* TODO(isolates): Release this on destruction? */ \
363 V(int*, irregexp_interpreter_backtrack_stack_cache, NULL) \
364 /* Serializer state. */ \
365 V(ExternalReferenceTable*, external_reference_table, NULL) \
366 /* AstNode state. */ \
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000367 V(int, ast_node_id, 0) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000368 V(unsigned, ast_node_count, 0) \
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000369 /* SafeStackFrameIterator activations count. */ \
370 V(int, safe_stack_iterator_counter, 0) \
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000371 V(uint64_t, enabled_cpu_features, 0) \
whesse@chromium.org030d38e2011-07-13 13:23:34 +0000372 V(CpuProfiler*, cpu_profiler, NULL) \
373 V(HeapProfiler*, heap_profiler, NULL) \
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000374 V(bool, observer_delivery_pending, false) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000375 ISOLATE_DEBUGGER_INIT_LIST(V)
376
377class Isolate {
378 // These forward declarations are required to make the friend declarations in
379 // PerIsolateThreadData work on some older versions of gcc.
380 class ThreadDataTable;
381 class EntryStackItem;
382 public:
383 ~Isolate();
384
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000385 // A thread has a PerIsolateThreadData instance for each isolate that it has
386 // entered. That instance is allocated when the isolate is initially entered
387 // and reused on subsequent entries.
388 class PerIsolateThreadData {
389 public:
390 PerIsolateThreadData(Isolate* isolate, ThreadId thread_id)
391 : isolate_(isolate),
392 thread_id_(thread_id),
393 stack_limit_(0),
394 thread_state_(NULL),
lrn@chromium.org7516f052011-03-30 08:52:27 +0000395#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
396 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000397 simulator_(NULL),
398#endif
399 next_(NULL),
400 prev_(NULL) { }
401 Isolate* isolate() const { return isolate_; }
402 ThreadId thread_id() const { return thread_id_; }
403 void set_stack_limit(uintptr_t value) { stack_limit_ = value; }
404 uintptr_t stack_limit() const { return stack_limit_; }
405 ThreadState* thread_state() const { return thread_state_; }
406 void set_thread_state(ThreadState* value) { thread_state_ = value; }
407
lrn@chromium.org7516f052011-03-30 08:52:27 +0000408#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
409 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000410 Simulator* simulator() const { return simulator_; }
411 void set_simulator(Simulator* simulator) {
412 simulator_ = simulator;
413 }
414#endif
415
416 bool Matches(Isolate* isolate, ThreadId thread_id) const {
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000417 return isolate_ == isolate && thread_id_.Equals(thread_id);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000418 }
419
420 private:
421 Isolate* isolate_;
422 ThreadId thread_id_;
423 uintptr_t stack_limit_;
424 ThreadState* thread_state_;
425
lrn@chromium.org7516f052011-03-30 08:52:27 +0000426#if !defined(__arm__) && defined(V8_TARGET_ARCH_ARM) || \
427 !defined(__mips__) && defined(V8_TARGET_ARCH_MIPS)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000428 Simulator* simulator_;
429#endif
430
431 PerIsolateThreadData* next_;
432 PerIsolateThreadData* prev_;
433
434 friend class Isolate;
435 friend class ThreadDataTable;
436 friend class EntryStackItem;
437
438 DISALLOW_COPY_AND_ASSIGN(PerIsolateThreadData);
439 };
440
441
442 enum AddressId {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000443#define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address,
444 FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM)
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +0000445#undef DECLARE_ENUM
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000446 kIsolateAddressCount
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000447 };
448
449 // Returns the PerIsolateThreadData for the current thread (or NULL if one is
450 // not currently set).
451 static PerIsolateThreadData* CurrentPerIsolateThreadData() {
452 return reinterpret_cast<PerIsolateThreadData*>(
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000453 Thread::GetThreadLocal(per_isolate_thread_data_key_));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000454 }
455
456 // Returns the isolate inside which the current thread is running.
457 INLINE(static Isolate* Current()) {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000458 Isolate* isolate = reinterpret_cast<Isolate*>(
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000459 Thread::GetExistingThreadLocal(isolate_key_));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000460 ASSERT(isolate != NULL);
461 return isolate;
462 }
463
464 INLINE(static Isolate* UncheckedCurrent()) {
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000465 return reinterpret_cast<Isolate*>(Thread::GetThreadLocal(isolate_key_));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000466 }
467
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000468 // Usually called by Init(), but can be called early e.g. to allow
469 // testing components that require logging but not the whole
470 // isolate.
471 //
472 // Safe to call more than once.
473 void InitializeLoggingAndCounters();
474
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000475 bool Init(Deserializer* des);
476
477 bool IsInitialized() { return state_ == INITIALIZED; }
478
479 // True if at least one thread Enter'ed this isolate.
480 bool IsInUse() { return entry_stack_ != NULL; }
481
482 // Destroys the non-default isolates.
483 // Sets default isolate into "has_been_disposed" state rather then destroying,
484 // for legacy API reasons.
485 void TearDown();
486
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000487 static void GlobalTearDown();
488
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000489 bool IsDefaultIsolate() const { return this == default_isolate_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000490
491 // Ensures that process-wide resources and the default isolate have been
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000492 // allocated. It is only necessary to call this method in rare cases, for
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000493 // example if you are using V8 from within the body of a static initializer.
494 // Safe to call multiple times.
495 static void EnsureDefaultIsolate();
496
lrn@chromium.org1c092762011-05-09 09:42:16 +0000497 // Find the PerThread for this particular (isolate, thread) combination
498 // If one does not yet exist, return null.
499 PerIsolateThreadData* FindPerThreadDataForThisThread();
500
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000501#ifdef ENABLE_DEBUGGER_SUPPORT
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000502 // Get the debugger from the default isolate. Preinitializes the
503 // default isolate if needed.
504 static Debugger* GetDefaultIsolateDebugger();
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000505#endif
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000506
507 // Get the stack guard from the default isolate. Preinitializes the
508 // default isolate if needed.
509 static StackGuard* GetDefaultIsolateStackGuard();
510
511 // Returns the key used to store the pointer to the current isolate.
512 // Used internally for V8 threads that do not execute JavaScript but still
513 // are part of the domain of an isolate (like the context switcher).
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000514 static Thread::LocalStorageKey isolate_key() {
515 return isolate_key_;
516 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000517
518 // Returns the key used to store process-wide thread IDs.
danno@chromium.org8c0a43f2012-04-03 08:37:53 +0000519 static Thread::LocalStorageKey thread_id_key() {
520 return thread_id_key_;
521 }
jkummerow@chromium.org1456e702012-03-30 08:38:13 +0000522
523 static Thread::LocalStorageKey per_isolate_thread_data_key();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000524
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000525 // If a client attempts to create a Locker without specifying an isolate,
526 // we assume that the client is using legacy behavior. Set up the current
527 // thread to be inside the implicit isolate (or fail a check if we have
528 // switched to non-legacy behavior).
529 static void EnterDefaultIsolate();
530
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000531 // Mutex for serializing access to break control structures.
532 Mutex* break_access() { return break_access_; }
533
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000534 // Mutex for serializing access to debugger.
535 Mutex* debugger_access() { return debugger_access_; }
536
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000537 Address get_address_from_id(AddressId id);
538
539 // Access to top context (where the current function object was created).
540 Context* context() { return thread_local_top_.context_; }
541 void set_context(Context* context) {
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000542 ASSERT(context == NULL || context->IsContext());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000543 thread_local_top_.context_ = context;
544 }
545 Context** context_address() { return &thread_local_top_.context_; }
546
547 SaveContext* save_context() {return thread_local_top_.save_context_; }
548 void set_save_context(SaveContext* save) {
549 thread_local_top_.save_context_ = save;
550 }
551
552 // Access to current thread id.
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000553 ThreadId thread_id() { return thread_local_top_.thread_id_; }
554 void set_thread_id(ThreadId id) { thread_local_top_.thread_id_ = id; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000555
556 // Interface to pending exception.
557 MaybeObject* pending_exception() {
558 ASSERT(has_pending_exception());
559 return thread_local_top_.pending_exception_;
560 }
561 bool external_caught_exception() {
562 return thread_local_top_.external_caught_exception_;
563 }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000564 void set_external_caught_exception(bool value) {
565 thread_local_top_.external_caught_exception_ = value;
566 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000567 void set_pending_exception(MaybeObject* exception) {
568 thread_local_top_.pending_exception_ = exception;
569 }
570 void clear_pending_exception() {
571 thread_local_top_.pending_exception_ = heap_.the_hole_value();
572 }
573 MaybeObject** pending_exception_address() {
574 return &thread_local_top_.pending_exception_;
575 }
576 bool has_pending_exception() {
577 return !thread_local_top_.pending_exception_->IsTheHole();
578 }
579 void clear_pending_message() {
580 thread_local_top_.has_pending_message_ = false;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000581 thread_local_top_.pending_message_obj_ = heap_.the_hole_value();
582 thread_local_top_.pending_message_script_ = NULL;
583 }
584 v8::TryCatch* try_catch_handler() {
585 return thread_local_top_.TryCatchHandler();
586 }
587 Address try_catch_handler_address() {
588 return thread_local_top_.try_catch_handler_address();
589 }
590 bool* external_caught_exception_address() {
591 return &thread_local_top_.external_caught_exception_;
592 }
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000593 v8::TryCatch* catcher() {
594 return thread_local_top_.catcher_;
595 }
596 void set_catcher(v8::TryCatch* catcher) {
597 thread_local_top_.catcher_ = catcher;
598 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000599
600 MaybeObject** scheduled_exception_address() {
601 return &thread_local_top_.scheduled_exception_;
602 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000603
604 Address pending_message_obj_address() {
605 return reinterpret_cast<Address>(&thread_local_top_.pending_message_obj_);
606 }
607
608 Address has_pending_message_address() {
609 return reinterpret_cast<Address>(&thread_local_top_.has_pending_message_);
610 }
611
612 Address pending_message_script_address() {
613 return reinterpret_cast<Address>(
614 &thread_local_top_.pending_message_script_);
615 }
616
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000617 MaybeObject* scheduled_exception() {
618 ASSERT(has_scheduled_exception());
619 return thread_local_top_.scheduled_exception_;
620 }
621 bool has_scheduled_exception() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000622 return thread_local_top_.scheduled_exception_ != heap_.the_hole_value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000623 }
624 void clear_scheduled_exception() {
625 thread_local_top_.scheduled_exception_ = heap_.the_hole_value();
626 }
627
628 bool IsExternallyCaught();
629
630 bool is_catchable_by_javascript(MaybeObject* exception) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000631 return (!exception->IsOutOfMemory()) &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000632 (exception != heap()->termination_exception());
633 }
634
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000635 // Serializer.
636 void PushToPartialSnapshotCache(Object* obj);
637
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000638 // JS execution stack (see frames.h).
639 static Address c_entry_fp(ThreadLocalTop* thread) {
640 return thread->c_entry_fp_;
641 }
642 static Address handler(ThreadLocalTop* thread) { return thread->handler_; }
643
644 inline Address* c_entry_fp_address() {
645 return &thread_local_top_.c_entry_fp_;
646 }
647 inline Address* handler_address() { return &thread_local_top_.handler_; }
648
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000649 // Bottom JS entry (see StackTracer::Trace in log.cc).
650 static Address js_entry_sp(ThreadLocalTop* thread) {
651 return thread->js_entry_sp_;
652 }
653 inline Address* js_entry_sp_address() {
654 return &thread_local_top_.js_entry_sp_;
655 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000656
657 // Generated code scratch locations.
658 void* formal_count_address() { return &thread_local_top_.formal_count_; }
659
660 // Returns the global object of the current context. It could be
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000661 // a builtin object, or a JS global object.
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000662 Handle<GlobalObject> global_object() {
663 return Handle<GlobalObject>(context()->global_object());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000664 }
665
666 // Returns the global proxy object of the current context.
667 Object* global_proxy() {
668 return context()->global_proxy();
669 }
670
671 Handle<JSBuiltinsObject> js_builtins_object() {
672 return Handle<JSBuiltinsObject>(thread_local_top_.context_->builtins());
673 }
674
675 static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
676 void FreeThreadResources() { thread_local_top_.Free(); }
677
678 // This method is called by the api after operations that may throw
679 // exceptions. If an exception was thrown and not handled by an external
680 // handler the exception is scheduled to be rethrown when we return to running
681 // JavaScript code. If an exception is scheduled true is returned.
682 bool OptionalRescheduleException(bool is_bottom_call);
683
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000684 class ExceptionScope {
685 public:
686 explicit ExceptionScope(Isolate* isolate) :
687 // Scope currently can only be used for regular exceptions, not
688 // failures like OOM or termination exception.
689 isolate_(isolate),
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000690 pending_exception_(isolate_->pending_exception()->ToObjectUnchecked(),
691 isolate_),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000692 catcher_(isolate_->catcher())
693 { }
694
695 ~ExceptionScope() {
696 isolate_->set_catcher(catcher_);
697 isolate_->set_pending_exception(*pending_exception_);
698 }
699
700 private:
701 Isolate* isolate_;
702 Handle<Object> pending_exception_;
703 v8::TryCatch* catcher_;
704 };
705
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000706 void SetCaptureStackTraceForUncaughtExceptions(
707 bool capture,
708 int frame_limit,
709 StackTrace::StackTraceOptions options);
710
711 // Tells whether the current context has experienced an out of memory
712 // exception.
713 bool is_out_of_memory();
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000714 bool ignore_out_of_memory() {
715 return thread_local_top_.ignore_out_of_memory_;
716 }
717 void set_ignore_out_of_memory(bool value) {
718 thread_local_top_.ignore_out_of_memory_ = value;
719 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000720
721 void PrintCurrentStackTrace(FILE* out);
722 void PrintStackTrace(FILE* out, char* thread_data);
723 void PrintStack(StringStream* accumulator);
724 void PrintStack();
725 Handle<String> StackTraceString();
jkummerow@chromium.org67255be2012-09-05 16:44:50 +0000726 NO_INLINE(void PushStackTraceAndDie(unsigned int magic,
727 Object* object,
728 Map* map,
729 unsigned int magic2));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000730 Handle<JSArray> CaptureCurrentStackTrace(
731 int frame_limit,
732 StackTrace::StackTraceOptions options);
733
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +0000734 Handle<JSArray> CaptureSimpleStackTrace(Handle<JSObject> error_object,
735 Handle<Object> caller,
736 int limit);
737 void CaptureAndSetDetailedStackTrace(Handle<JSObject> error_object);
jkummerow@chromium.orgab7dad42012-02-07 12:07:34 +0000738
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000739 // Returns if the top context may access the given global object. If
740 // the result is false, the pending exception is guaranteed to be
741 // set.
742 bool MayNamedAccess(JSObject* receiver,
743 Object* key,
744 v8::AccessType type);
745 bool MayIndexedAccess(JSObject* receiver,
746 uint32_t index,
747 v8::AccessType type);
748
749 void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback);
750 void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);
751
752 // Exception throwing support. The caller should use the result
753 // of Throw() as its return value.
754 Failure* Throw(Object* exception, MessageLocation* location = NULL);
755 // Re-throw an exception. This involves no error reporting since
756 // error reporting was handled when the exception was thrown
757 // originally.
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000758 Failure* ReThrow(MaybeObject* exception);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000759 void ScheduleThrow(Object* exception);
760 void ReportPendingMessages();
mmassi@chromium.org49a44672012-12-04 13:52:03 +0000761 // Return pending location if any or unfilled structure.
762 MessageLocation GetMessageLocation();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000763 Failure* ThrowIllegalOperation();
764
765 // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
766 Failure* PromoteScheduledException();
jkummerow@chromium.orgab7dad42012-02-07 12:07:34 +0000767 void DoThrow(Object* exception, MessageLocation* location);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000768 // Checks if exception should be reported and finds out if it's
769 // caught externally.
770 bool ShouldReportException(bool* can_be_caught_externally,
771 bool catchable_by_javascript);
772
773 // Attempts to compute the current source location, storing the
774 // result in the target out parameter.
775 void ComputeLocation(MessageLocation* target);
776
777 // Override command line flag.
778 void TraceException(bool flag);
779
780 // Out of resource exception helpers.
781 Failure* StackOverflow();
782 Failure* TerminateExecution();
783
784 // Administration
785 void Iterate(ObjectVisitor* v);
786 void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
787 char* Iterate(ObjectVisitor* v, char* t);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000788 void IterateThread(ThreadVisitor* v, char* t);
789
790
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000791 // Returns the current native and global context.
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000792 Handle<Context> native_context();
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000793 Handle<Context> global_context();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000794
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000795 // Returns the native context of the calling JavaScript code. That
796 // is, the native context of the top-most JavaScript frame.
797 Handle<Context> GetCallingNativeContext();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000798
799 void RegisterTryCatchHandler(v8::TryCatch* that);
800 void UnregisterTryCatchHandler(v8::TryCatch* that);
801
802 char* ArchiveThread(char* to);
803 char* RestoreThread(char* from);
804
805 static const char* const kStackOverflowMessage;
806
807 static const int kUC16AlphabetSize = 256; // See StringSearchBase.
808 static const int kBMMaxShift = 250; // See StringSearchBase.
809
810 // Accessors.
811#define GLOBAL_ACCESSOR(type, name, initialvalue) \
812 inline type name() const { \
813 ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \
814 return name##_; \
815 } \
816 inline void set_##name(type value) { \
817 ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \
818 name##_ = value; \
819 }
820 ISOLATE_INIT_LIST(GLOBAL_ACCESSOR)
821#undef GLOBAL_ACCESSOR
822
823#define GLOBAL_ARRAY_ACCESSOR(type, name, length) \
824 inline type* name() { \
825 ASSERT(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \
826 return &(name##_)[0]; \
827 }
828 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR)
829#undef GLOBAL_ARRAY_ACCESSOR
830
ulan@chromium.org09d7ab52013-02-25 15:50:35 +0000831#define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name) \
832 Handle<type> name() { \
833 return Handle<type>(context()->native_context()->name(), this); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000834 }
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000835 NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR)
836#undef NATIVE_CONTEXT_FIELD_ACCESSOR
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000837
838 Bootstrapper* bootstrapper() { return bootstrapper_; }
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000839 Counters* counters() {
840 // Call InitializeLoggingAndCounters() if logging is needed before
841 // the isolate is fully initialized.
842 ASSERT(counters_ != NULL);
843 return counters_;
844 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000845 CodeRange* code_range() { return code_range_; }
846 RuntimeProfiler* runtime_profiler() { return runtime_profiler_; }
847 CompilationCache* compilation_cache() { return compilation_cache_; }
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000848 Logger* logger() {
849 // Call InitializeLoggingAndCounters() if logging is needed before
850 // the isolate is fully initialized.
851 ASSERT(logger_ != NULL);
852 return logger_;
853 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000854 StackGuard* stack_guard() { return &stack_guard_; }
855 Heap* heap() { return &heap_; }
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000856 StatsTable* stats_table();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000857 StubCache* stub_cache() { return stub_cache_; }
858 DeoptimizerData* deoptimizer_data() { return deoptimizer_data_; }
859 ThreadLocalTop* thread_local_top() { return &thread_local_top_; }
860
861 TranscendentalCache* transcendental_cache() const {
862 return transcendental_cache_;
863 }
864
865 MemoryAllocator* memory_allocator() {
866 return memory_allocator_;
867 }
868
869 KeyedLookupCache* keyed_lookup_cache() {
870 return keyed_lookup_cache_;
871 }
872
873 ContextSlotCache* context_slot_cache() {
874 return context_slot_cache_;
875 }
876
877 DescriptorLookupCache* descriptor_lookup_cache() {
878 return descriptor_lookup_cache_;
879 }
880
881 v8::ImplementationUtilities::HandleScopeData* handle_scope_data() {
882 return &handle_scope_data_;
883 }
884 HandleScopeImplementer* handle_scope_implementer() {
885 ASSERT(handle_scope_implementer_);
886 return handle_scope_implementer_;
887 }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000888 Zone* runtime_zone() { return &runtime_zone_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000889
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +0000890 UnicodeCache* unicode_cache() {
891 return unicode_cache_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000892 }
893
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000894 InnerPointerToCodeCache* inner_pointer_to_code_cache() {
895 return inner_pointer_to_code_cache_;
896 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000897
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +0000898 ConsStringIteratorOp* write_iterator() { return write_iterator_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000899
900 GlobalHandles* global_handles() { return global_handles_; }
901
902 ThreadManager* thread_manager() { return thread_manager_; }
903
904 ContextSwitcher* context_switcher() { return context_switcher_; }
905
906 void set_context_switcher(ContextSwitcher* switcher) {
907 context_switcher_ = switcher;
908 }
909
910 StringTracker* string_tracker() { return string_tracker_; }
911
912 unibrow::Mapping<unibrow::Ecma262UnCanonicalize>* jsregexp_uncanonicalize() {
913 return &jsregexp_uncanonicalize_;
914 }
915
916 unibrow::Mapping<unibrow::CanonicalizationRange>* jsregexp_canonrange() {
917 return &jsregexp_canonrange_;
918 }
919
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +0000920 ConsStringIteratorOp* objects_string_compare_iterator_a() {
921 return &objects_string_compare_iterator_a_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000922 }
923
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +0000924 ConsStringIteratorOp* objects_string_compare_iterator_b() {
925 return &objects_string_compare_iterator_b_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000926 }
927
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +0000928 StaticResource<ConsStringIteratorOp>* objects_string_iterator() {
929 return &objects_string_iterator_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000930 }
931
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000932 RuntimeState* runtime_state() { return &runtime_state_; }
933
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000934 void set_fp_stubs_generated(bool value) {
935 fp_stubs_generated_ = value;
936 }
937
938 bool fp_stubs_generated() { return fp_stubs_generated_; }
939
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000940 Builtins* builtins() { return &builtins_; }
941
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000942 void NotifyExtensionInstalled() {
943 has_installed_extensions_ = true;
944 }
945
946 bool has_installed_extensions() { return has_installed_extensions_; }
947
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000948 unibrow::Mapping<unibrow::Ecma262Canonicalize>*
949 regexp_macro_assembler_canonicalize() {
950 return &regexp_macro_assembler_canonicalize_;
951 }
952
953 RegExpStack* regexp_stack() { return regexp_stack_; }
954
955 unibrow::Mapping<unibrow::Ecma262Canonicalize>*
956 interp_canonicalize_mapping() {
957 return &interp_canonicalize_mapping_;
958 }
959
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000960 void* PreallocatedStorageNew(size_t size);
961 void PreallocatedStorageDelete(void* p);
962 void PreallocatedStorageInit(size_t size);
963
964#ifdef ENABLE_DEBUGGER_SUPPORT
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000965 Debugger* debugger() {
966 if (!NoBarrier_Load(&debugger_initialized_)) InitializeDebugger();
967 return debugger_;
968 }
969 Debug* debug() {
970 if (!NoBarrier_Load(&debugger_initialized_)) InitializeDebugger();
971 return debug_;
972 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000973#endif
974
danno@chromium.org88aa0582012-03-23 15:11:57 +0000975 inline bool IsDebuggerActive();
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000976 inline bool DebuggerHasBreakPoints();
977
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000978#ifdef DEBUG
979 HistogramInfo* heap_histograms() { return heap_histograms_; }
980
981 JSObject::SpillInformation* js_spill_information() {
982 return &js_spill_information_;
983 }
984
985 int* code_kind_statistics() { return code_kind_statistics_; }
yangguo@chromium.org003650e2013-01-24 16:31:08 +0000986
987 bool allow_handle_deref() { return allow_handle_deref_; }
988 void set_allow_handle_deref(bool allow) { allow_handle_deref_ = allow; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000989#endif
990
lrn@chromium.org7516f052011-03-30 08:52:27 +0000991#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
992 defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000993 bool simulator_initialized() { return simulator_initialized_; }
994 void set_simulator_initialized(bool initialized) {
995 simulator_initialized_ = initialized;
996 }
997
998 HashMap* simulator_i_cache() { return simulator_i_cache_; }
999 void set_simulator_i_cache(HashMap* hash_map) {
1000 simulator_i_cache_ = hash_map;
1001 }
1002
1003 Redirection* simulator_redirection() {
1004 return simulator_redirection_;
1005 }
1006 void set_simulator_redirection(Redirection* redirection) {
1007 simulator_redirection_ = redirection;
1008 }
1009#endif
1010
1011 Factory* factory() { return reinterpret_cast<Factory*>(this); }
1012
mstarzinger@chromium.org15613d02012-05-23 12:04:37 +00001013 static const int kJSRegexpStaticOffsetsVectorSize = 128;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001014
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001015 Address external_callback() {
1016 return thread_local_top_.external_callback_;
1017 }
1018 void set_external_callback(Address callback) {
1019 thread_local_top_.external_callback_ = callback;
1020 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001021
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001022 StateTag current_vm_state() {
1023 return thread_local_top_.current_vm_state_;
1024 }
1025
1026 void SetCurrentVMState(StateTag state) {
1027 if (RuntimeProfiler::IsEnabled()) {
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00001028 // Make sure thread local top is initialized.
1029 ASSERT(thread_local_top_.isolate_ == this);
vitalyr@chromium.orgb803dc22011-04-07 21:57:01 +00001030 StateTag current_state = thread_local_top_.current_vm_state_;
1031 if (current_state != JS && state == JS) {
1032 // Non-JS -> JS transition.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001033 RuntimeProfiler::IsolateEnteredJS(this);
vitalyr@chromium.orgb803dc22011-04-07 21:57:01 +00001034 } else if (current_state == JS && state != JS) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001035 // JS -> non-JS transition.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001036 RuntimeProfiler::IsolateExitedJS(this);
vitalyr@chromium.orgb803dc22011-04-07 21:57:01 +00001037 } else {
1038 // Other types of state transitions are not interesting to the
1039 // runtime profiler, because they don't affect whether we're
1040 // in JS or not.
1041 ASSERT((current_state == JS) == (state == JS));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001042 }
1043 }
1044 thread_local_top_.current_vm_state_ = state;
1045 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001046
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001047 void SetData(void* data) { embedder_data_ = data; }
1048 void* GetData() { return embedder_data_; }
1049
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001050 LookupResult* top_lookup_result() {
1051 return thread_local_top_.top_lookup_result_;
1052 }
1053 void SetTopLookupResult(LookupResult* top) {
1054 thread_local_top_.top_lookup_result_ = top;
1055 }
1056
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001057 bool context_exit_happened() {
1058 return context_exit_happened_;
1059 }
1060 void set_context_exit_happened(bool context_exit_happened) {
1061 context_exit_happened_ = context_exit_happened;
1062 }
1063
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001064 double time_millis_since_init() {
1065 return OS::TimeCurrentMillis() - time_millis_at_init_;
1066 }
1067
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001068 DateCache* date_cache() {
1069 return date_cache_;
1070 }
1071
1072 void set_date_cache(DateCache* date_cache) {
1073 if (date_cache != date_cache_) {
1074 delete date_cache_;
1075 }
1076 date_cache_ = date_cache;
1077 }
1078
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001079 CodeStubInterfaceDescriptor*
1080 code_stub_interface_descriptor(int index);
1081
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001082 void IterateDeferredHandles(ObjectVisitor* visitor);
1083 void LinkDeferredHandles(DeferredHandles* deferred_handles);
1084 void UnlinkDeferredHandles(DeferredHandles* deferred_handles);
1085
1086 OptimizingCompilerThread* optimizing_compiler_thread() {
1087 return &optimizing_compiler_thread_;
1088 }
1089
yangguo@chromium.org46a2a512013-01-18 16:29:40 +00001090 // PreInits and returns a default isolate. Needed when a new thread tries
1091 // to create a Locker for the first time (the lock itself is in the isolate).
1092 // TODO(svenpanne) This method is on death row...
1093 static v8::Isolate* GetDefaultIsolateForLocking();
1094
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00001095 MarkingThread** marking_threads() {
1096 return marking_thread_;
1097 }
1098
1099 SweeperThread** sweeper_threads() {
1100 return sweeper_thread_;
1101 }
1102
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001103 private:
1104 Isolate();
1105
jkummerow@chromium.org1456e702012-03-30 08:38:13 +00001106 friend struct GlobalState;
1107 friend struct InitializeGlobalState;
1108
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00001109 enum State {
1110 UNINITIALIZED, // Some components may not have been allocated.
1111 INITIALIZED // All components are fully initialized.
1112 };
1113
1114 // These fields are accessed through the API, offsets must be kept in sync
1115 // with v8::internal::Internals (in include/v8.h) constants. This is also
1116 // verified in Isolate::Init() using runtime checks.
1117 State state_; // Will be padded to kApiPointerSize.
1118 void* embedder_data_;
1119 Heap heap_;
1120
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001121 // The per-process lock should be acquired before the ThreadDataTable is
1122 // modified.
1123 class ThreadDataTable {
1124 public:
1125 ThreadDataTable();
1126 ~ThreadDataTable();
1127
1128 PerIsolateThreadData* Lookup(Isolate* isolate, ThreadId thread_id);
1129 void Insert(PerIsolateThreadData* data);
1130 void Remove(Isolate* isolate, ThreadId thread_id);
1131 void Remove(PerIsolateThreadData* data);
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001132 void RemoveAllThreads(Isolate* isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001133
1134 private:
1135 PerIsolateThreadData* list_;
1136 };
1137
1138 // These items form a stack synchronously with threads Enter'ing and Exit'ing
1139 // the Isolate. The top of the stack points to a thread which is currently
1140 // running the Isolate. When the stack is empty, the Isolate is considered
1141 // not entered by any thread and can be Disposed.
1142 // If the same thread enters the Isolate more then once, the entry_count_
1143 // is incremented rather then a new item pushed to the stack.
1144 class EntryStackItem {
1145 public:
1146 EntryStackItem(PerIsolateThreadData* previous_thread_data,
1147 Isolate* previous_isolate,
1148 EntryStackItem* previous_item)
1149 : entry_count(1),
1150 previous_thread_data(previous_thread_data),
1151 previous_isolate(previous_isolate),
1152 previous_item(previous_item) { }
1153
1154 int entry_count;
1155 PerIsolateThreadData* previous_thread_data;
1156 Isolate* previous_isolate;
1157 EntryStackItem* previous_item;
1158
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001159 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001160 DISALLOW_COPY_AND_ASSIGN(EntryStackItem);
1161 };
1162
danno@chromium.org8c0a43f2012-04-03 08:37:53 +00001163 // This mutex protects highest_thread_id_, thread_data_table_ and
1164 // default_isolate_.
1165 static Mutex* process_wide_mutex_;
1166
1167 static Thread::LocalStorageKey per_isolate_thread_data_key_;
1168 static Thread::LocalStorageKey isolate_key_;
1169 static Thread::LocalStorageKey thread_id_key_;
1170 static Isolate* default_isolate_;
1171 static ThreadDataTable* thread_data_table_;
1172
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001173 void Deinit();
1174
1175 static void SetIsolateThreadLocals(Isolate* isolate,
1176 PerIsolateThreadData* data);
1177
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001178 // Allocate and insert PerIsolateThreadData into the ThreadDataTable
1179 // (regardless of whether such data already exists).
1180 PerIsolateThreadData* AllocatePerIsolateThreadData(ThreadId thread_id);
1181
1182 // Find the PerThread for this particular (isolate, thread) combination.
1183 // If one does not yet exist, allocate a new one.
1184 PerIsolateThreadData* FindOrAllocatePerThreadDataForThisThread();
1185
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001186 // Initializes the current thread to run this Isolate.
1187 // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
1188 // at the same time, this should be prevented using external locking.
1189 void Enter();
1190
1191 // Exits the current thread. The previosuly entered Isolate is restored
1192 // for the thread.
1193 // Not thread-safe. Multiple threads should not Enter/Exit the same isolate
1194 // at the same time, this should be prevented using external locking.
1195 void Exit();
1196
1197 void PreallocatedMemoryThreadStart();
1198 void PreallocatedMemoryThreadStop();
1199 void InitializeThreadLocal();
1200
1201 void PrintStackTrace(FILE* out, ThreadLocalTop* thread);
1202 void MarkCompactPrologue(bool is_compacting,
1203 ThreadLocalTop* archived_thread_data);
1204 void MarkCompactEpilogue(bool is_compacting,
1205 ThreadLocalTop* archived_thread_data);
1206
1207 void FillCache();
1208
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001209 void PropagatePendingExceptionToExternalTryCatch();
1210
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001211 void InitializeDebugger();
1212
jkummerow@chromium.orgab7dad42012-02-07 12:07:34 +00001213 // Traverse prototype chain to find out whether the object is derived from
1214 // the Error object.
1215 bool IsErrorObject(Handle<Object> obj);
1216
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +00001217 EntryStackItem* entry_stack_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001218 int stack_trace_nesting_level_;
1219 StringStream* incomplete_message_;
1220 // The preallocated memory thread singleton.
1221 PreallocatedMemoryThread* preallocated_memory_thread_;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001222 Address isolate_addresses_[kIsolateAddressCount + 1]; // NOLINT
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001223 NoAllocationStringAllocator* preallocated_message_space_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001224 Bootstrapper* bootstrapper_;
1225 RuntimeProfiler* runtime_profiler_;
1226 CompilationCache* compilation_cache_;
1227 Counters* counters_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001228 CodeRange* code_range_;
1229 Mutex* break_access_;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001230 Atomic32 debugger_initialized_;
1231 Mutex* debugger_access_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001232 Logger* logger_;
1233 StackGuard stack_guard_;
1234 StatsTable* stats_table_;
1235 StubCache* stub_cache_;
1236 DeoptimizerData* deoptimizer_data_;
1237 ThreadLocalTop thread_local_top_;
1238 bool capture_stack_trace_for_uncaught_exceptions_;
1239 int stack_trace_for_uncaught_exceptions_frame_limit_;
1240 StackTrace::StackTraceOptions stack_trace_for_uncaught_exceptions_options_;
1241 TranscendentalCache* transcendental_cache_;
1242 MemoryAllocator* memory_allocator_;
1243 KeyedLookupCache* keyed_lookup_cache_;
1244 ContextSlotCache* context_slot_cache_;
1245 DescriptorLookupCache* descriptor_lookup_cache_;
1246 v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
1247 HandleScopeImplementer* handle_scope_implementer_;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00001248 UnicodeCache* unicode_cache_;
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +00001249 Zone runtime_zone_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001250 PreallocatedStorage in_use_list_;
1251 PreallocatedStorage free_list_;
1252 bool preallocated_storage_preallocated_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001253 InnerPointerToCodeCache* inner_pointer_to_code_cache_;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001254 ConsStringIteratorOp* write_iterator_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001255 GlobalHandles* global_handles_;
1256 ContextSwitcher* context_switcher_;
1257 ThreadManager* thread_manager_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001258 RuntimeState runtime_state_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001259 bool fp_stubs_generated_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001260 Builtins builtins_;
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001261 bool has_installed_extensions_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001262 StringTracker* string_tracker_;
1263 unibrow::Mapping<unibrow::Ecma262UnCanonicalize> jsregexp_uncanonicalize_;
1264 unibrow::Mapping<unibrow::CanonicalizationRange> jsregexp_canonrange_;
yangguo@chromium.org4cd70b42013-01-04 08:57:54 +00001265 ConsStringIteratorOp objects_string_compare_iterator_a_;
1266 ConsStringIteratorOp objects_string_compare_iterator_b_;
1267 StaticResource<ConsStringIteratorOp> objects_string_iterator_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001268 unibrow::Mapping<unibrow::Ecma262Canonicalize>
1269 regexp_macro_assembler_canonicalize_;
1270 RegExpStack* regexp_stack_;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001271 DateCache* date_cache_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001272 unibrow::Mapping<unibrow::Ecma262Canonicalize> interp_canonicalize_mapping_;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +00001273 CodeStubInterfaceDescriptor* code_stub_interface_descriptors_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001274
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001275 // The garbage collector should be a little more aggressive when it knows
1276 // that a context was recently exited.
1277 bool context_exit_happened_;
1278
rossberg@chromium.org994edf62012-02-06 10:12:55 +00001279 // Time stamp at initialization.
1280 double time_millis_at_init_;
1281
lrn@chromium.org7516f052011-03-30 08:52:27 +00001282#if defined(V8_TARGET_ARCH_ARM) && !defined(__arm__) || \
1283 defined(V8_TARGET_ARCH_MIPS) && !defined(__mips__)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001284 bool simulator_initialized_;
1285 HashMap* simulator_i_cache_;
1286 Redirection* simulator_redirection_;
1287#endif
1288
1289#ifdef DEBUG
1290 // A static array of histogram info for each type.
1291 HistogramInfo heap_histograms_[LAST_TYPE + 1];
1292 JSObject::SpillInformation js_spill_information_;
1293 int code_kind_statistics_[Code::NUMBER_OF_KINDS];
yangguo@chromium.org003650e2013-01-24 16:31:08 +00001294
1295 bool allow_handle_deref_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001296#endif
1297
1298#ifdef ENABLE_DEBUGGER_SUPPORT
1299 Debugger* debugger_;
1300 Debug* debug_;
1301#endif
1302
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001303#define GLOBAL_BACKING_STORE(type, name, initialvalue) \
1304 type name##_;
1305 ISOLATE_INIT_LIST(GLOBAL_BACKING_STORE)
1306#undef GLOBAL_BACKING_STORE
1307
1308#define GLOBAL_ARRAY_BACKING_STORE(type, name, length) \
1309 type name##_[length];
1310 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_BACKING_STORE)
1311#undef GLOBAL_ARRAY_BACKING_STORE
1312
1313#ifdef DEBUG
1314 // This class is huge and has a number of fields controlled by
1315 // preprocessor defines. Make sure the offsets of these fields agree
1316 // between compilation units.
1317#define ISOLATE_FIELD_OFFSET(type, name, ignored) \
1318 static const intptr_t name##_debug_offset_;
1319 ISOLATE_INIT_LIST(ISOLATE_FIELD_OFFSET)
1320 ISOLATE_INIT_ARRAY_LIST(ISOLATE_FIELD_OFFSET)
1321#undef ISOLATE_FIELD_OFFSET
1322#endif
1323
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001324 DeferredHandles* deferred_handles_head_;
1325 OptimizingCompilerThread optimizing_compiler_thread_;
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00001326 MarkingThread** marking_thread_;
1327 SweeperThread** sweeper_thread_;
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001328
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001329 friend class ExecutionAccess;
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001330 friend class HandleScopeImplementer;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001331 friend class IsolateInitializer;
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00001332 friend class MarkingThread;
yangguo@chromium.org304cc332012-07-24 07:59:48 +00001333 friend class OptimizingCompilerThread;
mstarzinger@chromium.orge3b8d0f2013-02-01 09:06:41 +00001334 friend class SweeperThread;
lrn@chromium.org1c092762011-05-09 09:42:16 +00001335 friend class ThreadManager;
1336 friend class Simulator;
1337 friend class StackGuard;
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00001338 friend class ThreadId;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001339 friend class TestMemoryAllocatorScope;
mstarzinger@chromium.org068ea0a2013-01-30 09:39:44 +00001340 friend class TestCodeRangeScope;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001341 friend class v8::Isolate;
1342 friend class v8::Locker;
lrn@chromium.org1c092762011-05-09 09:42:16 +00001343 friend class v8::Unlocker;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001344
1345 DISALLOW_COPY_AND_ASSIGN(Isolate);
1346};
1347
1348
1349// If the GCC version is 4.1.x or 4.2.x an additional field is added to the
1350// class as a work around for a bug in the generated code found with these
1351// versions of GCC. See V8 issue 122 for details.
1352class SaveContext BASE_EMBEDDED {
1353 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001354 inline explicit SaveContext(Isolate* isolate);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001355
1356 ~SaveContext() {
1357 if (context_.is_null()) {
1358 Isolate* isolate = Isolate::Current();
1359 isolate->set_context(NULL);
1360 isolate->set_save_context(prev_);
1361 } else {
1362 Isolate* isolate = context_->GetIsolate();
1363 isolate->set_context(*context_);
1364 isolate->set_save_context(prev_);
1365 }
1366 }
1367
1368 Handle<Context> context() { return context_; }
1369 SaveContext* prev() { return prev_; }
1370
1371 // Returns true if this save context is below a given JavaScript frame.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001372 bool IsBelowFrame(JavaScriptFrame* frame) {
1373 return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001374 }
1375
1376 private:
1377 Handle<Context> context_;
1378#if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
1379 Handle<Context> dummy_;
1380#endif
1381 SaveContext* prev_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001382 Address c_entry_fp_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001383};
1384
1385
1386class AssertNoContextChange BASE_EMBEDDED {
1387#ifdef DEBUG
1388 public:
1389 AssertNoContextChange() :
1390 scope_(Isolate::Current()),
1391 context_(Isolate::Current()->context(), Isolate::Current()) {
1392 }
1393
1394 ~AssertNoContextChange() {
1395 ASSERT(Isolate::Current()->context() == *context_);
1396 }
1397
1398 private:
1399 HandleScope scope_;
1400 Handle<Context> context_;
1401#else
1402 public:
1403 AssertNoContextChange() { }
1404#endif
1405};
1406
1407
1408class ExecutionAccess BASE_EMBEDDED {
1409 public:
1410 explicit ExecutionAccess(Isolate* isolate) : isolate_(isolate) {
1411 Lock(isolate);
1412 }
1413 ~ExecutionAccess() { Unlock(isolate_); }
1414
1415 static void Lock(Isolate* isolate) { isolate->break_access_->Lock(); }
1416 static void Unlock(Isolate* isolate) { isolate->break_access_->Unlock(); }
1417
1418 static bool TryLock(Isolate* isolate) {
1419 return isolate->break_access_->TryLock();
1420 }
1421
1422 private:
1423 Isolate* isolate_;
1424};
1425
1426
1427// Support for checking for stack-overflows in C++ code.
1428class StackLimitCheck BASE_EMBEDDED {
1429 public:
1430 explicit StackLimitCheck(Isolate* isolate) : isolate_(isolate) { }
1431
1432 bool HasOverflowed() const {
1433 StackGuard* stack_guard = isolate_->stack_guard();
yangguo@chromium.orgeeb44b62012-11-13 13:56:09 +00001434 return (reinterpret_cast<uintptr_t>(this) < stack_guard->real_climit());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001435 }
1436 private:
1437 Isolate* isolate_;
1438};
1439
1440
1441// Support for temporarily postponing interrupts. When the outermost
1442// postpone scope is left the interrupts will be re-enabled and any
1443// interrupts that occurred while in the scope will be taken into
1444// account.
1445class PostponeInterruptsScope BASE_EMBEDDED {
1446 public:
1447 explicit PostponeInterruptsScope(Isolate* isolate)
1448 : stack_guard_(isolate->stack_guard()) {
1449 stack_guard_->thread_local_.postpone_interrupts_nesting_++;
1450 stack_guard_->DisableInterrupts();
1451 }
1452
1453 ~PostponeInterruptsScope() {
1454 if (--stack_guard_->thread_local_.postpone_interrupts_nesting_ == 0) {
1455 stack_guard_->EnableInterrupts();
1456 }
1457 }
1458 private:
1459 StackGuard* stack_guard_;
1460};
1461
1462
1463// Temporary macros for accessing current isolate and its subobjects.
1464// They provide better readability, especially when used a lot in the code.
1465#define HEAP (v8::internal::Isolate::Current()->heap())
1466#define FACTORY (v8::internal::Isolate::Current()->factory())
1467#define ISOLATE (v8::internal::Isolate::Current())
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001468#define LOGGER (v8::internal::Isolate::Current()->logger())
1469
1470
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001471// Tells whether the native context is marked with out of memory.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001472inline bool Context::has_out_of_memory() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001473 return native_context()->out_of_memory()->IsTrue();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001474}
1475
1476
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001477// Mark the native context with out of memory.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001478inline void Context::mark_out_of_memory() {
yangguo@chromium.org46839fb2012-08-28 09:06:19 +00001479 native_context()->set_out_of_memory(HEAP->true_value());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001480}
1481
1482
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001483} } // namespace v8::internal
1484
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001485#endif // V8_ISOLATE_H_