| 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 |