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 |