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 "vm/globals.h" | 8 #include "vm/globals.h" |
9 #include "vm/handles.h" | 9 #include "vm/handles.h" |
10 #include "vm/os_thread.h" | 10 #include "vm/os_thread.h" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 V(uword, native_call_wrapper_entry_point_, \ | 85 V(uword, native_call_wrapper_entry_point_, \ |
86 NativeEntry::NativeCallWrapperEntry(), 0) \ | 86 NativeEntry::NativeCallWrapperEntry(), 0) \ |
87 V(RawString**, predefined_symbols_address_, \ | 87 V(RawString**, predefined_symbols_address_, \ |
88 Symbols::PredefinedAddress(), NULL) \ | 88 Symbols::PredefinedAddress(), NULL) \ |
89 | 89 |
90 #define CACHED_CONSTANTS_LIST(V) \ | 90 #define CACHED_CONSTANTS_LIST(V) \ |
91 CACHED_VM_OBJECTS_LIST(V) \ | 91 CACHED_VM_OBJECTS_LIST(V) \ |
92 CACHED_ADDRESSES_LIST(V) \ | 92 CACHED_ADDRESSES_LIST(V) \ |
93 | 93 |
94 struct InterruptedThreadState { | 94 struct InterruptedThreadState { |
95 ThreadId tid; | |
96 uintptr_t pc; | 95 uintptr_t pc; |
97 uintptr_t csp; | 96 uintptr_t csp; |
98 uintptr_t dsp; | 97 uintptr_t dsp; |
99 uintptr_t fp; | 98 uintptr_t fp; |
100 uintptr_t lr; | 99 uintptr_t lr; |
101 }; | 100 }; |
102 | 101 |
103 // When a thread is interrupted the thread specific interrupt callback will be | 102 // When a thread is interrupted the thread specific interrupt callback will be |
104 // invoked. Each callback is given an InterruptedThreadState and the user data | 103 // invoked. Each callback is given an InterruptedThreadState and the user data |
105 // pointer. When inside a thread interrupt callback doing any of the following | 104 // pointer. When inside a thread interrupt callback doing any of the following |
106 // is forbidden: | 105 // is forbidden: |
107 // * Accessing TLS -- Because on Windows the callback will be running in a | 106 // * Accessing TLS -- Because on Windows the callback will be running in a |
108 // different thread. | 107 // different thread. |
109 // * Allocating memory -- Because this takes locks which may already be held, | 108 // * Allocating memory -- Because this takes locks which may already be held, |
110 // resulting in a dead lock. | 109 // resulting in a dead lock. |
111 // * Taking a lock -- See above. | 110 // * Taking a lock -- See above. |
112 typedef void (*ThreadInterruptCallback)(const InterruptedThreadState& state, | 111 typedef void (*ThreadInterruptCallback)(Thread* thread, |
113 void* data); | 112 const InterruptedThreadState& state); |
114 | 113 |
115 // A VM thread; may be executing Dart code or performing helper tasks like | 114 // A VM thread; may be executing Dart code or performing helper tasks like |
116 // garbage collection or compilation. The Thread structure associated with | 115 // garbage collection or compilation. The Thread structure associated with |
117 // a thread is allocated by EnsureInit before entering an isolate, and destroyed | 116 // a thread is allocated by EnsureInit before entering an isolate, and destroyed |
118 // automatically when the underlying OS thread exits. NOTE: On Windows, CleanUp | 117 // automatically when the underlying OS thread exits. NOTE: On Windows, CleanUp |
119 // must currently be called manually (issue 23474). | 118 // must currently be called manually (issue 23474). |
120 class Thread { | 119 class Thread { |
121 public: | 120 public: |
122 // The currently executing thread, or NULL if not yet initialized. | 121 // The currently executing thread, or NULL if not yet initialized. |
123 static Thread* Current() { | 122 static Thread* Current() { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 // The topmost zone used for allocation in this thread. | 155 // The topmost zone used for allocation in this thread. |
157 Zone* zone() const { return state_.zone; } | 156 Zone* zone() const { return state_.zone; } |
158 | 157 |
159 // The isolate that this thread is operating on, or NULL if none. | 158 // The isolate that this thread is operating on, or NULL if none. |
160 Isolate* isolate() const { return isolate_; } | 159 Isolate* isolate() const { return isolate_; } |
161 static intptr_t isolate_offset() { | 160 static intptr_t isolate_offset() { |
162 return OFFSET_OF(Thread, isolate_); | 161 return OFFSET_OF(Thread, isolate_); |
163 } | 162 } |
164 bool IsMutatorThread() const; | 163 bool IsMutatorThread() const; |
165 | 164 |
| 165 // Is |this| executing Dart code? |
| 166 bool IsExecutingDartCode() const; |
| 167 |
| 168 // Has |this| exited Dart code? |
| 169 bool HasExitedDartCode() const; |
| 170 |
166 // The (topmost) CHA for the compilation in this thread. | 171 // The (topmost) CHA for the compilation in this thread. |
167 CHA* cha() const; | 172 CHA* cha() const; |
168 void set_cha(CHA* value); | 173 void set_cha(CHA* value); |
169 | 174 |
170 int32_t no_callback_scope_depth() const { | 175 int32_t no_callback_scope_depth() const { |
171 return no_callback_scope_depth_; | 176 return no_callback_scope_depth_; |
172 } | 177 } |
173 | 178 |
174 void IncrementNoCallbackScopeDepth() { | 179 void IncrementNoCallbackScopeDepth() { |
175 ASSERT(no_callback_scope_depth_ < INT_MAX); | 180 ASSERT(no_callback_scope_depth_ < INT_MAX); |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 ThreadId id() const { | 375 ThreadId id() const { |
371 ASSERT(id_ != OSThread::kInvalidThreadId); | 376 ASSERT(id_ != OSThread::kInvalidThreadId); |
372 return id_; | 377 return id_; |
373 } | 378 } |
374 | 379 |
375 ThreadId join_id() const { | 380 ThreadId join_id() const { |
376 ASSERT(join_id_ != OSThread::kInvalidThreadJoinId); | 381 ASSERT(join_id_ != OSThread::kInvalidThreadJoinId); |
377 return join_id_; | 382 return join_id_; |
378 } | 383 } |
379 | 384 |
380 void SetThreadInterrupter(ThreadInterruptCallback callback, void* data); | 385 // Used to temporarily disable or enable thread interrupts. |
| 386 void DisableThreadInterrupts(); |
| 387 void EnableThreadInterrupts(); |
| 388 bool ThreadInterruptsEnabled(); |
381 | 389 |
382 bool IsThreadInterrupterEnabled(ThreadInterruptCallback* callback, | 390 void SetThreadInterruptCallback(ThreadInterruptCallback callback); |
383 void** data) const; | 391 |
| 392 // Returns true if *callback != null. |
| 393 bool GetThreadInterruptCallback(ThreadInterruptCallback* callback) const; |
384 | 394 |
385 #if defined(DEBUG) | 395 #if defined(DEBUG) |
386 #define REUSABLE_HANDLE_SCOPE_ACCESSORS(object) \ | 396 #define REUSABLE_HANDLE_SCOPE_ACCESSORS(object) \ |
387 void set_reusable_##object##_handle_scope_active(bool value) { \ | 397 void set_reusable_##object##_handle_scope_active(bool value) { \ |
388 reusable_##object##_handle_scope_active_ = value; \ | 398 reusable_##object##_handle_scope_active_ = value; \ |
389 } \ | 399 } \ |
390 bool reusable_##object##_handle_scope_active() const { \ | 400 bool reusable_##object##_handle_scope_active() const { \ |
391 return reusable_##object##_handle_scope_active_; \ | 401 return reusable_##object##_handle_scope_active_; \ |
392 } | 402 } |
393 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_ACCESSORS) | 403 REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_ACCESSORS) |
(...skipping 24 matching lines...) Expand all Loading... |
418 static bool IsThreadInList(ThreadId join_id); | 428 static bool IsThreadInList(ThreadId join_id); |
419 | 429 |
420 private: | 430 private: |
421 template<class T> T* AllocateReusableHandle(); | 431 template<class T> T* AllocateReusableHandle(); |
422 | 432 |
423 static ThreadLocalKey thread_key_; | 433 static ThreadLocalKey thread_key_; |
424 | 434 |
425 const ThreadId id_; | 435 const ThreadId id_; |
426 const ThreadId join_id_; | 436 const ThreadId join_id_; |
427 ThreadInterruptCallback thread_interrupt_callback_; | 437 ThreadInterruptCallback thread_interrupt_callback_; |
428 void* thread_interrupt_data_; | 438 uintptr_t thread_interrupt_disabled_; |
429 Isolate* isolate_; | 439 Isolate* isolate_; |
430 Heap* heap_; | 440 Heap* heap_; |
431 State state_; | 441 State state_; |
432 Mutex timeline_block_lock_; | 442 Mutex timeline_block_lock_; |
433 TimelineEventBlock* timeline_block_; | 443 TimelineEventBlock* timeline_block_; |
434 StoreBufferBlock* store_buffer_block_; | 444 StoreBufferBlock* store_buffer_block_; |
435 class Log* log_; | 445 class Log* log_; |
436 #define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value) \ | 446 #define DECLARE_MEMBERS(type_name, member_name, expr, default_init_value) \ |
437 type_name member_name; | 447 type_name member_name; |
438 CACHED_CONSTANTS_LIST(DECLARE_MEMBERS) | 448 CACHED_CONSTANTS_LIST(DECLARE_MEMBERS) |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 }; | 548 }; |
539 | 549 |
540 #if defined(TARGET_OS_WINDOWS) | 550 #if defined(TARGET_OS_WINDOWS) |
541 // Clears the state of the current thread and frees the allocation. | 551 // Clears the state of the current thread and frees the allocation. |
542 void WindowsThreadCleanUp(); | 552 void WindowsThreadCleanUp(); |
543 #endif | 553 #endif |
544 | 554 |
545 } // namespace dart | 555 } // namespace dart |
546 | 556 |
547 #endif // VM_THREAD_H_ | 557 #endif // VM_THREAD_H_ |
OLD | NEW |