OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 13 matching lines...) Expand all Loading... |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #ifndef V8_ISOLATE_H_ | 28 #ifndef V8_ISOLATE_H_ |
29 #define V8_ISOLATE_H_ | 29 #define V8_ISOLATE_H_ |
30 | 30 |
31 // #define V8_USE_TLS_FOR_GLOBAL_ISOLATE | 31 // #define V8_USE_TLS_FOR_GLOBAL_ISOLATE |
32 | 32 |
33 #include "apiutils.h" | 33 #include "apiutils.h" |
| 34 #include "contexts.h" |
| 35 #include "execution.h" |
| 36 #include "frames-inl.h" |
| 37 #include "frames.h" |
| 38 #include "handles.h" |
34 #include "heap.h" | 39 #include "heap.h" |
35 #include "execution.h" | |
36 #include "zone.h" | 40 #include "zone.h" |
37 | 41 |
38 namespace v8 { | 42 namespace v8 { |
39 namespace internal { | 43 namespace internal { |
40 | 44 |
41 class Bootstrapper; | 45 class Bootstrapper; |
42 class CompilationCache; | 46 class CompilationCache; |
43 class ContextSlotCache; | 47 class ContextSlotCache; |
44 class CpuFeatures; | 48 class CpuFeatures; |
45 class Deserializer; | 49 class Deserializer; |
46 class HandleScopeImplementer; | 50 class HandleScopeImplementer; |
| 51 class NoAllocationStringAllocator; |
| 52 class PreallocatedMemoryThread; |
47 class SaveContext; | 53 class SaveContext; |
48 class StubCache; | 54 class StubCache; |
49 class ScannerCharacterClasses; | 55 class ScannerCharacterClasses; |
| 56 class ThreadVisitor; // Defined in v8threads.h |
| 57 |
| 58 #define RETURN_IF_SCHEDULED_EXCEPTION() \ |
| 59 if (Isolate::Current()->has_scheduled_exception()) \ |
| 60 return Isolate::Current()->PromoteScheduledException() |
| 61 |
| 62 #define ISOLATE_ADDRESS_LIST(C) \ |
| 63 C(handler_address) \ |
| 64 C(c_entry_fp_address) \ |
| 65 C(context_address) \ |
| 66 C(pending_exception_address) \ |
| 67 C(external_caught_exception_address) |
| 68 |
| 69 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 70 #define ISOLATE_ADDRESS_LIST_PROF(C) \ |
| 71 C(js_entry_sp_address) |
| 72 #else |
| 73 #define ISOLATE_ADDRESS_LIST_PROF(C) |
| 74 #endif |
| 75 |
50 | 76 |
51 class ThreadLocalTop BASE_EMBEDDED { | 77 class ThreadLocalTop BASE_EMBEDDED { |
52 public: | 78 public: |
53 // Initialize the thread data. | 79 // Initialize the thread data. |
54 void Initialize(); | 80 void Initialize(); |
55 | 81 |
56 // Get the top C++ try catch handler or NULL if none are registered. | 82 // Get the top C++ try catch handler or NULL if none are registered. |
57 // | 83 // |
58 // This method is not guarenteed to return an address that can be | 84 // This method is not guarenteed to return an address that can be |
59 // used for comparison with addresses into the JS stack. If such an | 85 // used for comparison with addresses into the JS stack. If such an |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 V(int, serialize_partial_snapshot_cache_length, 0) \ | 173 V(int, serialize_partial_snapshot_cache_length, 0) \ |
148 /* Assembler state. */ \ | 174 /* Assembler state. */ \ |
149 /* A previously allocated buffer of kMinimalBufferSize bytes, or NULL. */ \ | 175 /* A previously allocated buffer of kMinimalBufferSize bytes, or NULL. */ \ |
150 V(byte*, assembler_spare_buffer, NULL) \ | 176 V(byte*, assembler_spare_buffer, NULL) \ |
151 ISOLATE_PLATFORM_INIT_LIST(V) | 177 ISOLATE_PLATFORM_INIT_LIST(V) |
152 | 178 |
153 class Isolate { | 179 class Isolate { |
154 public: | 180 public: |
155 ~Isolate(); | 181 ~Isolate(); |
156 | 182 |
| 183 enum AddressId { |
| 184 #define C(name) k_##name, |
| 185 ISOLATE_ADDRESS_LIST(C) |
| 186 ISOLATE_ADDRESS_LIST_PROF(C) |
| 187 #undef C |
| 188 k_isolate_address_count |
| 189 }; |
| 190 |
157 // Returns the single global isolate. | 191 // Returns the single global isolate. |
158 static Isolate* Current() { | 192 static Isolate* Current() { |
159 #ifdef V8_USE_TLS_FOR_GLOBAL_ISOLATE | 193 #ifdef V8_USE_TLS_FOR_GLOBAL_ISOLATE |
160 Isolate* isolate = reinterpret_cast<Isolate*>( | 194 Isolate* isolate = reinterpret_cast<Isolate*>( |
161 Thread::GetThreadLocal(global_isolate_key_)); | 195 Thread::GetThreadLocal(global_isolate_key_)); |
162 if (isolate == NULL) { | 196 if (isolate == NULL) { |
163 isolate = InitThreadForGlobalIsolate(); | 197 isolate = InitThreadForGlobalIsolate(); |
164 ASSERT(isolate != NULL); | 198 ASSERT(isolate != NULL); |
165 } | 199 } |
166 return isolate; | 200 return isolate; |
167 #else | 201 #else |
168 ASSERT(global_isolate_ != NULL); | 202 ASSERT(global_isolate_ != NULL); |
169 return global_isolate_; | 203 return global_isolate_; |
170 #endif | 204 #endif |
171 } | 205 } |
172 | 206 |
173 #ifdef V8_USE_TLS_FOR_GLOBAL_ISOLATE | 207 #ifdef V8_USE_TLS_FOR_GLOBAL_ISOLATE |
174 static Isolate* InitThreadForGlobalIsolate(); | 208 static Isolate* InitThreadForGlobalIsolate(); |
175 #endif | 209 #endif |
176 | 210 |
| 211 // Destroy the global isolate and create a new one in its place. |
| 212 static void TearDownAndRecreateGlobalIsolate(); |
| 213 |
177 // Creates a new isolate (perhaps using a deserializer). Returns null | 214 // Creates a new isolate (perhaps using a deserializer). Returns null |
178 // on failure. | 215 // on failure. |
179 static Isolate* Create(Deserializer* des); | 216 static Isolate* Create(Deserializer* des); |
180 | 217 |
| 218 // Debug. |
| 219 // Mutex for serializing access to break control structures. |
| 220 Mutex* break_access() { return break_access_; } |
| 221 |
| 222 Address get_address_from_id(AddressId id); |
| 223 |
| 224 // Access to top context (where the current function object was created). |
| 225 Context* context() { return thread_local_top_.context_; } |
| 226 void set_context(Context* context) { |
| 227 thread_local_top_.context_ = context; |
| 228 } |
| 229 Context** context_address() { return &thread_local_top_.context_; } |
| 230 |
| 231 SaveContext* save_context() {return thread_local_top_.save_context_; } |
| 232 void set_save_context(SaveContext* save) { |
| 233 thread_local_top_.save_context_ = save; |
| 234 } |
| 235 |
| 236 // Access to current thread id. |
| 237 int thread_id() { return thread_local_top_.thread_id_; } |
| 238 void set_thread_id(int id) { thread_local_top_.thread_id_ = id; } |
| 239 |
| 240 // Interface to pending exception. |
| 241 Object* pending_exception() { |
| 242 ASSERT(has_pending_exception()); |
| 243 return thread_local_top_.pending_exception_; |
| 244 } |
| 245 bool external_caught_exception() { |
| 246 return thread_local_top_.external_caught_exception_; |
| 247 } |
| 248 void set_pending_exception(Object* exception) { |
| 249 thread_local_top_.pending_exception_ = exception; |
| 250 } |
| 251 void clear_pending_exception() { |
| 252 thread_local_top_.pending_exception_ = heap_.the_hole_value(); |
| 253 } |
| 254 Object** pending_exception_address() { |
| 255 return &thread_local_top_.pending_exception_; |
| 256 } |
| 257 bool has_pending_exception() { |
| 258 return !thread_local_top_.pending_exception_->IsTheHole(); |
| 259 } |
| 260 void clear_pending_message() { |
| 261 thread_local_top_.has_pending_message_ = false; |
| 262 thread_local_top_.pending_message_ = NULL; |
| 263 thread_local_top_.pending_message_obj_ = heap_.the_hole_value(); |
| 264 thread_local_top_.pending_message_script_ = NULL; |
| 265 } |
| 266 v8::TryCatch* try_catch_handler() { |
| 267 return thread_local_top_.TryCatchHandler(); |
| 268 } |
| 269 Address try_catch_handler_address() { |
| 270 return thread_local_top_.try_catch_handler_address(); |
| 271 } |
| 272 bool* external_caught_exception_address() { |
| 273 return &thread_local_top_.external_caught_exception_; |
| 274 } |
| 275 |
| 276 Object** scheduled_exception_address() { |
| 277 return &thread_local_top_.scheduled_exception_; |
| 278 } |
| 279 Object* scheduled_exception() { |
| 280 ASSERT(has_scheduled_exception()); |
| 281 return thread_local_top_.scheduled_exception_; |
| 282 } |
| 283 bool has_scheduled_exception() { |
| 284 return !thread_local_top_.scheduled_exception_->IsTheHole(); |
| 285 } |
| 286 void clear_scheduled_exception() { |
| 287 thread_local_top_.scheduled_exception_ = heap_.the_hole_value(); |
| 288 } |
| 289 |
| 290 void setup_external_caught() { |
| 291 thread_local_top_.external_caught_exception_ = |
| 292 has_pending_exception() && |
| 293 (thread_local_top_.catcher_ != NULL) && |
| 294 (try_catch_handler() == thread_local_top_.catcher_); |
| 295 } |
| 296 |
| 297 // JS execution stack (see frames.h). |
| 298 static Address c_entry_fp(ThreadLocalTop* thread) { |
| 299 return thread->c_entry_fp_; |
| 300 } |
| 301 static Address handler(ThreadLocalTop* thread) { return thread->handler_; } |
| 302 |
| 303 inline Address* c_entry_fp_address() { |
| 304 return &thread_local_top_.c_entry_fp_; |
| 305 } |
| 306 inline Address* handler_address() { return &thread_local_top_.handler_; } |
| 307 |
| 308 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 309 // Bottom JS entry (see StackTracer::Trace in log.cc). |
| 310 static Address js_entry_sp(ThreadLocalTop* thread) { |
| 311 return thread->js_entry_sp_; |
| 312 } |
| 313 inline Address* js_entry_sp_address() { |
| 314 return &thread_local_top_.js_entry_sp_; |
| 315 } |
| 316 #endif |
| 317 |
| 318 // Generated code scratch locations. |
| 319 void* formal_count_address() { return &thread_local_top_.formal_count_; } |
| 320 |
| 321 // Returns the global object of the current context. It could be |
| 322 // a builtin object, or a js global object. |
| 323 Handle<GlobalObject> global() { |
| 324 return Handle<GlobalObject>(context()->global()); |
| 325 } |
| 326 |
| 327 // Returns the global proxy object of the current context. |
| 328 Object* global_proxy() { |
| 329 return context()->global_proxy(); |
| 330 } |
| 331 |
| 332 Handle<JSBuiltinsObject> builtins() { |
| 333 return Handle<JSBuiltinsObject>(thread_local_top_.context_->builtins()); |
| 334 } |
| 335 |
| 336 static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); } |
| 337 void FreeThreadResources() { thread_local_top_.Free(); } |
| 338 |
| 339 // This method is called by the api after operations that may throw |
| 340 // exceptions. If an exception was thrown and not handled by an external |
| 341 // handler the exception is scheduled to be rethrown when we return to running |
| 342 // JavaScript code. If an exception is scheduled true is returned. |
| 343 bool OptionalRescheduleException(bool is_bottom_call); |
| 344 |
| 345 |
| 346 // Tells whether the current context has experienced an out of memory |
| 347 // exception. |
| 348 bool is_out_of_memory(); |
| 349 |
| 350 |
| 351 void MarkCompactPrologue(bool is_compacting); |
| 352 void MarkCompactEpilogue(bool is_compacting); |
| 353 void MarkCompactPrologue(bool is_compacting, |
| 354 char* archived_thread_data); |
| 355 void MarkCompactEpilogue(bool is_compacting, |
| 356 char* archived_thread_data); |
| 357 void PrintCurrentStackTrace(FILE* out); |
| 358 void PrintStackTrace(FILE* out, char* thread_data); |
| 359 void PrintStack(StringStream* accumulator); |
| 360 void PrintStack(); |
| 361 Handle<String> StackTraceString(); |
| 362 Local<StackTrace> CaptureCurrentStackTrace( |
| 363 int frame_limit, |
| 364 StackTrace::StackTraceOptions options); |
| 365 |
| 366 // Returns if the top context may access the given global object. If |
| 367 // the result is false, the pending exception is guaranteed to be |
| 368 // set. |
| 369 bool MayNamedAccess(JSObject* receiver, |
| 370 Object* key, |
| 371 v8::AccessType type); |
| 372 bool MayIndexedAccess(JSObject* receiver, |
| 373 uint32_t index, |
| 374 v8::AccessType type); |
| 375 |
| 376 void SetFailedAccessCheckCallback(v8::FailedAccessCheckCallback callback); |
| 377 void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type); |
| 378 |
| 379 // Exception throwing support. The caller should use the result |
| 380 // of Throw() as its return value. |
| 381 Failure* Throw(Object* exception, MessageLocation* location = NULL); |
| 382 // Re-throw an exception. This involves no error reporting since |
| 383 // error reporting was handled when the exception was thrown |
| 384 // originally. |
| 385 Failure* ReThrow(Object* exception, MessageLocation* location = NULL); |
| 386 void ScheduleThrow(Object* exception); |
| 387 void ReportPendingMessages(); |
| 388 Failure* ThrowIllegalOperation(); |
| 389 |
| 390 // Promote a scheduled exception to pending. Asserts has_scheduled_exception. |
| 391 Object* PromoteScheduledException(); |
| 392 void DoThrow(Object* exception, |
| 393 MessageLocation* location, |
| 394 const char* message); |
| 395 bool ShouldReturnException(bool* is_caught_externally, |
| 396 bool catchable_by_javascript); |
| 397 void ReportUncaughtException(Handle<Object> exception, |
| 398 MessageLocation* location, |
| 399 Handle<String> stack_trace); |
| 400 |
| 401 // Attempts to compute the current source location, storing the |
| 402 // result in the target out parameter. |
| 403 void ComputeLocation(MessageLocation* target); |
| 404 |
| 405 // Override command line flag. |
| 406 void TraceException(bool flag); |
| 407 |
| 408 // Out of resource exception helpers. |
| 409 Failure* StackOverflow(); |
| 410 Failure* TerminateExecution(); |
| 411 |
| 412 // Administration |
| 413 void Iterate(ObjectVisitor* v); |
| 414 void Iterate(ObjectVisitor* v, ThreadLocalTop* t); |
| 415 char* Iterate(ObjectVisitor* v, char* t); |
| 416 void IterateThread(ThreadVisitor* v); |
| 417 void IterateThread(ThreadVisitor* v, char* t); |
| 418 |
| 419 |
| 420 // Returns the current global context. |
| 421 Handle<Context> global_context(); |
| 422 |
| 423 // Returns the global context of the calling JavaScript code. That |
| 424 // is, the global context of the top-most JavaScript frame. |
| 425 Handle<Context> GetCallingGlobalContext(); |
| 426 |
| 427 void RegisterTryCatchHandler(v8::TryCatch* that); |
| 428 void UnregisterTryCatchHandler(v8::TryCatch* that); |
| 429 |
| 430 char* ArchiveThread(char* to); |
| 431 char* RestoreThread(char* from); |
| 432 |
| 433 static const char* kStackOverflowMessage; |
| 434 |
| 435 // Accessors. |
181 #define GLOBAL_ACCESSOR(type, name, initialvalue) \ | 436 #define GLOBAL_ACCESSOR(type, name, initialvalue) \ |
182 type name() const { return name##_; } \ | 437 type name() const { return name##_; } \ |
183 void set_##name(type value) { name##_ = value; } | 438 void set_##name(type value) { name##_ = value; } |
184 ISOLATE_INIT_LIST(GLOBAL_ACCESSOR) | 439 ISOLATE_INIT_LIST(GLOBAL_ACCESSOR) |
185 #undef GLOBAL_ACCESSOR | 440 #undef GLOBAL_ACCESSOR |
186 | 441 |
187 #define GLOBAL_ARRAY_ACCESSOR(type, name, length) \ | 442 #define GLOBAL_ARRAY_ACCESSOR(type, name, length) \ |
188 type* name() { return &(name##_[0]); } | 443 type* name() { return &(name##_[0]); } |
189 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR) | 444 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR) |
190 #undef GLOBAL_ARRAY_ACCESSOR | 445 #undef GLOBAL_ARRAY_ACCESSOR |
191 | 446 |
192 // Debug. | 447 #define GLOBAL_CONTEXT_FIELD_ACCESSOR(index, type, name) \ |
193 // Mutex for serializing access to break control structures. | 448 Handle<type> name() { \ |
194 Mutex* break_access() { return break_access_; } | 449 return Handle<type>(context()->global_context()->name()); \ |
| 450 } |
| 451 GLOBAL_CONTEXT_FIELDS(GLOBAL_CONTEXT_FIELD_ACCESSOR) |
| 452 #undef GLOBAL_CONTEXT_FIELD_ACCESSOR |
195 | 453 |
196 // Accessors. | |
197 Bootstrapper* bootstrapper() { return bootstrapper_; } | 454 Bootstrapper* bootstrapper() { return bootstrapper_; } |
198 CpuFeatures* cpu_features() { return cpu_features_; } | 455 CpuFeatures* cpu_features() { return cpu_features_; } |
199 CompilationCache* compilation_cache() { return compilation_cache_; } | 456 CompilationCache* compilation_cache() { return compilation_cache_; } |
200 StackGuard* stack_guard() { return &stack_guard_; } | 457 StackGuard* stack_guard() { return &stack_guard_; } |
201 Heap* heap() { return &heap_; } | 458 Heap* heap() { return &heap_; } |
202 StubCache* stub_cache() { return stub_cache_; } | 459 StubCache* stub_cache() { return stub_cache_; } |
203 ThreadLocalTop* thread_local_top() { return &thread_local_top_; } | 460 ThreadLocalTop* thread_local_top() { return &thread_local_top_; } |
204 | 461 |
205 TranscendentalCache* transcendental_cache() const { | 462 TranscendentalCache* transcendental_cache() const { |
206 return transcendental_cache_; | 463 return transcendental_cache_; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 bool Init(Deserializer* des); | 512 bool Init(Deserializer* des); |
256 | 513 |
257 enum State { | 514 enum State { |
258 UNINITIALIZED, // Some components may not have been allocated. | 515 UNINITIALIZED, // Some components may not have been allocated. |
259 PREINITIALIZED, // Components have been allocated but not initialized. | 516 PREINITIALIZED, // Components have been allocated but not initialized. |
260 INITIALIZED // All components are fully initialized. | 517 INITIALIZED // All components are fully initialized. |
261 }; | 518 }; |
262 | 519 |
263 State state_; | 520 State state_; |
264 | 521 |
| 522 void PreallocatedMemoryThreadStart(); |
| 523 void PreallocatedMemoryThreadStop(); |
| 524 void InitializeThreadLocal(); |
| 525 |
| 526 void PrintStackTrace(FILE* out, ThreadLocalTop* thread); |
| 527 void MarkCompactPrologue(bool is_compacting, |
| 528 ThreadLocalTop* archived_thread_data); |
| 529 void MarkCompactEpilogue(bool is_compacting, |
| 530 ThreadLocalTop* archived_thread_data); |
| 531 |
| 532 void FillCache(); |
| 533 |
| 534 int stack_trace_nesting_level_; |
| 535 StringStream* incomplete_message_; |
| 536 // The preallocated memory thread singleton. |
| 537 PreallocatedMemoryThread* preallocated_memory_thread_; |
| 538 Address isolate_addresses_[k_isolate_address_count + 1]; |
| 539 NoAllocationStringAllocator* preallocated_message_space_; |
| 540 |
265 Bootstrapper* bootstrapper_; | 541 Bootstrapper* bootstrapper_; |
266 CompilationCache* compilation_cache_; | 542 CompilationCache* compilation_cache_; |
267 CpuFeatures* cpu_features_; | 543 CpuFeatures* cpu_features_; |
268 Mutex* break_access_; | 544 Mutex* break_access_; |
269 Heap heap_; | 545 Heap heap_; |
270 StackGuard stack_guard_; | 546 StackGuard stack_guard_; |
271 StubCache* stub_cache_; | 547 StubCache* stub_cache_; |
272 ThreadLocalTop thread_local_top_; | 548 ThreadLocalTop thread_local_top_; |
273 TranscendentalCache* transcendental_cache_; | 549 TranscendentalCache* transcendental_cache_; |
274 KeyedLookupCache* keyed_lookup_cache_; | 550 KeyedLookupCache* keyed_lookup_cache_; |
(...skipping 13 matching lines...) Expand all Loading... |
288 type name##_[length]; | 564 type name##_[length]; |
289 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_BACKING_STORE) | 565 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_BACKING_STORE) |
290 #undef GLOBAL_ARRAY_BACKING_STORE | 566 #undef GLOBAL_ARRAY_BACKING_STORE |
291 | 567 |
292 friend class IsolateInitializer; | 568 friend class IsolateInitializer; |
293 | 569 |
294 DISALLOW_COPY_AND_ASSIGN(Isolate); | 570 DISALLOW_COPY_AND_ASSIGN(Isolate); |
295 }; | 571 }; |
296 | 572 |
297 | 573 |
| 574 // If the GCC version is 4.1.x or 4.2.x an additional field is added to the |
| 575 // class as a work around for a bug in the generated code found with these |
| 576 // versions of GCC. See V8 issue 122 for details. |
| 577 class SaveContext BASE_EMBEDDED { |
| 578 public: |
| 579 SaveContext() |
| 580 : context_(Isolate::Current()->context()), |
| 581 #if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300 |
| 582 dummy_(Isolate::Current()->context()), |
| 583 #endif |
| 584 prev_(Isolate::Current()->save_context()) { |
| 585 Isolate::Current()->set_save_context(this); |
| 586 |
| 587 // If there is no JS frame under the current C frame, use the value 0. |
| 588 JavaScriptFrameIterator it; |
| 589 js_sp_ = it.done() ? 0 : it.frame()->sp(); |
| 590 } |
| 591 |
| 592 ~SaveContext() { |
| 593 Isolate::Current()->set_context(*context_); |
| 594 Isolate::Current()->set_save_context(prev_); |
| 595 } |
| 596 |
| 597 Handle<Context> context() { return context_; } |
| 598 SaveContext* prev() { return prev_; } |
| 599 |
| 600 // Returns true if this save context is below a given JavaScript frame. |
| 601 bool below(JavaScriptFrame* frame) { |
| 602 return (js_sp_ == 0) || (frame->sp() < js_sp_); |
| 603 } |
| 604 |
| 605 private: |
| 606 Handle<Context> context_; |
| 607 #if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300 |
| 608 Handle<Context> dummy_; |
| 609 #endif |
| 610 SaveContext* prev_; |
| 611 Address js_sp_; // The top JS frame's sp when saving context. |
| 612 }; |
| 613 |
| 614 |
| 615 class AssertNoContextChange BASE_EMBEDDED { |
| 616 #ifdef DEBUG |
| 617 public: |
| 618 AssertNoContextChange() : |
| 619 context_(Isolate::Current()->context()) { |
| 620 } |
| 621 |
| 622 ~AssertNoContextChange() { |
| 623 ASSERT(Isolate::Current()->context() == *context_); |
| 624 } |
| 625 |
| 626 private: |
| 627 HandleScope scope_; |
| 628 Handle<Context> context_; |
| 629 #else |
| 630 public: |
| 631 AssertNoContextChange() { } |
| 632 #endif |
| 633 }; |
| 634 |
| 635 |
| 636 class ExecutionAccess BASE_EMBEDDED { |
| 637 public: |
| 638 ExecutionAccess(); |
| 639 ~ExecutionAccess(); |
| 640 }; |
| 641 |
| 642 |
298 // Support for checking for stack-overflows in C++ code. | 643 // Support for checking for stack-overflows in C++ code. |
299 class StackLimitCheck BASE_EMBEDDED { | 644 class StackLimitCheck BASE_EMBEDDED { |
300 public: | 645 public: |
301 bool HasOverflowed() const { | 646 bool HasOverflowed() const { |
302 StackGuard* stack_guard = Isolate::Current()->stack_guard(); | 647 StackGuard* stack_guard = Isolate::Current()->stack_guard(); |
303 // Stack has overflowed in C++ code only if stack pointer exceeds the C++ | 648 // Stack has overflowed in C++ code only if stack pointer exceeds the C++ |
304 // stack guard and the limits are not set to interrupt values. | 649 // stack guard and the limits are not set to interrupt values. |
305 // TODO(214): Stack overflows are ignored if a interrupt is pending. This | 650 // TODO(214): Stack overflows are ignored if a interrupt is pending. This |
306 // code should probably always use the initial C++ limit. | 651 // code should probably always use the initial C++ limit. |
307 return (reinterpret_cast<uintptr_t>(this) < stack_guard->climit()) && | 652 return (reinterpret_cast<uintptr_t>(this) < stack_guard->climit()) && |
(...skipping 21 matching lines...) Expand all Loading... |
329 } | 674 } |
330 } | 675 } |
331 }; | 676 }; |
332 | 677 |
333 | 678 |
334 // Temporary macros for accessing fields off the global isolate. Define these | 679 // Temporary macros for accessing fields off the global isolate. Define these |
335 // when reformatting code would become burdensome. | 680 // when reformatting code would become burdensome. |
336 #define HEAP (v8::internal::Isolate::Current()->heap()) | 681 #define HEAP (v8::internal::Isolate::Current()->heap()) |
337 #define ZONE (v8::internal::Isolate::Current()->zone()) | 682 #define ZONE (v8::internal::Isolate::Current()->zone()) |
338 | 683 |
| 684 // Tells whether the global context is marked with out of memory. |
| 685 inline bool Context::has_out_of_memory() { |
| 686 return global_context()->out_of_memory() == HEAP->true_value(); |
| 687 } |
| 688 |
| 689 // Mark the global context with out of memory. |
| 690 inline void Context::mark_out_of_memory() { |
| 691 global_context()->set_out_of_memory(HEAP->true_value()); |
| 692 } |
339 | 693 |
340 // Temporary macro to be used to flag definitions that are indeed static | 694 // Temporary macro to be used to flag definitions that are indeed static |
341 // and not per-isolate. (It would be great to be able to grep for [static]!) | 695 // and not per-isolate. (It would be great to be able to grep for [static]!) |
342 #define RLYSTC static | 696 #define RLYSTC static |
343 | 697 |
344 | 698 |
345 // Temporary macro to be used to flag classes that should be static. | 699 // Temporary macro to be used to flag classes that should be static. |
346 #define STATIC_CLASS class | 700 #define STATIC_CLASS class |
347 | 701 |
348 | 702 |
349 // Temporary macro to be used to flag classes that are completely converted | 703 // Temporary macro to be used to flag classes that are completely converted |
350 // to be isolate-friendly. Their mix of static/nonstatic methods/fields is | 704 // to be isolate-friendly. Their mix of static/nonstatic methods/fields is |
351 // correct. | 705 // correct. |
352 #define ISOLATED_CLASS class | 706 #define ISOLATED_CLASS class |
353 | 707 |
354 } } // namespace v8::internal | 708 } } // namespace v8::internal |
355 | 709 |
| 710 |
356 #endif // V8_ISOLATE_H_ | 711 #endif // V8_ISOLATE_H_ |
OLD | NEW |