| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_ISOLATE_H_ | 5 #ifndef VM_ISOLATE_H_ |
| 6 #define VM_ISOLATE_H_ | 6 #define VM_ISOLATE_H_ |
| 7 | 7 |
| 8 #include "include/dart_api.h" | 8 #include "include/dart_api.h" |
| 9 #include "platform/assert.h" | 9 #include "platform/assert.h" |
| 10 #include "vm/atomic.h" | 10 #include "vm/atomic.h" |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 environment_callback_ = value; | 222 environment_callback_ = value; |
| 223 } | 223 } |
| 224 | 224 |
| 225 Dart_LibraryTagHandler library_tag_handler() const { | 225 Dart_LibraryTagHandler library_tag_handler() const { |
| 226 return library_tag_handler_; | 226 return library_tag_handler_; |
| 227 } | 227 } |
| 228 void set_library_tag_handler(Dart_LibraryTagHandler value) { | 228 void set_library_tag_handler(Dart_LibraryTagHandler value) { |
| 229 library_tag_handler_ = value; | 229 library_tag_handler_ = value; |
| 230 } | 230 } |
| 231 | 231 |
| 232 void SetStackLimit(uword value); | |
| 233 void SetStackLimitFromStackBase(uword stack_base); | |
| 234 void ClearStackLimit(); | |
| 235 | |
| 236 // Returns the current C++ stack pointer. Equivalent taking the address of a | |
| 237 // stack allocated local, but plays well with AddressSanitizer. | |
| 238 // TODO(koda): Move to Thread. | |
| 239 static uword GetCurrentStackPointer(); | |
| 240 | |
| 241 void SetupInstructionsSnapshotPage( | 232 void SetupInstructionsSnapshotPage( |
| 242 const uint8_t* instructions_snapshot_buffer); | 233 const uint8_t* instructions_snapshot_buffer); |
| 243 void SetupDataSnapshotPage( | 234 void SetupDataSnapshotPage( |
| 244 const uint8_t* instructions_snapshot_buffer); | 235 const uint8_t* instructions_snapshot_buffer); |
| 245 | 236 |
| 246 // Returns true if any of the interrupts specified by 'interrupt_bits' are | 237 void ScheduleMessageInterrupts(); |
| 247 // currently scheduled for this isolate, but leaves them unchanged. | |
| 248 // | |
| 249 // NOTE: The read uses relaxed memory ordering, i.e., it is atomic and | |
| 250 // an interrupt is guaranteed to be observed eventually, but any further | |
| 251 // order guarantees must be ensured by other synchronization. See the | |
| 252 // tests in isolate_test.cc for example usage. | |
| 253 bool HasInterruptsScheduled(uword interrupt_bits) { | |
| 254 ASSERT(interrupt_bits == (interrupt_bits & kInterruptsMask)); | |
| 255 uword limit = AtomicOperations::LoadRelaxed(&stack_limit_); | |
| 256 return (limit != saved_stack_limit_) && | |
| 257 (((limit & kInterruptsMask) & interrupt_bits) != 0); | |
| 258 } | |
| 259 | |
| 260 // Access to the current stack limit for generated code. This may be | |
| 261 // overwritten with a special value to trigger interrupts. | |
| 262 uword stack_limit_address() const { | |
| 263 return reinterpret_cast<uword>(&stack_limit_); | |
| 264 } | |
| 265 static intptr_t stack_limit_offset() { | |
| 266 return OFFSET_OF(Isolate, stack_limit_); | |
| 267 } | |
| 268 | |
| 269 // The true stack limit for this isolate. | |
| 270 uword saved_stack_limit() const { return saved_stack_limit_; } | |
| 271 | |
| 272 // Stack overflow flags | |
| 273 enum { | |
| 274 kOsrRequest = 0x1, // Current stack overflow caused by OSR request. | |
| 275 }; | |
| 276 | |
| 277 uword stack_overflow_flags_address() const { | |
| 278 return reinterpret_cast<uword>(&stack_overflow_flags_); | |
| 279 } | |
| 280 static intptr_t stack_overflow_flags_offset() { | |
| 281 return OFFSET_OF(Isolate, stack_overflow_flags_); | |
| 282 } | |
| 283 | |
| 284 int32_t IncrementAndGetStackOverflowCount() { | |
| 285 return ++stack_overflow_count_; | |
| 286 } | |
| 287 | |
| 288 // Retrieves and clears the stack overflow flags. These are set by | |
| 289 // the generated code before the slow path runtime routine for a | |
| 290 // stack overflow is called. | |
| 291 uword GetAndClearStackOverflowFlags(); | |
| 292 | |
| 293 // Interrupt bits. | |
| 294 enum { | |
| 295 kVMInterrupt = 0x1, // Internal VM checks: safepoints, store buffers, etc. | |
| 296 kMessageInterrupt = 0x2, // An interrupt to process an out of band message. | |
| 297 | |
| 298 kInterruptsMask = (kVMInterrupt | kMessageInterrupt), | |
| 299 }; | |
| 300 | |
| 301 void ScheduleInterrupts(uword interrupt_bits); | |
| 302 RawError* HandleInterrupts(); | |
| 303 uword GetAndClearInterrupts(); | |
| 304 | 238 |
| 305 // Marks all libraries as loaded. | 239 // Marks all libraries as loaded. |
| 306 void DoneLoading(); | 240 void DoneLoading(); |
| 307 | 241 |
| 308 bool MakeRunnable(); | 242 bool MakeRunnable(); |
| 309 void Run(); | 243 void Run(); |
| 310 | 244 |
| 311 MessageHandler* message_handler() const { return message_handler_; } | 245 MessageHandler* message_handler() const { return message_handler_; } |
| 312 void set_message_handler(MessageHandler* value) { message_handler_ = value; } | 246 void set_message_handler(MessageHandler* value) { message_handler_ = value; } |
| 313 | 247 |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 669 | 603 |
| 670 static void KillAllIsolates(LibMsgId msg_id); | 604 static void KillAllIsolates(LibMsgId msg_id); |
| 671 static void KillIfExists(Isolate* isolate, LibMsgId msg_id); | 605 static void KillIfExists(Isolate* isolate, LibMsgId msg_id); |
| 672 | 606 |
| 673 static void DisableIsolateCreation(); | 607 static void DisableIsolateCreation(); |
| 674 static void EnableIsolateCreation(); | 608 static void EnableIsolateCreation(); |
| 675 | 609 |
| 676 private: | 610 private: |
| 677 friend class Dart; // Init, InitOnce, Shutdown. | 611 friend class Dart; // Init, InitOnce, Shutdown. |
| 678 friend class IsolateKillerVisitor; // Kill(). | 612 friend class IsolateKillerVisitor; // Kill(). |
| 679 friend class NoOOBMessageScope; | |
| 680 | 613 |
| 681 explicit Isolate(const Dart_IsolateFlags& api_flags); | 614 explicit Isolate(const Dart_IsolateFlags& api_flags); |
| 682 | 615 |
| 683 static void InitOnce(); | 616 static void InitOnce(); |
| 684 static Isolate* Init(const char* name_prefix, | 617 static Isolate* Init(const char* name_prefix, |
| 685 const Dart_IsolateFlags& api_flags, | 618 const Dart_IsolateFlags& api_flags, |
| 686 bool is_vm_isolate = false); | 619 bool is_vm_isolate = false); |
| 687 | 620 |
| 688 // The isolates_list_monitor_ should be held when calling Kill(). | 621 // The isolates_list_monitor_ should be held when calling Kill(). |
| 689 void KillLocked(LibMsgId msg_id); | 622 void KillLocked(LibMsgId msg_id); |
| 690 | 623 |
| 691 void LowLevelShutdown(); | 624 void LowLevelShutdown(); |
| 692 void Shutdown(); | 625 void Shutdown(); |
| 693 | 626 |
| 694 void BuildName(const char* name_prefix); | 627 void BuildName(const char* name_prefix); |
| 695 | 628 |
| 696 void ProfileIdle(); | 629 void ProfileIdle(); |
| 697 | 630 |
| 698 // Visit all object pointers. Caller must ensure concurrent sweeper is not | 631 // Visit all object pointers. Caller must ensure concurrent sweeper is not |
| 699 // running, and the visitor must not allocate. | 632 // running, and the visitor must not allocate. |
| 700 void VisitObjectPointers(ObjectPointerVisitor* visitor, bool validate_frames); | 633 void VisitObjectPointers(ObjectPointerVisitor* visitor, bool validate_frames); |
| 701 | 634 |
| 702 void set_user_tag(uword tag) { | 635 void set_user_tag(uword tag) { |
| 703 user_tag_ = tag; | 636 user_tag_ = tag; |
| 704 } | 637 } |
| 705 | 638 |
| 706 void DeferOOBMessageInterrupts(); | |
| 707 void RestoreOOBMessageInterrupts(); | |
| 708 | |
| 709 RawGrowableObjectArray* GetAndClearPendingServiceExtensionCalls(); | 639 RawGrowableObjectArray* GetAndClearPendingServiceExtensionCalls(); |
| 710 RawGrowableObjectArray* pending_service_extension_calls() const { | 640 RawGrowableObjectArray* pending_service_extension_calls() const { |
| 711 return pending_service_extension_calls_; | 641 return pending_service_extension_calls_; |
| 712 } | 642 } |
| 713 void set_pending_service_extension_calls(const GrowableObjectArray& value); | 643 void set_pending_service_extension_calls(const GrowableObjectArray& value); |
| 714 RawGrowableObjectArray* registered_service_extension_handlers() const { | 644 RawGrowableObjectArray* registered_service_extension_handlers() const { |
| 715 return registered_service_extension_handlers_; | 645 return registered_service_extension_handlers_; |
| 716 } | 646 } |
| 717 void set_registered_service_extension_handlers( | 647 void set_registered_service_extension_handlers( |
| 718 const GrowableObjectArray& value); | 648 const GrowableObjectArray& value); |
| 719 | 649 |
| 720 Monitor* threads_lock() const; | 650 Monitor* threads_lock() const; |
| 721 Thread* ScheduleThread(bool is_mutator, bool bypass_safepoint = false); | 651 Thread* ScheduleThread(bool is_mutator, bool bypass_safepoint = false); |
| 722 void UnscheduleThread( | 652 void UnscheduleThread( |
| 723 Thread* thread, bool is_mutator, bool bypass_safepoint = false); | 653 Thread* thread, bool is_mutator, bool bypass_safepoint = false); |
| 724 | 654 |
| 725 // DEPRECATED: Use Thread's methods instead. During migration, these default | 655 // DEPRECATED: Use Thread's methods instead. During migration, these default |
| 726 // to using the mutator thread (which must also be the current thread). | 656 // to using the mutator thread (which must also be the current thread). |
| 727 Zone* current_zone() const { | 657 Zone* current_zone() const { |
| 728 ASSERT(Thread::Current() == mutator_thread_); | 658 ASSERT(Thread::Current() == mutator_thread_); |
| 729 return mutator_thread_->zone(); | 659 return mutator_thread_->zone(); |
| 730 } | 660 } |
| 731 | 661 |
| 732 // Accessed from generated code: | 662 // Accessed from generated code: |
| 733 // TODO(asiva): Need to consider moving the stack_limit_ from isolate to | |
| 734 // being thread specific. | |
| 735 uword stack_limit_; | |
| 736 StoreBuffer* store_buffer_; | 663 StoreBuffer* store_buffer_; |
| 737 Heap* heap_; | 664 Heap* heap_; |
| 738 uword user_tag_; | 665 uword user_tag_; |
| 739 RawUserTag* current_tag_; | 666 RawUserTag* current_tag_; |
| 740 RawUserTag* default_tag_; | 667 RawUserTag* default_tag_; |
| 741 RawCode* ic_miss_code_; | 668 RawCode* ic_miss_code_; |
| 742 ClassTable class_table_; | 669 ClassTable class_table_; |
| 743 bool single_step_; | 670 bool single_step_; |
| 744 bool skip_step_; // skip the next single step. | 671 bool skip_step_; // skip the next single step. |
| 745 | 672 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 759 void* init_callback_data_; | 686 void* init_callback_data_; |
| 760 Dart_EnvironmentCallback environment_callback_; | 687 Dart_EnvironmentCallback environment_callback_; |
| 761 Dart_LibraryTagHandler library_tag_handler_; | 688 Dart_LibraryTagHandler library_tag_handler_; |
| 762 ApiState* api_state_; | 689 ApiState* api_state_; |
| 763 Debugger* debugger_; | 690 Debugger* debugger_; |
| 764 bool resume_request_; | 691 bool resume_request_; |
| 765 int64_t last_resume_timestamp_; | 692 int64_t last_resume_timestamp_; |
| 766 bool has_compiled_code_; // Can check that no compilation occured. | 693 bool has_compiled_code_; // Can check that no compilation occured. |
| 767 Random random_; | 694 Random random_; |
| 768 Simulator* simulator_; | 695 Simulator* simulator_; |
| 769 Mutex* mutex_; // Protects stack_limit_, saved_stack_limit_, compiler stats. | 696 Mutex* mutex_; // Protects compiler stats. |
| 770 Mutex* symbols_mutex_; // Protects concurrent access to the symbol table. | 697 Mutex* symbols_mutex_; // Protects concurrent access to the symbol table. |
| 771 Mutex* type_canonicalization_mutex_; // Protects type canonicalization. | 698 Mutex* type_canonicalization_mutex_; // Protects type canonicalization. |
| 772 Mutex* constant_canonicalization_mutex_; // Protects const canonicalization. | 699 Mutex* constant_canonicalization_mutex_; // Protects const canonicalization. |
| 773 uword saved_stack_limit_; | |
| 774 uword deferred_interrupts_mask_; | |
| 775 uword deferred_interrupts_; | |
| 776 uword stack_overflow_flags_; | |
| 777 int32_t stack_overflow_count_; | |
| 778 MessageHandler* message_handler_; | 700 MessageHandler* message_handler_; |
| 779 IsolateSpawnState* spawn_state_; | 701 IsolateSpawnState* spawn_state_; |
| 780 bool is_runnable_; | 702 bool is_runnable_; |
| 781 Dart_GcPrologueCallback gc_prologue_callback_; | 703 Dart_GcPrologueCallback gc_prologue_callback_; |
| 782 Dart_GcEpilogueCallback gc_epilogue_callback_; | 704 Dart_GcEpilogueCallback gc_epilogue_callback_; |
| 783 intptr_t defer_finalization_count_; | 705 intptr_t defer_finalization_count_; |
| 784 DeoptContext* deopt_context_; | 706 DeoptContext* deopt_context_; |
| 785 | 707 |
| 786 CompilerStats* compiler_stats_; | 708 CompilerStats* compiler_stats_; |
| 787 | 709 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 friend class Reusable##name##HandleScope; | 822 friend class Reusable##name##HandleScope; |
| 901 REUSABLE_HANDLE_LIST(REUSABLE_FRIEND_DECLARATION) | 823 REUSABLE_HANDLE_LIST(REUSABLE_FRIEND_DECLARATION) |
| 902 #undef REUSABLE_FRIEND_DECLARATION | 824 #undef REUSABLE_FRIEND_DECLARATION |
| 903 | 825 |
| 904 friend class GCMarker; // VisitObjectPointers | 826 friend class GCMarker; // VisitObjectPointers |
| 905 friend class SafepointHandler; | 827 friend class SafepointHandler; |
| 906 friend class Scavenger; // VisitObjectPointers | 828 friend class Scavenger; // VisitObjectPointers |
| 907 friend class ServiceIsolate; | 829 friend class ServiceIsolate; |
| 908 friend class Thread; | 830 friend class Thread; |
| 909 friend class Timeline; | 831 friend class Timeline; |
| 910 friend class IsolateTestHelper; | |
| 911 | 832 |
| 912 DISALLOW_COPY_AND_ASSIGN(Isolate); | 833 DISALLOW_COPY_AND_ASSIGN(Isolate); |
| 913 }; | 834 }; |
| 914 | 835 |
| 915 | 836 |
| 916 // When we need to execute code in an isolate, we use the | 837 // When we need to execute code in an isolate, we use the |
| 917 // StartIsolateScope. | 838 // StartIsolateScope. |
| 918 class StartIsolateScope { | 839 class StartIsolateScope { |
| 919 public: | 840 public: |
| 920 explicit StartIsolateScope(Isolate* new_isolate) | 841 explicit StartIsolateScope(Isolate* new_isolate) |
| 921 : new_isolate_(new_isolate), saved_isolate_(Isolate::Current()) { | 842 : new_isolate_(new_isolate), saved_isolate_(Isolate::Current()) { |
| 922 // TODO(koda): Audit users; passing NULL goes against naming of this class. | 843 // TODO(koda): Audit users; passing NULL goes against naming of this class. |
| 923 if (new_isolate_ == NULL) { | 844 if (new_isolate_ == NULL) { |
| 924 ASSERT(Isolate::Current() == NULL); | 845 ASSERT(Isolate::Current() == NULL); |
| 925 // Do nothing. | 846 // Do nothing. |
| 926 return; | 847 return; |
| 927 } | 848 } |
| 928 if (saved_isolate_ != new_isolate_) { | 849 if (saved_isolate_ != new_isolate_) { |
| 929 ASSERT(Isolate::Current() == NULL); | 850 ASSERT(Isolate::Current() == NULL); |
| 851 Thread::EnterIsolate(new_isolate_); |
| 930 // Ensure this is not a nested 'isolate enter' with prior state. | 852 // Ensure this is not a nested 'isolate enter' with prior state. |
| 931 ASSERT(new_isolate_->saved_stack_limit() == 0); | 853 ASSERT(Thread::Current()->saved_stack_limit() == 0); |
| 932 Thread::EnterIsolate(new_isolate_); | |
| 933 } | 854 } |
| 934 } | 855 } |
| 935 | 856 |
| 936 ~StartIsolateScope() { | 857 ~StartIsolateScope() { |
| 937 if (new_isolate_ == NULL) { | 858 if (new_isolate_ == NULL) { |
| 938 ASSERT(Isolate::Current() == NULL); | 859 ASSERT(Isolate::Current() == NULL); |
| 939 // Do nothing. | 860 // Do nothing. |
| 940 return; | 861 return; |
| 941 } | 862 } |
| 942 if (saved_isolate_ != new_isolate_) { | 863 if (saved_isolate_ != new_isolate_) { |
| 943 ASSERT(saved_isolate_ == NULL); | 864 ASSERT(saved_isolate_ == NULL); |
| 944 // ASSERT that we have bottomed out of all Dart invocations. | 865 // ASSERT that we have bottomed out of all Dart invocations. |
| 945 ASSERT(new_isolate_->saved_stack_limit() == 0); | 866 ASSERT(Thread::Current()->saved_stack_limit() == 0); |
| 946 Thread::ExitIsolate(); | 867 Thread::ExitIsolate(); |
| 947 } | 868 } |
| 948 } | 869 } |
| 949 | 870 |
| 950 private: | 871 private: |
| 951 Isolate* new_isolate_; | 872 Isolate* new_isolate_; |
| 952 Isolate* saved_isolate_; | 873 Isolate* saved_isolate_; |
| 953 | 874 |
| 954 DISALLOW_COPY_AND_ASSIGN(StartIsolateScope); | 875 DISALLOW_COPY_AND_ASSIGN(StartIsolateScope); |
| 955 }; | 876 }; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 intptr_t* spawn_count_; | 956 intptr_t* spawn_count_; |
| 1036 | 957 |
| 1037 Dart_IsolateFlags isolate_flags_; | 958 Dart_IsolateFlags isolate_flags_; |
| 1038 bool paused_; | 959 bool paused_; |
| 1039 bool errors_are_fatal_; | 960 bool errors_are_fatal_; |
| 1040 }; | 961 }; |
| 1041 | 962 |
| 1042 } // namespace dart | 963 } // namespace dart |
| 1043 | 964 |
| 1044 #endif // VM_ISOLATE_H_ | 965 #endif // VM_ISOLATE_H_ |
| OLD | NEW |