39 ASSERT(isolate_ ==
nullptr);
40 ASSERT(store_buffer_block_ ==
nullptr);
41 ASSERT(marking_stack_block_ ==
nullptr);
45 if (api_reusable_scope_ !=
nullptr) {
46 delete api_reusable_scope_;
47 api_reusable_scope_ =
nullptr;
54#define REUSABLE_HANDLE_SCOPE_INIT(object) \
55 reusable_##object##_handle_scope_active_(false),
57#define REUSABLE_HANDLE_SCOPE_INIT(object)
60#define REUSABLE_HANDLE_INITIALIZERS(object) object##_handle_(nullptr),
64 write_barrier_mask_(UntaggedObject::kGenerationalBarrierMask),
65 active_exception_(Object::null()),
66 active_stacktrace_(Object::null()),
67 global_object_pool_(ObjectPool::null()),
69 execution_state_(kThreadInNative),
71 api_top_scope_(nullptr),
72 double_truncate_round_supported_(
73 TargetCPUFeatures::double_truncate_round_supported() ? 1 : 0),
75 task_kind_(kUnknownTask),
79 dart_stream_(nullptr),
82 service_extension_stream_(
ASSERT_NOTNULL(&Service::extension_stream)),
84 service_extension_stream_(nullptr),
87 api_reusable_scope_(nullptr),
88 no_callback_scope_depth_(0),
90 no_safepoint_scope_depth_(0),
93 stack_overflow_count_(0),
94 hierarchy_info_(nullptr),
95 type_usage_info_(nullptr),
96 sticky_error_(Error::null()),
99#
if defined(USING_SAFE_STACK)
100 saved_safestack_limit_(0),
102#
if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
104 heap_sampler_(this) {
109#define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \
110 member_name = default_init_value;
114 for (intptr_t i = 0; i < kNumberOfDartAvailableCpuRegs; ++i) {
115 write_barrier_wrappers_entry_points_[i] = 0;
118#define DEFAULT_INIT(name) name##_entry_point_ = 0;
122#define DEFAULT_INIT(returntype, name, ...) name##_entry_point_ = 0;
128 if (!is_vm_isolate) {
132#if defined(DART_HOST_OS_FUCHSIA)
133 next_task_id_ = trace_generate_nonce();
135 next_task_id_ = Random::GlobalNextUInt64();
138 memset(&unboxed_runtime_arg_, 0,
sizeof(simd128_value_t));
146} double_negate_constant = {0x8000000000000000ULL, 0x8000000000000000ULL};
151} double_abs_constant = {0x7FFFFFFFFFFFFFFFULL, 0x7FFFFFFFFFFFFFFFULL};
158} float_not_constant = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF};
165} float_negate_constant = {0x80000000, 0x80000000, 0x80000000, 0x80000000};
172} float_absolute_constant = {0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF};
179} float_zerow_constant = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000};
181void Thread::InitVMConstants() {
182#if defined(DART_COMPRESSED_POINTERS)
183 heap_base_ = Object::null()->heap_base();
186#define ASSERT_VM_HEAP(type_name, member_name, init_expr, default_init_value) \
187 ASSERT((init_expr)->IsOldObject());
191#define INIT_VALUE(type_name, member_name, init_expr, default_init_value) \
192 ASSERT(member_name == default_init_value); \
193 member_name = (init_expr);
198 write_barrier_wrappers_entry_points_[i] =
199 StubCode::WriteBarrierWrappers().EntryPoint() +
203#define INIT_VALUE(name) \
204 ASSERT(name##_entry_point_ == 0); \
205 name##_entry_point_ = k##name##RuntimeEntry.GetEntryPoint();
209#define INIT_VALUE(returntype, name, ...) \
210 ASSERT(name##_entry_point_ == 0); \
211 name##_entry_point_ = k##name##RuntimeEntry.GetEntryPoint();
216#define REUSABLE_HANDLE_ALLOCATION(object) \
217 this->object##_handle_ = this->AllocateReusableHandle<object>();
219#undef REUSABLE_HANDLE_ALLOCATION
222void Thread::set_active_exception(
const Object& value) {
223 active_exception_ =
value.ptr();
226void Thread::set_active_stacktrace(
const Object& value) {
227 active_stacktrace_ =
value.ptr();
230ErrorPtr Thread::sticky_error()
const {
231 return sticky_error_;
234void Thread::set_sticky_error(
const Error& value) {
236 sticky_error_ =
value.ptr();
239void Thread::ClearStickyError() {
240 sticky_error_ = Error::null();
243ErrorPtr Thread::StealStickyError() {
245 ErrorPtr return_value = sticky_error_;
246 sticky_error_ = Error::null();
250const char* Thread::TaskKindToCString(
TaskKind kind) {
253 return "kUnknownTask";
255 return "kMutatorTask";
257 return "kCompilerTask";
259 return "kSweeperTask";
261 return "kMarkerTask";
268void Thread::AssertNonMutatorInvariants() {
269 ASSERT(BypassSafepoints());
270 ASSERT(store_buffer_block_ ==
nullptr);
271 ASSERT(marking_stack_block_ ==
nullptr);
272 ASSERT(deferred_marking_stack_block_ ==
nullptr);
273 AssertNonDartMutatorInvariants();
276void Thread::AssertNonDartMutatorInvariants() {
277 ASSERT(!IsDartMutatorThread());
278 ASSERT(isolate() ==
nullptr);
279 ASSERT(isolate_group() !=
nullptr);
280 ASSERT(task_kind_ != kMutatorTask);
284void Thread::AssertEmptyStackInvariants() {
285 ASSERT(zone() ==
nullptr);
286 ASSERT(top_handle_scope() ==
nullptr);
287 ASSERT(long_jump_base() ==
nullptr);
288 ASSERT(top_resource() ==
nullptr);
289 ASSERT(top_exit_frame_info_ == 0);
290 ASSERT(api_top_scope_ ==
nullptr);
291 ASSERT(!pending_deopts_.HasPendingDeopts());
292 ASSERT(compiler_state_ ==
nullptr);
293 ASSERT(hierarchy_info_ ==
nullptr);
294 ASSERT(type_usage_info_ ==
nullptr);
295 ASSERT(no_active_isolate_scope_ ==
nullptr);
296 ASSERT(compiler_timings_ ==
nullptr);
297 ASSERT(!exit_through_ffi_);
298 ASSERT(runtime_call_deopt_ability_ == RuntimeCallDeoptAbility::kCanLazyDeopt);
299 ASSERT(no_callback_scope_depth_ == 0);
300 ASSERT(force_growth_scope_depth_ == 0);
301 ASSERT(no_reload_scope_depth_ == 0);
302 ASSERT(stopped_mutators_scope_depth_ == 0);
303 ASSERT(stack_overflow_flags_ == 0);
308 if (active_stacktrace_.untag() != 0) {
309 ASSERT(sticky_error() == Error::null());
310 ASSERT(active_exception_ == Object::null());
311 ASSERT(active_stacktrace_ == Object::null());
315void Thread::AssertEmptyThreadInvariants() {
316 AssertEmptyStackInvariants();
321 ASSERT(isolate_ ==
nullptr);
322 ASSERT(isolate_group_ ==
nullptr);
323 ASSERT(os_thread() ==
nullptr);
324 ASSERT(vm_tag_ == VMTag::kInvalidTagId);
325 ASSERT(task_kind_ == kUnknownTask);
326 ASSERT(execution_state_ == Thread::kThreadInNative);
327 ASSERT(scheduled_dart_mutator_isolate_ ==
nullptr);
329 ASSERT(write_barrier_mask_ == UntaggedObject::kGenerationalBarrierMask);
330 ASSERT(store_buffer_block_ ==
nullptr);
331 ASSERT(marking_stack_block_ ==
nullptr);
332 ASSERT(deferred_marking_stack_block_ ==
nullptr);
333 ASSERT(!is_unwind_in_progress_);
335 ASSERT(saved_stack_limit_ == OSThread::kInvalidStackLimit);
336 ASSERT(stack_limit_.load() == 0);
337 ASSERT(safepoint_state_ == 0);
340 if (active_stacktrace_.untag() != 0) {
341 ASSERT(field_table_values_ ==
nullptr);
342 ASSERT(global_object_pool_ == Object::null());
343#define CHECK_REUSABLE_HANDLE(object) ASSERT(object##_handle_->IsNull());
345#undef CHECK_REUSABLE_HANDLE
349bool Thread::HasActiveState() {
351 if (top_exit_frame_info() != 0) {
355 if (api_top_scope() !=
nullptr) {
359 if (zone() !=
nullptr) {
362 AssertEmptyStackInvariants();
371 const bool is_nested_reenter =
374 auto group = isolate->
group();
376 group->IncreaseMutatorCount(isolate, is_nested_reenter);
387 ASSERT(thread->scheduled_dart_mutator_isolate_ == isolate);
396 thread = AddActiveThread(group, isolate,
true,
398 thread->SetupState(kMutatorTask);
399 thread->SetupMutatorState(kMutatorTask);
400 thread->SetupDartMutatorState(isolate);
404 ResumeDartMutatorThreadInternal(thread);
409 if (isolate_shutdown)
return false;
417 const intptr_t kMaxSuspendedThreads = 20;
419 return group->thread_registry()->active_isolates_count() <
420 kMaxSuspendedThreads;
423void Thread::ExitIsolate(
bool isolate_shutdown) {
424 Thread* thread = Thread::Current();
425 ASSERT(thread !=
nullptr);
431 DEBUG_ASSERT(!thread->IsAnyReusableHandleScopeActive());
433 auto isolate = thread->
isolate();
436 thread->
set_vm_tag(isolate->is_runnable() ? VMTag::kIdleTagId
437 : VMTag::kLoadWaitTagId);
439 ASSERT(isolate->sticky_error_ == Error::null());
443 isolate->scheduled_mutator_thread_ =
nullptr;
452 isolate->is_runnable() ? VMTag::kIdleTagId : VMTag::kLoadWaitTagId;
453 SuspendDartMutatorThreadInternal(thread, tag);
461 thread->ResetDartMutatorState(isolate);
462 thread->ResetMutatorState();
463 thread->ResetState();
464 SuspendDartMutatorThreadInternal(thread, VMTag::kInvalidTagId);
465 FreeActiveThread(thread,
false);
470 ASSERT(!(isolate_shutdown && is_nested_exit));
472 group->DecreaseMutatorCount(isolate, is_nested_exit);
478 bool bypass_safepoint) {
479 Thread* thread = AddActiveThread(isolate_group,
nullptr,
480 false, bypass_safepoint);
481 if (thread !=
nullptr) {
482 thread->SetupState(kind);
485 thread->SetupMutatorState(kind);
486 ResumeThreadInternal(thread);
494void Thread::ExitIsolateGroupAsHelper(
bool bypass_safepoint) {
495 Thread* thread = Thread::Current();
500 thread->ResetMutatorState();
501 thread->ResetState();
502 SuspendThreadInternal(thread, VMTag::kInvalidTagId);
503 FreeActiveThread(thread, bypass_safepoint);
509 AddActiveThread(isolate_group,
nullptr,
511 if (thread !=
nullptr) {
512 thread->SetupState(kind);
513 ResumeThreadInternal(thread);
521void Thread::ExitIsolateGroupAsNonMutator() {
522 Thread* thread = Thread::Current();
523 ASSERT(thread !=
nullptr);
526 thread->ResetState();
527 SuspendThreadInternal(thread, VMTag::kInvalidTagId);
528 FreeActiveThread(thread,
true);
531void Thread::ResumeDartMutatorThreadInternal(
Thread* thread) {
532 ResumeThreadInternal(thread);
533 if (Dart::vm_isolate() !=
nullptr &&
534 thread->
isolate() != Dart::vm_isolate()) {
535#if defined(USING_SIMULATOR)
536 thread->
SetStackLimit(Simulator::Current()->overflow_stack_limit());
538 thread->
SetStackLimit(OSThread::Current()->overflow_stack_limit());
543void Thread::SuspendDartMutatorThreadInternal(Thread* thread,
544 VMTag::VMTagId tag) {
545 thread->ClearStackLimit();
546 SuspendThreadInternal(thread, tag);
549void Thread::ResumeThreadInternal(Thread* thread) {
550 ASSERT(!thread->IsAtSafepoint());
551 ASSERT(thread->isolate_group() !=
nullptr);
552 ASSERT(thread->execution_state() == Thread::kThreadInNative);
553 ASSERT(thread->vm_tag() == VMTag::kInvalidTagId ||
554 thread->vm_tag() == VMTag::kIdleTagId ||
555 thread->vm_tag() == VMTag::kLoadWaitTagId);
557 thread->set_vm_tag(VMTag::kVMTagId);
558 thread->set_execution_state(Thread::kThreadInVM);
560 OSThread* os_thread = OSThread::Current();
561 thread->set_os_thread(os_thread);
562 os_thread->set_thread(thread);
563 Thread::SetCurrent(thread);
566#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
567 thread->heap_sampler().Initialize();
571void Thread::SuspendThreadInternal(Thread* thread, VMTag::VMTagId tag) {
572 thread->heap()->new_space()->AbandonRemainingTLAB(thread);
574#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
575 thread->heap_sampler().Cleanup();
578 OSThread* os_thread = thread->os_thread();
579 ASSERT(os_thread !=
nullptr);
581 os_thread->set_thread(
nullptr);
582 OSThread::SetCurrent(os_thread);
583 thread->set_os_thread(
nullptr);
585 thread->set_vm_tag(tag);
588Thread* Thread::AddActiveThread(IsolateGroup* group,
590 bool is_dart_mutator,
591 bool bypass_safepoint) {
594 const bool is_vm_isolate =
595 Dart::vm_isolate() ==
nullptr || Dart::vm_isolate() == isolate;
597 auto thread_registry =
group->thread_registry();
598 auto safepoint_handler =
group->safepoint_handler();
599 MonitorLocker ml(thread_registry->threads_lock());
601 if (!bypass_safepoint) {
602 while (safepoint_handler->AnySafepointInProgressLocked()) {
607 Thread* thread = thread_registry->GetFreeThreadLocked(is_vm_isolate);
608 thread->AssertEmptyThreadInvariants();
610 thread->isolate_ = isolate;
611 thread->isolate_group_ =
group;
612 thread->scheduled_dart_mutator_isolate_ = isolate;
616 thread->set_safepoint_state(Thread::SetBypassSafepoints(bypass_safepoint, 0));
617 thread->runtime_call_deopt_ability_ = RuntimeCallDeoptAbility::kCanLazyDeopt;
618 ASSERT(!thread->IsAtSafepoint());
620 ASSERT(thread->saved_stack_limit_ == OSThread::kInvalidStackLimit);
624void Thread::FreeActiveThread(Thread* thread,
bool bypass_safepoint) {
625 ASSERT(!thread->HasActiveState());
626 ASSERT(!thread->IsAtSafepoint());
628 if (!bypass_safepoint) {
633 thread->ClearReusableHandles();
636 auto group = thread->isolate_group_;
637 auto thread_registry =
group->thread_registry();
639 MonitorLocker ml(thread_registry->threads_lock());
641 if (!bypass_safepoint) {
657 RawReloadParticipationScope enable_reload(thread);
658 thread->EnterSafepoint();
661 thread->isolate_ =
nullptr;
662 thread->isolate_group_ =
nullptr;
663 thread->scheduled_dart_mutator_isolate_ =
nullptr;
664 thread->set_execution_state(Thread::kThreadInNative);
665 thread->stack_limit_.store(0);
666 thread->safepoint_state_ = 0;
668 thread->AssertEmptyThreadInvariants();
669 thread_registry->ReturnThreadLocked(thread);
672void Thread::ReleaseStoreBuffer() {
673 ASSERT(IsAtSafepoint() || OwnsSafepoint());
674 if (store_buffer_block_ ==
nullptr || store_buffer_block_->IsEmpty()) {
678 StoreBufferRelease(StoreBuffer::kIgnoreThreshold);
682 store_buffer_block_ = isolate_group()->store_buffer()->PopEmptyBlock();
685void Thread::SetStackLimit(
uword limit) {
689 if (!HasScheduledInterrupts()) {
691 stack_limit_.store(limit);
693 saved_stack_limit_ = limit;
696void Thread::ClearStackLimit() {
697 SetStackLimit(OSThread::kInvalidStackLimit);
701 return (limit & ~Thread::kInterruptsMask) ==
702 (kInterruptStackLimit &
~Thread::kInterruptsMask);
705void Thread::ScheduleInterrupts(
uword interrupt_bits) {
706 ASSERT((interrupt_bits & ~kInterruptsMask) == 0);
708 uword old_limit = stack_limit_.load();
712 new_limit = old_limit | interrupt_bits;
714 new_limit = (kInterruptStackLimit & ~kInterruptsMask) | interrupt_bits;
716 }
while (!stack_limit_.compare_exchange_weak(old_limit, new_limit));
719uword Thread::GetAndClearInterrupts() {
720 uword interrupt_bits = 0;
721 uword old_limit = stack_limit_.load();
722 uword new_limit = saved_stack_limit_;
725 interrupt_bits = interrupt_bits | (old_limit & kInterruptsMask);
727 return interrupt_bits;
729 }
while (!stack_limit_.compare_exchange_weak(old_limit, new_limit));
731 return interrupt_bits;
734ErrorPtr Thread::HandleInterrupts() {
735 uword interrupt_bits = GetAndClearInterrupts();
736 if ((interrupt_bits & kVMInterrupt) != 0) {
738 if (isolate_group()->store_buffer()->Overflowed()) {
742 heap()->CollectGarbage(
this, GCType::kEvacuate, GCReason::kStoreBuffer);
744 heap()->CheckFinalizeMarking(
this);
747 if (isolate()->TakeHasCompletedBlocks()) {
748 Profiler::ProcessCompletedBlocks(isolate());
752#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
762 if ((interrupt_bits & kMessageInterrupt) != 0) {
764 isolate()->message_handler()->HandleOOBMessages();
765 if (status != MessageHandler::kOK) {
768 if (FLAG_trace_isolates) {
770 "[!] Terminating isolate due to OOB message:\n"
774 return StealStickyError();
777 return Error::null();
780uword Thread::GetAndClearStackOverflowFlags() {
781 uword stack_overflow_flags = stack_overflow_flags_;
782 stack_overflow_flags_ = 0;
783 return stack_overflow_flags;
787 StoreBufferRelease(policy);
788 StoreBufferAcquire();
792 ASSERT(
this == Thread::Current());
793 store_buffer_block_->Push(obj);
794 if (store_buffer_block_->IsFull()) {
795 StoreBufferBlockProcess(StoreBuffer::kCheckThreshold);
800 store_buffer_block_->Push(obj);
801 if (store_buffer_block_->IsFull()) {
802 StoreBufferBlockProcess(StoreBuffer::kIgnoreThreshold);
808 store_buffer_block_ =
nullptr;
809 isolate_group()->store_buffer()->PushBlock(block, policy);
812void Thread::StoreBufferAcquire() {
813 store_buffer_block_ = isolate_group()->store_buffer()->PopNonFullBlock();
816void Thread::MarkingStackBlockProcess() {
817 MarkingStackRelease();
818 MarkingStackAcquire();
821void Thread::DeferredMarkingStackBlockProcess() {
822 DeferredMarkingStackRelease();
823 DeferredMarkingStackAcquire();
827 marking_stack_block_->Push(obj);
828 if (marking_stack_block_->IsFull()) {
829 MarkingStackBlockProcess();
833void Thread::DeferredMarkingStackAddObject(
ObjectPtr obj) {
834 deferred_marking_stack_block_->Push(obj);
835 if (deferred_marking_stack_block_->IsFull()) {
836 DeferredMarkingStackBlockProcess();
840void Thread::MarkingStackRelease() {
842 marking_stack_block_ =
nullptr;
843 write_barrier_mask_ = UntaggedObject::kGenerationalBarrierMask;
844 isolate_group()->marking_stack()->PushBlock(block);
847void Thread::MarkingStackAcquire() {
848 marking_stack_block_ = isolate_group()->marking_stack()->PopEmptyBlock();
849 write_barrier_mask_ = UntaggedObject::kGenerationalBarrierMask |
850 UntaggedObject::kIncrementalBarrierMask;
853void Thread::MarkingStackFlush() {
854 isolate_group()->marking_stack()->PushBlock(marking_stack_block_);
855 marking_stack_block_ = isolate_group()->marking_stack()->PopEmptyBlock();
858void Thread::DeferredMarkingStackRelease() {
860 deferred_marking_stack_block_ =
nullptr;
861 isolate_group()->deferred_marking_stack()->PushBlock(block);
864void Thread::DeferredMarkingStackAcquire() {
865 deferred_marking_stack_block_ =
866 isolate_group()->deferred_marking_stack()->PopEmptyBlock();
869void Thread::DeferredMarkingStackFlush() {
870 isolate_group()->deferred_marking_stack()->PushBlock(
871 deferred_marking_stack_block_);
872 deferred_marking_stack_block_ =
873 isolate_group()->deferred_marking_stack()->PopEmptyBlock();
877 return isolate_group_->heap();
880bool Thread::IsExecutingDartCode()
const {
881 return (top_exit_frame_info() == 0) && VMTag::IsDartTag(vm_tag());
884bool Thread::HasExitedDartCode()
const {
885 return (top_exit_frame_info() != 0) && !VMTag::IsDartTag(vm_tag());
889C* Thread::AllocateReusableHandle() {
890 C* handle =
reinterpret_cast<C*
>(reusable_handles_.AllocateScopedHandle());
891 C::initializeHandle(handle, C::null());
895void Thread::ClearReusableHandles() {
896#define CLEAR_REUSABLE_HANDLE(object) *object##_handle_ = object::null();
898#undef CLEAR_REUSABLE_HANDLE
903 ASSERT(visitor !=
nullptr);
905 if (zone() !=
nullptr) {
906 zone()->VisitObjectPointers(visitor);
910 reusable_handles_.VisitObjectPointers(visitor);
919 while (scope !=
nullptr) {
925 if (IsDartMutatorThread()) {
937 StackFrameIterator::kAllowCrossThreadIteration;
941 this, cross_thread_policy);
944 while (
frame !=
nullptr) {
945 frame->VisitObjectPointers(visitor);
959 Thread::RestoreWriteBarrierInvariantOp op)
962 current_(
Thread::Current()),
966 for (; first != last + 1; first++) {
969 if (obj->IsImmediateObject())
continue;
976 if (
length > Array::kMaxLengthForWriteBarrierElimination) {
985 !obj->IsUnhandledException())
997 case Thread::RestoreWriteBarrierInvariantOp::kAddToRememberedSet:
998 if (obj->IsOldObject()) {
1001 if (current_->is_marking()) {
1002 current_->DeferredMarkingStackAddObject(obj);
1005 case Thread::RestoreWriteBarrierInvariantOp::kAddToDeferredMarkingStack:
1007 ASSERT(current_->is_marking());
1008 current_->DeferredMarkingStackAddObject(obj);
1014#if defined(DART_COMPRESSED_POINTERS)
1015 void VisitCompressedPointers(
uword heap_base,
1023 Thread*
const thread_;
1024 Thread*
const current_;
1025 Thread::RestoreWriteBarrierInvariantOp op_;
1039void Thread::RestoreWriteBarrierInvariant(RestoreWriteBarrierInvariantOp op) {
1040 ASSERT(IsAtSafepoint() || OwnsGCSafepoint() ||
this == Thread::Current());
1042 const StackFrameIterator::CrossThreadPolicy cross_thread_policy =
1043 StackFrameIterator::kAllowCrossThreadIteration;
1044 StackFrameIterator frames_iterator(top_exit_frame_info(),
1045 ValidationPolicy::kDontValidateFrames,
1046 this, cross_thread_policy);
1047 RestoreWriteBarrierInvariantVisitor visitor(isolate_group(),
this, op);
1048 ObjectStore* object_store = isolate_group()->object_store();
1049 bool scan_next_dart_frame =
false;
1050 for (StackFrame*
frame = frames_iterator.NextFrame();
frame !=
nullptr;
1051 frame = frames_iterator.NextFrame()) {
1052 if (
frame->IsExitFrame()) {
1053 scan_next_dart_frame =
true;
1054 }
else if (
frame->IsEntryFrame()) {
1056 }
else if (
frame->IsStubFrame()) {
1058 if (Code::ContainsInstructionAt(
1059 object_store->init_late_static_field_stub(), pc) ||
1060 Code::ContainsInstructionAt(
1061 object_store->init_late_final_static_field_stub(), pc) ||
1062 Code::ContainsInstructionAt(
1063 object_store->init_late_instance_field_stub(), pc) ||
1064 Code::ContainsInstructionAt(
1065 object_store->init_late_final_instance_field_stub(), pc)) {
1066 scan_next_dart_frame =
true;
1070 if (scan_next_dart_frame) {
1071 frame->VisitObjectPointers(&visitor);
1073 scan_next_dart_frame =
false;
1078void Thread::DeferredMarkLiveTemporaries() {
1079 RestoreWriteBarrierInvariant(
1080 RestoreWriteBarrierInvariantOp::kAddToDeferredMarkingStack);
1083void Thread::RememberLiveTemporaries() {
1084 RestoreWriteBarrierInvariant(
1085 RestoreWriteBarrierInvariantOp::kAddToRememberedSet);
1088bool Thread::CanLoadFromThread(
const Object&
object) {
1092 if (
object.IsCode()) {
1093#define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \
1094 if (object.ptr() == expr) { \
1103#define CHECK_OBJECT(type_name, member_name, expr, default_init_value) \
1104 if (object.ptr() == expr) { \
1112intptr_t Thread::OffsetFromThread(
const Object&
object) {
1116 if (
object.IsCode()) {
1117#define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \
1118 ASSERT((expr)->untag()->InVMIsolateHeap()); \
1119 if (object.ptr() == expr) { \
1120 return Thread::member_name##offset(); \
1123#undef COMPUTE_OFFSET
1128#define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \
1129 if (object.ptr() == expr) { \
1130 return Thread::member_name##offset(); \
1133#undef COMPUTE_OFFSET
1140 if (Isolate::Current() == Dart::vm_isolate()) {
1146#define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value) \
1147 if (Thread::member_name##offset() == offset) { \
1152#undef COMPUTE_OFFSET
1157#define COMPUTE_OFFSET(name) \
1158 if (runtime_entry == &k##name##RuntimeEntry) { \
1159 return Thread::name##_entry_point_offset(); \
1162#undef COMPUTE_OFFSET
1164#define COMPUTE_OFFSET(returntype, name, ...) \
1165 if (runtime_entry == &k##name##RuntimeEntry) { \
1166 return Thread::name##_entry_point_offset(); \
1169#undef COMPUTE_OFFSET
1176bool Thread::TopErrorHandlerIsSetJump()
const {
1177 if (long_jump_base() ==
nullptr)
return false;
1178 if (top_exit_frame_info_ == 0)
return true;
1179#if defined(USING_SIMULATOR) || defined(USING_SAFE_STACK)
1183 return reinterpret_cast<uword>(long_jump_base()) < top_exit_frame_info_;
1187bool Thread::TopErrorHandlerIsExitFrame()
const {
1188 if (top_exit_frame_info_ == 0)
return false;
1189 if (long_jump_base() ==
nullptr)
return true;
1190#if defined(USING_SIMULATOR) || defined(USING_SAFE_STACK)
1194 return top_exit_frame_info_ < reinterpret_cast<uword>(long_jump_base());
1200 return IsValidLocalHandle(
object) || IsValidZoneHandle(
object) ||
1201 IsValidScopedHandle(
object);
1206 while (scope !=
nullptr) {
1215intptr_t Thread::CountLocalHandles()
const {
1218 while (scope !=
nullptr) {
1225int Thread::ZoneSizeInBytes()
const {
1228 while (scope !=
nullptr) {
1235void Thread::EnterApiScope() {
1236 ASSERT(MayAllocateHandles());
1238 if (new_scope ==
nullptr) {
1239 new_scope =
new ApiLocalScope(api_top_scope(), top_exit_frame_info());
1240 ASSERT(new_scope !=
nullptr);
1242 new_scope->
Reinit(
this, api_top_scope(), top_exit_frame_info());
1243 set_api_reusable_scope(
nullptr);
1245 set_api_top_scope(new_scope);
1248void Thread::ExitApiScope() {
1249 ASSERT(MayAllocateHandles());
1252 set_api_top_scope(scope->
previous());
1253 if (reusable_scope ==
nullptr) {
1255 set_api_reusable_scope(scope);
1257 ASSERT(reusable_scope != scope);
1262void Thread::UnwindScopes(
uword stack_marker) {
1266 while (scope !=
nullptr && scope->
stack_marker() != 0 &&
1268 api_top_scope_ = scope->
previous();
1270 scope = api_top_scope_;
1274void Thread::EnterSafepointUsingLock() {
1275 isolate_group()->safepoint_handler()->EnterSafepointUsingLock(
this);
1278void Thread::ExitSafepointUsingLock() {
1279 isolate_group()->safepoint_handler()->ExitSafepointUsingLock(
this);
1282void Thread::BlockForSafepoint() {
1283 isolate_group()->safepoint_handler()->BlockForSafepoint(
this);
1286bool Thread::OwnsGCSafepoint()
const {
1287 return isolate_group()->safepoint_handler()->InnermostSafepointOperation(
1288 this) <= SafepointLevel::kGCAndDeopt;
1291bool Thread::OwnsDeoptSafepoint()
const {
1292 return isolate_group()->safepoint_handler()->InnermostSafepointOperation(
1293 this) == SafepointLevel::kGCAndDeopt;
1296bool Thread::OwnsReloadSafepoint()
const {
1297 return isolate_group()->safepoint_handler()->InnermostSafepointOperation(
1298 this) <= SafepointLevel::kGCAndDeoptAndReload;
1301bool Thread::OwnsSafepoint()
const {
1302 return isolate_group()->safepoint_handler()->InnermostSafepointOperation(
1303 this) != SafepointLevel::kNoSafepoint;
1306bool Thread::CanAcquireSafepointLocks()
const {
1321 return isolate_group()->safepoint_handler()->InnermostSafepointOperation(
1322 this) >= SafepointLevel::kGCAndDeoptAndReload;
1325void Thread::SetupState(TaskKind kind) {
1329void Thread::ResetState() {
1330 task_kind_ = kUnknownTask;
1331 vm_tag_ = VMTag::kInvalidTagId;
1334void Thread::SetupMutatorState(TaskKind kind) {
1335 ASSERT(store_buffer_block_ ==
nullptr);
1337 if (isolate_group()->marking_stack() !=
nullptr) {
1339 MarkingStackAcquire();
1340 DeferredMarkingStackAcquire();
1345 if (kind == kMutatorTask) {
1346 StoreBufferAcquire();
1348 store_buffer_block_ = isolate_group()->store_buffer()->PopEmptyBlock();
1352void Thread::ResetMutatorState() {
1353 ASSERT(execution_state() == Thread::kThreadInVM);
1354 ASSERT(store_buffer_block_ !=
nullptr);
1357 MarkingStackRelease();
1358 DeferredMarkingStackRelease();
1360 StoreBufferRelease();
1363void Thread::SetupDartMutatorState(Isolate* isolate) {
1364 field_table_values_ = isolate->field_table_->table();
1365 isolate->mutator_thread_ =
this;
1367 SetupDartMutatorStateDependingOnSnapshot(isolate->group());
1370void Thread::SetupDartMutatorStateDependingOnSnapshot(IsolateGroup* group) {
1377#if defined(DART_PRECOMPILED_RUNTIME)
1378 auto object_store =
group->object_store();
1379 if (object_store !=
nullptr) {
1380 global_object_pool_ = object_store->global_object_pool();
1382 auto dispatch_table =
group->dispatch_table();
1383 if (dispatch_table !=
nullptr) {
1384 dispatch_table_array_ = dispatch_table->ArrayOrigin();
1386#define INIT_ENTRY_POINT(name) \
1387 if (object_store->name() != Object::null()) { \
1388 name##_entry_point_ = Function::EntryPointOf(object_store->name()); \
1391#undef INIT_ENTRY_POINT
1396void Thread::ResetDartMutatorState(Isolate* isolate) {
1397 ASSERT(execution_state() == Thread::kThreadInVM);
1399 isolate->mutator_thread_ =
nullptr;
1400 is_unwind_in_progress_ =
false;
1402 field_table_values_ =
nullptr;
1407#if !defined(PRODUCT)
1408DisableThreadInterruptsScope::DisableThreadInterruptsScope(
Thread* thread)
1412 ASSERT(os_thread !=
nullptr);
1418 if (
thread() !=
nullptr) {
1420 ASSERT(os_thread !=
nullptr);
1427#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
1428 thread->no_reload_scope_depth_++;
1434#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
1435 thread()->no_reload_scope_depth_ -= 1;
1440 if (
thread()->no_reload_scope_depth_ == 0) {
#define DEBUG_ASSERT(cond)
#define RELEASE_ASSERT(cond)
#define ASSERT_NOTNULL(ptr)
uword stack_marker() const
void Reinit(Thread *thread, ApiLocalScope *previous, uword stack_marker)
LocalHandles * local_handles()
ApiLocalScope * previous() const
void Reset(Thread *thread)
Thread * scheduled_mutator_thread_
~DisableThreadInterruptsScope()
void SetThreadSamplingInterval()
void UpdateThreadEnable()
bool ShouldSetThreadSamplingInterval()
bool ShouldUpdateThreadEnable()
void SendInternalLibMessage(LibMsgId msg_id, uint64_t capability)
IsolateGroup * group() const
Thread * mutator_thread() const
void VisitObjectPointers(ObjectPointerVisitor *visitor)
bool IsValidHandle(Dart_Handle object) const
NoReloadScope(Thread *thread)
void DisableThreadInterrupts()
void EnableThreadInterrupts()
void clear_gc_root_type()
void set_gc_root_type(const char *gc_root_type)
void VisitPointer(ObjectPtr *p)
bool IsDartInstance() const
UntaggedObject * untag() const
intptr_t GetClassId() const
void VisitPointers(ObjectPtr *first, ObjectPtr *last) override
RestoreWriteBarrierInvariantVisitor(IsolateGroup *group, Thread *thread, Thread::RestoreWriteBarrierInvariantOp op)
ThreadState * thread() const
Isolate * isolate() const
OSThread * os_thread() const
void set_execution_state(ExecutionState state)
void set_vm_tag(uword tag)
ApiLocalScope * api_top_scope() const
bool OwnsSafepoint() const
void AssertNonMutatorInvariants()
DART_WARN_UNUSED_RESULT ErrorPtr StealStickyError()
void SetStackLimit(uword value)
static bool IsSafepointLevelRequested(uword state, SafepointLevel level)
friend class compiler::target::Thread
void AssertNonDartMutatorInvariants()
uword top_exit_frame_info() const
bool IsDartMutatorThread() const
Isolate * isolate() const
IsolateGroup * isolate_group() const
ErrorPtr sticky_error() const
DART_FORCE_INLINE void EnsureInRememberedSet(Thread *thread)
bool InVMIsolateHeap() const
uintptr_t SizeInBytes() const
struct _Dart_Handle * Dart_Handle
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
#define DECLARE_FLAG(type, name)
static bool ShouldSuspend(bool isolate_shutdown, Thread *thread)
MarkingStack::Block MarkingStackBlock
static const double double_nan_constant
const intptr_t kStoreBufferWrapperSize
raw_obj untag() -> num_entries()) VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->untag() ->length())) VARIABLE_COMPRESSED_VISITOR(TypedData, TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *Smi::Value(raw_obj->untag() ->length())) VARIABLE_COMPRESSED_VISITOR(Record, RecordShape(raw_obj->untag() ->shape()).num_fields()) VARIABLE_NULL_VISITOR(CompressedStackMaps, CompressedStackMaps::PayloadSizeOf(raw_obj)) VARIABLE_NULL_VISITOR(OneByteString, Smi::Value(raw_obj->untag() ->length())) VARIABLE_NULL_VISITOR(TwoByteString, Smi::Value(raw_obj->untag() ->length())) intptr_t UntaggedField::VisitFieldPointers(FieldPtr raw_obj, ObjectPointerVisitor *visitor)
static bool IsInterruptLimit(uword limit)
constexpr int kNumberOfDartAvailableCpuRegs
#define RUNTIME_ENTRY_LIST(V)
#define LEAF_RUNTIME_ENTRY_LIST(V)
#define CHECK_REUSABLE_HANDLE(object)
#define INIT_VALUE(type_name, member_name, init_expr, default_init_value)
#define COMPUTE_OFFSET(type_name, member_name, expr, default_init_value)
#define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value)
#define CLEAR_REUSABLE_HANDLE(object)
#define ASSERT_VM_HEAP(type_name, member_name, init_expr, default_init_value)
#define REUSABLE_HANDLE_ALLOCATION(object)
#define CHECK_OBJECT(type_name, member_name, expr, default_init_value)
#define CACHED_FUNCTION_ENTRY_POINTS_LIST(V)
#define REUSABLE_HANDLE_LIST(V)
#define CACHED_CONSTANTS_LIST(V)
#define CACHED_NON_VM_STUB_LIST(V)
#define CACHED_VM_STUBS_LIST(V)
#define CACHED_VM_OBJECTS_LIST(V)
#define DO_IF_NOT_TSAN(CODE)
#define NOT_IN_PRODUCT(code)
#define ONLY_IN_PRECOMPILED(code)
#define REUSABLE_HANDLE_SCOPE_INIT(object)
#define REUSABLE_HANDLE_INITIALIZERS(object)