OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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_THREAD_H_ | 5 #ifndef VM_THREAD_H_ |
6 #define VM_THREAD_H_ | 6 #define VM_THREAD_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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 // "helper" to gain limited concurrent access to the isolate. One example is | 138 // "helper" to gain limited concurrent access to the isolate. One example is |
139 // SweeperTask (which uses the class table, which is copy-on-write). | 139 // SweeperTask (which uses the class table, which is copy-on-write). |
140 // TODO(koda): Properly synchronize heap access to expand allowed operations. | 140 // TODO(koda): Properly synchronize heap access to expand allowed operations. |
141 static bool EnterIsolateAsHelper(Isolate* isolate, | 141 static bool EnterIsolateAsHelper(Isolate* isolate, |
142 bool bypass_safepoint = false); | 142 bool bypass_safepoint = false); |
143 static void ExitIsolateAsHelper(bool bypass_safepoint = false); | 143 static void ExitIsolateAsHelper(bool bypass_safepoint = false); |
144 | 144 |
145 // Empties the store buffer block into the isolate. | 145 // Empties the store buffer block into the isolate. |
146 void PrepareForGC(); | 146 void PrepareForGC(); |
147 | 147 |
| 148 void SetStackLimit(uword value); |
| 149 void SetStackLimitFromStackBase(uword stack_base); |
| 150 void ClearStackLimit(); |
| 151 |
| 152 // Returns the current C++ stack pointer. Equivalent taking the address of a |
| 153 // stack allocated local, but plays well with AddressSanitizer. |
| 154 static uword GetCurrentStackPointer(); |
| 155 |
| 156 // Access to the current stack limit for generated code. This may be |
| 157 // overwritten with a special value to trigger interrupts. |
| 158 uword stack_limit_address() const { |
| 159 return reinterpret_cast<uword>(&stack_limit_); |
| 160 } |
| 161 static intptr_t stack_limit_offset() { |
| 162 return OFFSET_OF(Thread, stack_limit_); |
| 163 } |
| 164 |
| 165 // The true stack limit for this isolate. |
| 166 uword saved_stack_limit() const { return saved_stack_limit_; } |
| 167 |
| 168 // Stack overflow flags |
| 169 enum { |
| 170 kOsrRequest = 0x1, // Current stack overflow caused by OSR request. |
| 171 }; |
| 172 |
| 173 uword stack_overflow_flags_address() const { |
| 174 return reinterpret_cast<uword>(&stack_overflow_flags_); |
| 175 } |
| 176 static intptr_t stack_overflow_flags_offset() { |
| 177 return OFFSET_OF(Thread, stack_overflow_flags_); |
| 178 } |
| 179 |
| 180 int32_t IncrementAndGetStackOverflowCount() { |
| 181 return ++stack_overflow_count_; |
| 182 } |
| 183 |
| 184 // Retrieves and clears the stack overflow flags. These are set by |
| 185 // the generated code before the slow path runtime routine for a |
| 186 // stack overflow is called. |
| 187 uword GetAndClearStackOverflowFlags(); |
| 188 |
| 189 // Interrupt bits. |
| 190 enum { |
| 191 kVMInterrupt = 0x1, // Internal VM checks: safepoints, store buffers, etc. |
| 192 kMessageInterrupt = 0x2, // An interrupt to process an out of band message. |
| 193 |
| 194 kInterruptsMask = (kVMInterrupt | kMessageInterrupt), |
| 195 }; |
| 196 |
| 197 void ScheduleInterrupts(uword interrupt_bits); |
| 198 void ScheduleInterruptsLocked(uword interrupt_bits); |
| 199 RawError* HandleInterrupts(); |
| 200 uword GetAndClearInterrupts(); |
| 201 |
148 // OSThread corresponding to this thread. | 202 // OSThread corresponding to this thread. |
149 OSThread* os_thread() const { return os_thread_; } | 203 OSThread* os_thread() const { return os_thread_; } |
150 void set_os_thread(OSThread* os_thread) { | 204 void set_os_thread(OSThread* os_thread) { |
151 os_thread_ = os_thread; | 205 os_thread_ = os_thread; |
152 } | 206 } |
153 | 207 |
154 // Monitor corresponding to this thread. | 208 // Monitor corresponding to this thread. |
155 Monitor* thread_lock() const { return thread_lock_; } | 209 Monitor* thread_lock() const { return thread_lock_; } |
156 | 210 |
157 // The topmost zone used for allocation in this thread. | 211 // The topmost zone used for allocation in this thread. |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 bool IsValidLocalHandle(Dart_Handle object) const; | 580 bool IsValidLocalHandle(Dart_Handle object) const; |
527 int CountLocalHandles() const; | 581 int CountLocalHandles() const; |
528 int ZoneSizeInBytes() const; | 582 int ZoneSizeInBytes() const; |
529 void UnwindScopes(uword stack_marker); | 583 void UnwindScopes(uword stack_marker); |
530 | 584 |
531 void InitVMConstants(); | 585 void InitVMConstants(); |
532 | 586 |
533 private: | 587 private: |
534 template<class T> T* AllocateReusableHandle(); | 588 template<class T> T* AllocateReusableHandle(); |
535 | 589 |
| 590 // Accessed from generated code: |
| 591 uword stack_limit_; |
| 592 uword stack_overflow_flags_; |
| 593 Isolate* isolate_; |
| 594 Heap* heap_; |
| 595 uword top_exit_frame_info_; |
| 596 StoreBufferBlock* store_buffer_block_; |
| 597 uword vm_tag_; |
| 598 // State that is cached in the TLS for fast access in generated code. |
| 599 #define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value) \ |
| 600 type_name member_name; |
| 601 CACHED_CONSTANTS_LIST(DECLARE_MEMBERS) |
| 602 #undef DECLARE_MEMBERS |
| 603 |
| 604 #define DECLARE_MEMBERS(name) \ |
| 605 uword name##_entry_point_; |
| 606 RUNTIME_ENTRY_LIST(DECLARE_MEMBERS) |
| 607 #undef DECLARE_MEMBERS |
| 608 |
| 609 #define DECLARE_MEMBERS(returntype, name, ...) \ |
| 610 uword name##_entry_point_; |
| 611 LEAF_RUNTIME_ENTRY_LIST(DECLARE_MEMBERS) |
| 612 #undef DECLARE_MEMBERS |
| 613 |
536 OSThread* os_thread_; | 614 OSThread* os_thread_; |
537 Monitor* thread_lock_; | 615 Monitor* thread_lock_; |
538 Isolate* isolate_; | |
539 Heap* heap_; | |
540 Zone* zone_; | 616 Zone* zone_; |
541 ApiLocalScope* api_reusable_scope_; | 617 ApiLocalScope* api_reusable_scope_; |
542 ApiLocalScope* api_top_scope_; | 618 ApiLocalScope* api_top_scope_; |
543 uword top_exit_frame_info_; | |
544 StackResource* top_resource_; | 619 StackResource* top_resource_; |
545 LongJumpScope* long_jump_base_; | 620 LongJumpScope* long_jump_base_; |
546 StoreBufferBlock* store_buffer_block_; | |
547 int32_t no_callback_scope_depth_; | 621 int32_t no_callback_scope_depth_; |
548 #if defined(DEBUG) | 622 #if defined(DEBUG) |
549 HandleScope* top_handle_scope_; | 623 HandleScope* top_handle_scope_; |
550 int32_t no_handle_scope_depth_; | 624 int32_t no_handle_scope_depth_; |
551 int32_t no_safepoint_scope_depth_; | 625 int32_t no_safepoint_scope_depth_; |
552 #endif | 626 #endif |
553 VMHandles reusable_handles_; | 627 VMHandles reusable_handles_; |
| 628 uword saved_stack_limit_; |
| 629 uint16_t deferred_interrupts_mask_; |
| 630 uint16_t deferred_interrupts_; |
| 631 int32_t stack_overflow_count_; |
554 | 632 |
555 // Compiler state: | 633 // Compiler state: |
556 CHA* cha_; | 634 CHA* cha_; |
557 intptr_t deopt_id_; // Compilation specific counter. | 635 intptr_t deopt_id_; // Compilation specific counter. |
558 uword vm_tag_; | |
559 RawGrowableObjectArray* pending_functions_; | 636 RawGrowableObjectArray* pending_functions_; |
560 | 637 |
561 RawError* sticky_error_; | 638 RawError* sticky_error_; |
562 | 639 |
563 // State that is cached in the TLS for fast access in generated code. | |
564 #define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value) \ | |
565 type_name member_name; | |
566 CACHED_CONSTANTS_LIST(DECLARE_MEMBERS) | |
567 #undef DECLARE_MEMBERS | |
568 | |
569 #define DECLARE_MEMBERS(name) \ | |
570 uword name##_entry_point_; | |
571 RUNTIME_ENTRY_LIST(DECLARE_MEMBERS) | |
572 #undef DECLARE_MEMBERS | |
573 | |
574 #define DECLARE_MEMBERS(returntype, name, ...) \ | |
575 uword name##_entry_point_; | |
576 LEAF_RUNTIME_ENTRY_LIST(DECLARE_MEMBERS) | |
577 #undef DECLARE_MEMBERS | |
578 | |
579 // Reusable handles support. | 640 // Reusable handles support. |
580 #define REUSABLE_HANDLE_FIELDS(object) \ | 641 #define REUSABLE_HANDLE_FIELDS(object) \ |
581 object* object##_handle_; | 642 object* object##_handle_; |
582 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_FIELDS) | 643 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_FIELDS) |
583 #undef REUSABLE_HANDLE_FIELDS | 644 #undef REUSABLE_HANDLE_FIELDS |
584 | 645 |
585 #if defined(DEBUG) | 646 #if defined(DEBUG) |
586 #define REUSABLE_HANDLE_SCOPE_VARIABLE(object) \ | 647 #define REUSABLE_HANDLE_SCOPE_VARIABLE(object) \ |
587 bool reusable_##object##_handle_scope_active_; | 648 bool reusable_##object##_handle_scope_active_; |
588 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_VARIABLE); | 649 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_VARIABLE); |
(...skipping 26 matching lines...) Expand all Loading... |
615 safepoint_state_ = value; | 676 safepoint_state_ = value; |
616 } | 677 } |
617 void EnterSafepointUsingLock(); | 678 void EnterSafepointUsingLock(); |
618 void ExitSafepointUsingLock(); | 679 void ExitSafepointUsingLock(); |
619 void BlockForSafepoint(); | 680 void BlockForSafepoint(); |
620 | 681 |
621 static void SetCurrent(Thread* current) { | 682 static void SetCurrent(Thread* current) { |
622 OSThread::SetCurrentTLS(reinterpret_cast<uword>(current)); | 683 OSThread::SetCurrentTLS(reinterpret_cast<uword>(current)); |
623 } | 684 } |
624 | 685 |
| 686 void DeferOOBMessageInterrupts(); |
| 687 void RestoreOOBMessageInterrupts(); |
| 688 |
625 #define REUSABLE_FRIEND_DECLARATION(name) \ | 689 #define REUSABLE_FRIEND_DECLARATION(name) \ |
626 friend class Reusable##name##HandleScope; | 690 friend class Reusable##name##HandleScope; |
627 REUSABLE_HANDLE_LIST(REUSABLE_FRIEND_DECLARATION) | 691 REUSABLE_HANDLE_LIST(REUSABLE_FRIEND_DECLARATION) |
628 #undef REUSABLE_FRIEND_DECLARATION | 692 #undef REUSABLE_FRIEND_DECLARATION |
629 | 693 |
630 friend class ApiZone; | 694 friend class ApiZone; |
| 695 friend class InterruptChecker; |
631 friend class Isolate; | 696 friend class Isolate; |
| 697 friend class IsolateTestHelper; |
| 698 friend class NoOOBMessageScope; |
632 friend class Simulator; | 699 friend class Simulator; |
633 friend class StackZone; | 700 friend class StackZone; |
634 friend class ThreadRegistry; | 701 friend class ThreadRegistry; |
635 | 702 |
636 DISALLOW_COPY_AND_ASSIGN(Thread); | 703 DISALLOW_COPY_AND_ASSIGN(Thread); |
637 }; | 704 }; |
638 | 705 |
639 | 706 |
640 #if defined(TARGET_OS_WINDOWS) | 707 #if defined(TARGET_OS_WINDOWS) |
641 // Clears the state of the current thread and frees the allocation. | 708 // Clears the state of the current thread and frees the allocation. |
642 void WindowsThreadCleanUp(); | 709 void WindowsThreadCleanUp(); |
643 #endif | 710 #endif |
644 | 711 |
645 | 712 |
646 // Disable thread interrupts. | 713 // Disable thread interrupts. |
647 class DisableThreadInterruptsScope : public StackResource { | 714 class DisableThreadInterruptsScope : public StackResource { |
648 public: | 715 public: |
649 explicit DisableThreadInterruptsScope(Thread* thread); | 716 explicit DisableThreadInterruptsScope(Thread* thread); |
650 ~DisableThreadInterruptsScope(); | 717 ~DisableThreadInterruptsScope(); |
651 }; | 718 }; |
652 | 719 |
653 } // namespace dart | 720 } // namespace dart |
654 | 721 |
655 #endif // VM_THREAD_H_ | 722 #endif // VM_THREAD_H_ |
OLD | NEW |