OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_ISOLATE_H_ | 5 #ifndef V8_ISOLATE_H_ |
6 #define V8_ISOLATE_H_ | 6 #define V8_ISOLATE_H_ |
7 | 7 |
8 #include <queue> | 8 #include <queue> |
9 #include <set> | 9 #include <set> |
10 | 10 |
(...skipping 526 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
537 | 537 |
538 static base::Thread::LocalStorageKey per_isolate_thread_data_key(); | 538 static base::Thread::LocalStorageKey per_isolate_thread_data_key(); |
539 | 539 |
540 // Mutex for serializing access to break control structures. | 540 // Mutex for serializing access to break control structures. |
541 base::RecursiveMutex* break_access() { return &break_access_; } | 541 base::RecursiveMutex* break_access() { return &break_access_; } |
542 | 542 |
543 Address get_address_from_id(AddressId id); | 543 Address get_address_from_id(AddressId id); |
544 | 544 |
545 // Access to top context (where the current function object was created). | 545 // Access to top context (where the current function object was created). |
546 Context* context() { return thread_local_top_.context_; } | 546 Context* context() { return thread_local_top_.context_; } |
547 void set_context(Context* context) { | 547 inline void set_context(Context* context); |
548 DCHECK(context == NULL || context->IsContext()); | |
549 thread_local_top_.context_ = context; | |
550 } | |
551 Context** context_address() { return &thread_local_top_.context_; } | 548 Context** context_address() { return &thread_local_top_.context_; } |
552 | 549 |
553 THREAD_LOCAL_TOP_ACCESSOR(SaveContext*, save_context) | 550 THREAD_LOCAL_TOP_ACCESSOR(SaveContext*, save_context) |
554 | 551 |
555 // Access to current thread id. | 552 // Access to current thread id. |
556 THREAD_LOCAL_TOP_ACCESSOR(ThreadId, thread_id) | 553 THREAD_LOCAL_TOP_ACCESSOR(ThreadId, thread_id) |
557 | 554 |
558 // Interface to pending exception. | 555 // Interface to pending exception. |
559 Object* pending_exception() { | 556 inline Object* pending_exception(); |
560 DCHECK(has_pending_exception()); | 557 inline void set_pending_exception(Object* exception_obj); |
561 DCHECK(!thread_local_top_.pending_exception_->IsException()); | 558 inline void clear_pending_exception(); |
562 return thread_local_top_.pending_exception_; | |
563 } | |
564 | |
565 void set_pending_exception(Object* exception_obj) { | |
566 DCHECK(!exception_obj->IsException()); | |
567 thread_local_top_.pending_exception_ = exception_obj; | |
568 } | |
569 | |
570 void clear_pending_exception() { | |
571 DCHECK(!thread_local_top_.pending_exception_->IsException()); | |
572 thread_local_top_.pending_exception_ = heap_.the_hole_value(); | |
573 } | |
574 | 559 |
575 THREAD_LOCAL_TOP_ADDRESS(Object*, pending_exception) | 560 THREAD_LOCAL_TOP_ADDRESS(Object*, pending_exception) |
576 | 561 |
577 bool has_pending_exception() { | 562 inline bool has_pending_exception(); |
578 DCHECK(!thread_local_top_.pending_exception_->IsException()); | |
579 return !thread_local_top_.pending_exception_->IsTheHole(); | |
580 } | |
581 | 563 |
582 THREAD_LOCAL_TOP_ADDRESS(Context*, pending_handler_context) | 564 THREAD_LOCAL_TOP_ADDRESS(Context*, pending_handler_context) |
583 THREAD_LOCAL_TOP_ADDRESS(Code*, pending_handler_code) | 565 THREAD_LOCAL_TOP_ADDRESS(Code*, pending_handler_code) |
584 THREAD_LOCAL_TOP_ADDRESS(intptr_t, pending_handler_offset) | 566 THREAD_LOCAL_TOP_ADDRESS(intptr_t, pending_handler_offset) |
585 THREAD_LOCAL_TOP_ADDRESS(Address, pending_handler_fp) | 567 THREAD_LOCAL_TOP_ADDRESS(Address, pending_handler_fp) |
586 THREAD_LOCAL_TOP_ADDRESS(Address, pending_handler_sp) | 568 THREAD_LOCAL_TOP_ADDRESS(Address, pending_handler_sp) |
587 | 569 |
588 THREAD_LOCAL_TOP_ACCESSOR(bool, external_caught_exception) | 570 THREAD_LOCAL_TOP_ACCESSOR(bool, external_caught_exception) |
589 | 571 |
590 void clear_pending_message() { | |
591 thread_local_top_.pending_message_obj_ = heap_.the_hole_value(); | |
592 } | |
593 v8::TryCatch* try_catch_handler() { | 572 v8::TryCatch* try_catch_handler() { |
594 return thread_local_top_.try_catch_handler(); | 573 return thread_local_top_.try_catch_handler(); |
595 } | 574 } |
596 bool* external_caught_exception_address() { | 575 bool* external_caught_exception_address() { |
597 return &thread_local_top_.external_caught_exception_; | 576 return &thread_local_top_.external_caught_exception_; |
598 } | 577 } |
599 | 578 |
600 THREAD_LOCAL_TOP_ADDRESS(Object*, scheduled_exception) | 579 THREAD_LOCAL_TOP_ADDRESS(Object*, scheduled_exception) |
601 | 580 |
| 581 inline void clear_pending_message(); |
602 Address pending_message_obj_address() { | 582 Address pending_message_obj_address() { |
603 return reinterpret_cast<Address>(&thread_local_top_.pending_message_obj_); | 583 return reinterpret_cast<Address>(&thread_local_top_.pending_message_obj_); |
604 } | 584 } |
605 | 585 |
606 Object* scheduled_exception() { | 586 inline Object* scheduled_exception(); |
607 DCHECK(has_scheduled_exception()); | 587 inline bool has_scheduled_exception(); |
608 DCHECK(!thread_local_top_.scheduled_exception_->IsException()); | 588 inline void clear_scheduled_exception(); |
609 return thread_local_top_.scheduled_exception_; | |
610 } | |
611 bool has_scheduled_exception() { | |
612 DCHECK(!thread_local_top_.scheduled_exception_->IsException()); | |
613 return thread_local_top_.scheduled_exception_ != heap_.the_hole_value(); | |
614 } | |
615 void clear_scheduled_exception() { | |
616 DCHECK(!thread_local_top_.scheduled_exception_->IsException()); | |
617 thread_local_top_.scheduled_exception_ = heap_.the_hole_value(); | |
618 } | |
619 | 589 |
620 bool IsJavaScriptHandlerOnTop(Object* exception); | 590 bool IsJavaScriptHandlerOnTop(Object* exception); |
621 bool IsExternalHandlerOnTop(Object* exception); | 591 bool IsExternalHandlerOnTop(Object* exception); |
622 | 592 |
623 bool is_catchable_by_javascript(Object* exception) { | 593 inline bool is_catchable_by_javascript(Object* exception); |
624 return exception != heap()->termination_exception(); | |
625 } | |
626 | 594 |
627 // JS execution stack (see frames.h). | 595 // JS execution stack (see frames.h). |
628 static Address c_entry_fp(ThreadLocalTop* thread) { | 596 static Address c_entry_fp(ThreadLocalTop* thread) { |
629 return thread->c_entry_fp_; | 597 return thread->c_entry_fp_; |
630 } | 598 } |
631 static Address handler(ThreadLocalTop* thread) { return thread->handler_; } | 599 static Address handler(ThreadLocalTop* thread) { return thread->handler_; } |
632 Address c_function() { return thread_local_top_.c_function_; } | 600 Address c_function() { return thread_local_top_.c_function_; } |
633 | 601 |
634 inline Address* c_entry_fp_address() { | 602 inline Address* c_entry_fp_address() { |
635 return &thread_local_top_.c_entry_fp_; | 603 return &thread_local_top_.c_entry_fp_; |
636 } | 604 } |
637 inline Address* handler_address() { return &thread_local_top_.handler_; } | 605 inline Address* handler_address() { return &thread_local_top_.handler_; } |
638 inline Address* c_function_address() { | 606 inline Address* c_function_address() { |
639 return &thread_local_top_.c_function_; | 607 return &thread_local_top_.c_function_; |
640 } | 608 } |
641 | 609 |
642 // Bottom JS entry. | 610 // Bottom JS entry. |
643 Address js_entry_sp() { | 611 Address js_entry_sp() { |
644 return thread_local_top_.js_entry_sp_; | 612 return thread_local_top_.js_entry_sp_; |
645 } | 613 } |
646 inline Address* js_entry_sp_address() { | 614 inline Address* js_entry_sp_address() { |
647 return &thread_local_top_.js_entry_sp_; | 615 return &thread_local_top_.js_entry_sp_; |
648 } | 616 } |
649 | 617 |
650 // Returns the global object of the current context. It could be | 618 // Returns the global object of the current context. It could be |
651 // a builtin object, or a JS global object. | 619 // a builtin object, or a JS global object. |
652 Handle<GlobalObject> global_object() { | 620 inline Handle<GlobalObject> global_object(); |
653 return Handle<GlobalObject>(context()->global_object()); | |
654 } | |
655 | 621 |
656 // Returns the global proxy object of the current context. | 622 // Returns the global proxy object of the current context. |
657 JSObject* global_proxy() { | 623 JSObject* global_proxy() { |
658 return context()->global_proxy(); | 624 return context()->global_proxy(); |
659 } | 625 } |
660 | 626 |
661 static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); } | 627 static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); } |
662 void FreeThreadResources() { thread_local_top_.Free(); } | 628 void FreeThreadResources() { thread_local_top_.Free(); } |
663 | 629 |
664 // This method is called by the api after operations that may throw | 630 // This method is called by the api after operations that may throw |
665 // exceptions. If an exception was thrown and not handled by an external | 631 // exceptions. If an exception was thrown and not handled by an external |
666 // handler the exception is scheduled to be rethrown when we return to running | 632 // handler the exception is scheduled to be rethrown when we return to running |
667 // JavaScript code. If an exception is scheduled true is returned. | 633 // JavaScript code. If an exception is scheduled true is returned. |
668 bool OptionalRescheduleException(bool is_bottom_call); | 634 bool OptionalRescheduleException(bool is_bottom_call); |
669 | 635 |
670 // Push and pop a promise and the current try-catch handler. | 636 // Push and pop a promise and the current try-catch handler. |
671 void PushPromise(Handle<JSObject> promise, Handle<JSFunction> function); | 637 void PushPromise(Handle<JSObject> promise, Handle<JSFunction> function); |
672 void PopPromise(); | 638 void PopPromise(); |
673 Handle<Object> GetPromiseOnStackOnThrow(); | 639 Handle<Object> GetPromiseOnStackOnThrow(); |
674 | 640 |
675 class ExceptionScope { | 641 class ExceptionScope { |
676 public: | 642 public: |
677 // Scope currently can only be used for regular exceptions, | 643 // Scope currently can only be used for regular exceptions, |
678 // not termination exception. | 644 // not termination exception. |
679 explicit ExceptionScope(Isolate* isolate) | 645 inline explicit ExceptionScope(Isolate* isolate); |
680 : isolate_(isolate), | 646 inline ~ExceptionScope(); |
681 pending_exception_(isolate_->pending_exception(), isolate_) {} | |
682 | |
683 ~ExceptionScope() { | |
684 isolate_->set_pending_exception(*pending_exception_); | |
685 } | |
686 | 647 |
687 private: | 648 private: |
688 Isolate* isolate_; | 649 Isolate* isolate_; |
689 Handle<Object> pending_exception_; | 650 Handle<Object> pending_exception_; |
690 }; | 651 }; |
691 | 652 |
692 void SetCaptureStackTraceForUncaughtExceptions( | 653 void SetCaptureStackTraceForUncaughtExceptions( |
693 bool capture, | 654 bool capture, |
694 int frame_limit, | 655 int frame_limit, |
695 StackTrace::StackTraceOptions options); | 656 StackTrace::StackTraceOptions options); |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
823 #undef GLOBAL_ACCESSOR | 784 #undef GLOBAL_ACCESSOR |
824 | 785 |
825 #define GLOBAL_ARRAY_ACCESSOR(type, name, length) \ | 786 #define GLOBAL_ARRAY_ACCESSOR(type, name, length) \ |
826 inline type* name() { \ | 787 inline type* name() { \ |
827 DCHECK(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \ | 788 DCHECK(OFFSET_OF(Isolate, name##_) == name##_debug_offset_); \ |
828 return &(name##_)[0]; \ | 789 return &(name##_)[0]; \ |
829 } | 790 } |
830 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR) | 791 ISOLATE_INIT_ARRAY_LIST(GLOBAL_ARRAY_ACCESSOR) |
831 #undef GLOBAL_ARRAY_ACCESSOR | 792 #undef GLOBAL_ARRAY_ACCESSOR |
832 | 793 |
833 #define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name) \ | 794 #define NATIVE_CONTEXT_FIELD_ACCESSOR(index, type, name) \ |
834 Handle<type> name() { \ | 795 inline Handle<type> name(); \ |
835 return Handle<type>(native_context()->name(), this); \ | 796 inline bool is_##name(type* value); |
836 } \ | |
837 bool is_##name(type* value) { \ | |
838 return native_context()->is_##name(value); \ | |
839 } | |
840 NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR) | 797 NATIVE_CONTEXT_FIELDS(NATIVE_CONTEXT_FIELD_ACCESSOR) |
841 #undef NATIVE_CONTEXT_FIELD_ACCESSOR | 798 #undef NATIVE_CONTEXT_FIELD_ACCESSOR |
842 | 799 |
843 Bootstrapper* bootstrapper() { return bootstrapper_; } | 800 Bootstrapper* bootstrapper() { return bootstrapper_; } |
844 Counters* counters() { | 801 Counters* counters() { |
845 // Call InitializeLoggingAndCounters() if logging is needed before | 802 // Call InitializeLoggingAndCounters() if logging is needed before |
846 // the isolate is fully initialized. | 803 // the isolate is fully initialized. |
847 DCHECK(counters_ != NULL); | 804 DCHECK(counters_ != NULL); |
848 return counters_; | 805 return counters_; |
849 } | 806 } |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1400 PromiseOnStack* prev_; | 1357 PromiseOnStack* prev_; |
1401 }; | 1358 }; |
1402 | 1359 |
1403 | 1360 |
1404 // If the GCC version is 4.1.x or 4.2.x an additional field is added to the | 1361 // If the GCC version is 4.1.x or 4.2.x an additional field is added to the |
1405 // class as a work around for a bug in the generated code found with these | 1362 // class as a work around for a bug in the generated code found with these |
1406 // versions of GCC. See V8 issue 122 for details. | 1363 // versions of GCC. See V8 issue 122 for details. |
1407 class SaveContext BASE_EMBEDDED { | 1364 class SaveContext BASE_EMBEDDED { |
1408 public: | 1365 public: |
1409 explicit SaveContext(Isolate* isolate); | 1366 explicit SaveContext(Isolate* isolate); |
1410 | 1367 ~SaveContext(); |
1411 ~SaveContext() { | |
1412 isolate_->set_context(context_.is_null() ? NULL : *context_); | |
1413 isolate_->set_save_context(prev_); | |
1414 } | |
1415 | 1368 |
1416 Handle<Context> context() { return context_; } | 1369 Handle<Context> context() { return context_; } |
1417 SaveContext* prev() { return prev_; } | 1370 SaveContext* prev() { return prev_; } |
1418 | 1371 |
1419 // Returns true if this save context is below a given JavaScript frame. | 1372 // Returns true if this save context is below a given JavaScript frame. |
1420 bool IsBelowFrame(JavaScriptFrame* frame) { | 1373 bool IsBelowFrame(JavaScriptFrame* frame) { |
1421 return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp()); | 1374 return (c_entry_fp_ == 0) || (c_entry_fp_ > frame->sp()); |
1422 } | 1375 } |
1423 | 1376 |
1424 private: | 1377 private: |
1425 Isolate* isolate_; | 1378 Isolate* isolate_; |
1426 Handle<Context> context_; | 1379 Handle<Context> context_; |
1427 SaveContext* prev_; | 1380 SaveContext* prev_; |
1428 Address c_entry_fp_; | 1381 Address c_entry_fp_; |
1429 }; | 1382 }; |
1430 | 1383 |
1431 | 1384 |
1432 class AssertNoContextChange BASE_EMBEDDED { | 1385 class AssertNoContextChange BASE_EMBEDDED { |
1433 #ifdef DEBUG | 1386 #ifdef DEBUG |
1434 public: | 1387 public: |
1435 explicit AssertNoContextChange(Isolate* isolate) | 1388 explicit AssertNoContextChange(Isolate* isolate); |
1436 : isolate_(isolate), | |
1437 context_(isolate->context(), isolate) { } | |
1438 ~AssertNoContextChange() { | 1389 ~AssertNoContextChange() { |
1439 DCHECK(isolate_->context() == *context_); | 1390 DCHECK(isolate_->context() == *context_); |
1440 } | 1391 } |
1441 | 1392 |
1442 private: | 1393 private: |
1443 Isolate* isolate_; | 1394 Isolate* isolate_; |
1444 Handle<Context> context_; | 1395 Handle<Context> context_; |
1445 #else | 1396 #else |
1446 public: | 1397 public: |
1447 explicit AssertNoContextChange(Isolate* isolate) { } | 1398 explicit AssertNoContextChange(Isolate* isolate) { } |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1589 } | 1540 } |
1590 | 1541 |
1591 EmbeddedVector<char, 128> filename_; | 1542 EmbeddedVector<char, 128> filename_; |
1592 FILE* file_; | 1543 FILE* file_; |
1593 int scope_depth_; | 1544 int scope_depth_; |
1594 }; | 1545 }; |
1595 | 1546 |
1596 } } // namespace v8::internal | 1547 } } // namespace v8::internal |
1597 | 1548 |
1598 #endif // V8_ISOLATE_H_ | 1549 #endif // V8_ISOLATE_H_ |
OLD | NEW |