diff --git a/pkg/dart_internal/lib/isolate_group.dart b/pkg/dart_internal/lib/isolate_group.dart new file mode 100644 index 00000000000..be487f78e7e --- /dev/null +++ b/pkg/dart_internal/lib/isolate_group.dart @@ -0,0 +1,6 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +// ignore: export_internal_library +export 'dart:_internal' show IsolateGroup; diff --git a/runtime/lib/concurrent.cc b/runtime/lib/concurrent.cc index 12ab35d7494..49e609723c5 100644 --- a/runtime/lib/concurrent.cc +++ b/runtime/lib/concurrent.cc @@ -110,4 +110,45 @@ DEFINE_FFI_NATIVE_ENTRY(ConditionVariable_NotifyAll, condvar->NotifyAll(); } +DEFINE_FFI_NATIVE_ENTRY(IsolateGroup_runSync, + Dart_Handle, + (Dart_Handle closure)) { + Thread* current_thread = Thread::Current(); + ASSERT(current_thread->execution_state() == Thread::kThreadInNative); + Isolate* saved_isolate = current_thread->isolate(); + current_thread->ExitSafepointFromNative(); + current_thread->set_execution_state(Thread::kThreadInVM); + Thread::ExitIsolate(/*isolate_shutdown=*/false); + + Thread::EnterIsolateGroupAsMutator(current_thread->isolate_group(), + /*bypass_safepoint=*/false); + + auto mutator_thread = Thread::Current(); + + ApiState* state = mutator_thread->isolate_group()->api_state(); + ASSERT(state != nullptr); + mutator_thread->EnterApiScope(); + ASSERT(mutator_thread->execution_state() == Thread::kThreadInVM); + + Dart_PersistentHandle persistent_result; + { + TransitionVMToNative transition(mutator_thread); + Dart_Handle result = Dart_InvokeClosure(closure, 0, nullptr); + persistent_result = Dart_NewPersistentHandle(result); + } + + mutator_thread->ExitApiScope(); + + Thread::ExitIsolateGroupAsMutator(/*bypass_safepoint=*/false); + Thread::EnterIsolate(saved_isolate); + + Thread* T = Thread::Current(); + T->EnterSafepointToNative(); + T->set_execution_state(Thread::kThreadInNative); + + Dart_Handle local_handle = Dart_HandleFromPersistent(persistent_result); + Dart_DeletePersistentHandle(persistent_result); + return local_handle; +} + } // namespace dart diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc index c7f1161378a..8a8b206d837 100644 --- a/runtime/lib/isolate.cc +++ b/runtime/lib/isolate.cc @@ -117,7 +117,7 @@ DEFINE_NATIVE_ENTRY(SendPort_sendInternal_, 0, 2) { #if defined(DEBUG) if (same_group) { ASSERT(PortMap::IsReceiverInThisIsolateGroupOrClosed(destination_port_id, - isolate->group())); + group)); } #endif diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h index 1ad3835c645..4fe3599decd 100644 --- a/runtime/vm/bootstrap_natives.h +++ b/runtime/vm/bootstrap_natives.h @@ -375,6 +375,7 @@ namespace dart { V(ConditionVariable_NotifyAll, void, (Dart_Handle)) \ V(ConditionVariable_Wait, void, (Dart_Handle, Dart_Handle)) \ V(FinalizerEntry_SetExternalSize, void, (Dart_Handle, intptr_t)) \ + V(IsolateGroup_runSync, Dart_Handle, (Dart_Handle)) \ V(Mutex_Initialize, void, (Dart_Handle)) \ V(Mutex_RunLocked, Dart_Handle, (Dart_Handle, Dart_Handle)) \ V(Pointer_asTypedListFinalizerAllocateData, void*, ()) \ diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc index 42d89ce95f1..bc7c2e25a32 100644 --- a/runtime/vm/compiler/backend/il.cc +++ b/runtime/vm/compiler/backend/il.cc @@ -7320,19 +7320,6 @@ void NativeCallInstr::SetupNative() { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); - // Currently we perform unoptimized compilations only on mutator threads. If - // the compiler has to resolve a native to a function pointer it calls out to - // the embedder to do so. - // - // Unfortunately that embedder API was designed by giving it a handle to a - // string. So the embedder will have to call back into the VM to convert it to - // a C string - which requires an active isolate. - // - // => To allow this `dart-->jit-compiler-->embedder-->dart api` we set the - // active isolate again. - // - ActiveIsolateScope active_isolate(thread); - const Class& cls = Class::Handle(zone, function().Owner()); const Library& library = Library::Handle(zone, cls.library()); diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h index 9df34a32581..650c41c2894 100644 --- a/runtime/vm/compiler/runtime_api.h +++ b/runtime/vm/compiler/runtime_api.h @@ -1296,6 +1296,10 @@ class Thread : public AllStatic { static word suspend_state_handle_exception_entry_point_offset(); +#if !defined(PRODUCT) + static word single_step_offset(); +#endif // !defined(PRODUCT) + static word OffsetFromThread(const dart::Object& object); static intptr_t OffsetFromThread(const dart::RuntimeEntry* runtime_entry); }; @@ -1344,7 +1348,6 @@ class Isolate : public AllStatic { static word user_tag_offset(); static word finalizers_offset(); #if !defined(PRODUCT) - static word single_step_offset(); static word has_resumption_breakpoints_offset(); #endif // !defined(PRODUCT) }; diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h index 31c50df5e78..a90bd048559 100644 --- a/runtime/vm/compiler/runtime_offsets_extracted.h +++ b/runtime/vm/compiler/runtime_offsets_extracted.h @@ -209,14 +209,13 @@ static constexpr dart::compiler::target::word Isolate_current_tag_offset = 0xc; static constexpr dart::compiler::target::word Isolate_default_tag_offset = 0x10; static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18; static constexpr dart::compiler::target::word - Isolate_has_resumption_breakpoints_offset = 0x1d; + Isolate_has_resumption_breakpoints_offset = 0x1c; static constexpr dart::compiler::target::word IsolateGroup_object_store_offset = 0x10; static constexpr dart::compiler::target::word IsolateGroup_class_table_offset = 0x8; static constexpr dart::compiler::target::word IsolateGroup_cached_class_table_table_offset = 0xc; -static constexpr dart::compiler::target::word Isolate_single_step_offset = 0x1c; static constexpr dart::compiler::target::word Isolate_user_tag_offset = 0x8; static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 0xc; static constexpr dart::compiler::target::word @@ -364,13 +363,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0xfc; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0x60; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x3ec; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x3f0; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x2c; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x3cc; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x3f0; + Thread_service_extension_stream_offset = 0x3f4; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x124; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -482,6 +481,7 @@ static constexpr dart::compiler::target::word Thread_safepoint_state_offset = 0x3c0; static constexpr dart::compiler::target::word Thread_shared_field_table_values_offset = 0x34; +static constexpr dart::compiler::target::word Thread_single_step_offset = 0x3e4; static constexpr dart::compiler::target::word Thread_slow_type_test_stub_offset = 0xe0; static constexpr dart::compiler::target::word @@ -928,14 +928,13 @@ static constexpr dart::compiler::target::word Isolate_current_tag_offset = 0x18; static constexpr dart::compiler::target::word Isolate_default_tag_offset = 0x20; static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x30; static constexpr dart::compiler::target::word - Isolate_has_resumption_breakpoints_offset = 0x39; + Isolate_has_resumption_breakpoints_offset = 0x38; static constexpr dart::compiler::target::word IsolateGroup_object_store_offset = 0x20; static constexpr dart::compiler::target::word IsolateGroup_class_table_offset = 0x10; static constexpr dart::compiler::target::word IsolateGroup_cached_class_table_table_offset = 0x18; -static constexpr dart::compiler::target::word Isolate_single_step_offset = 0x38; static constexpr dart::compiler::target::word Isolate_user_tag_offset = 0x10; static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 0x18; static constexpr dart::compiler::target::word @@ -1084,13 +1083,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0x1f8; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0xc0; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x7c8; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x7d0; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x798; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x7d0; + Thread_service_extension_stream_offset = 0x7d8; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -1202,6 +1201,7 @@ static constexpr dart::compiler::target::word Thread_safepoint_state_offset = 0x780; static constexpr dart::compiler::target::word Thread_shared_field_table_values_offset = 0x68; +static constexpr dart::compiler::target::word Thread_single_step_offset = 0x7b8; static constexpr dart::compiler::target::word Thread_slow_type_test_stub_offset = 0x1c0; static constexpr dart::compiler::target::word @@ -1649,14 +1649,13 @@ static constexpr dart::compiler::target::word Isolate_current_tag_offset = 0xc; static constexpr dart::compiler::target::word Isolate_default_tag_offset = 0x10; static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18; static constexpr dart::compiler::target::word - Isolate_has_resumption_breakpoints_offset = 0x1d; + Isolate_has_resumption_breakpoints_offset = 0x1c; static constexpr dart::compiler::target::word IsolateGroup_object_store_offset = 0x10; static constexpr dart::compiler::target::word IsolateGroup_class_table_offset = 0x8; static constexpr dart::compiler::target::word IsolateGroup_cached_class_table_table_offset = 0xc; -static constexpr dart::compiler::target::word Isolate_single_step_offset = 0x1c; static constexpr dart::compiler::target::word Isolate_user_tag_offset = 0x8; static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 0xc; static constexpr dart::compiler::target::word @@ -1804,13 +1803,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0xfc; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0x60; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x3dc; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x3e0; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x2c; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x3bc; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x3e0; + Thread_service_extension_stream_offset = 0x3e4; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x124; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -1922,6 +1921,7 @@ static constexpr dart::compiler::target::word Thread_safepoint_state_offset = 0x3b0; static constexpr dart::compiler::target::word Thread_shared_field_table_values_offset = 0x34; +static constexpr dart::compiler::target::word Thread_single_step_offset = 0x3d4; static constexpr dart::compiler::target::word Thread_slow_type_test_stub_offset = 0xe0; static constexpr dart::compiler::target::word @@ -2367,14 +2367,13 @@ static constexpr dart::compiler::target::word Isolate_current_tag_offset = 0x18; static constexpr dart::compiler::target::word Isolate_default_tag_offset = 0x20; static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x30; static constexpr dart::compiler::target::word - Isolate_has_resumption_breakpoints_offset = 0x39; + Isolate_has_resumption_breakpoints_offset = 0x38; static constexpr dart::compiler::target::word IsolateGroup_object_store_offset = 0x20; static constexpr dart::compiler::target::word IsolateGroup_class_table_offset = 0x10; static constexpr dart::compiler::target::word IsolateGroup_cached_class_table_table_offset = 0x18; -static constexpr dart::compiler::target::word Isolate_single_step_offset = 0x38; static constexpr dart::compiler::target::word Isolate_user_tag_offset = 0x10; static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 0x18; static constexpr dart::compiler::target::word @@ -2523,13 +2522,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0x1f8; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0xc0; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x810; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x818; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x7e0; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x818; + Thread_service_extension_stream_offset = 0x820; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -2641,6 +2640,7 @@ static constexpr dart::compiler::target::word Thread_safepoint_state_offset = 0x7c8; static constexpr dart::compiler::target::word Thread_shared_field_table_values_offset = 0x68; +static constexpr dart::compiler::target::word Thread_single_step_offset = 0x800; static constexpr dart::compiler::target::word Thread_slow_type_test_stub_offset = 0x1c0; static constexpr dart::compiler::target::word @@ -3091,14 +3091,13 @@ static constexpr dart::compiler::target::word Isolate_current_tag_offset = 0x18; static constexpr dart::compiler::target::word Isolate_default_tag_offset = 0x20; static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x30; static constexpr dart::compiler::target::word - Isolate_has_resumption_breakpoints_offset = 0x39; + Isolate_has_resumption_breakpoints_offset = 0x38; static constexpr dart::compiler::target::word IsolateGroup_object_store_offset = 0x20; static constexpr dart::compiler::target::word IsolateGroup_class_table_offset = 0x10; static constexpr dart::compiler::target::word IsolateGroup_cached_class_table_table_offset = 0x18; -static constexpr dart::compiler::target::word Isolate_single_step_offset = 0x38; static constexpr dart::compiler::target::word Isolate_user_tag_offset = 0x10; static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 0x10; static constexpr dart::compiler::target::word @@ -3247,13 +3246,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0x200; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0xc8; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x7d0; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x7d8; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x60; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x7a0; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x7d8; + Thread_service_extension_stream_offset = 0x7e0; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x250; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -3365,6 +3364,7 @@ static constexpr dart::compiler::target::word Thread_safepoint_state_offset = 0x788; static constexpr dart::compiler::target::word Thread_shared_field_table_values_offset = 0x70; +static constexpr dart::compiler::target::word Thread_single_step_offset = 0x7c0; static constexpr dart::compiler::target::word Thread_slow_type_test_stub_offset = 0x1c8; static constexpr dart::compiler::target::word @@ -3812,14 +3812,13 @@ static constexpr dart::compiler::target::word Isolate_current_tag_offset = 0x18; static constexpr dart::compiler::target::word Isolate_default_tag_offset = 0x20; static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x30; static constexpr dart::compiler::target::word - Isolate_has_resumption_breakpoints_offset = 0x39; + Isolate_has_resumption_breakpoints_offset = 0x38; static constexpr dart::compiler::target::word IsolateGroup_object_store_offset = 0x20; static constexpr dart::compiler::target::word IsolateGroup_class_table_offset = 0x10; static constexpr dart::compiler::target::word IsolateGroup_cached_class_table_table_offset = 0x18; -static constexpr dart::compiler::target::word Isolate_single_step_offset = 0x38; static constexpr dart::compiler::target::word Isolate_user_tag_offset = 0x10; static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 0x10; static constexpr dart::compiler::target::word @@ -3968,13 +3967,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0x200; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0xc8; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x818; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x820; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x60; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x7e8; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x820; + Thread_service_extension_stream_offset = 0x828; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x250; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -4086,6 +4085,7 @@ static constexpr dart::compiler::target::word Thread_safepoint_state_offset = 0x7d0; static constexpr dart::compiler::target::word Thread_shared_field_table_values_offset = 0x70; +static constexpr dart::compiler::target::word Thread_single_step_offset = 0x808; static constexpr dart::compiler::target::word Thread_slow_type_test_stub_offset = 0x1c8; static constexpr dart::compiler::target::word @@ -4534,14 +4534,13 @@ static constexpr dart::compiler::target::word Isolate_current_tag_offset = 0xc; static constexpr dart::compiler::target::word Isolate_default_tag_offset = 0x10; static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x18; static constexpr dart::compiler::target::word - Isolate_has_resumption_breakpoints_offset = 0x1d; + Isolate_has_resumption_breakpoints_offset = 0x1c; static constexpr dart::compiler::target::word IsolateGroup_object_store_offset = 0x10; static constexpr dart::compiler::target::word IsolateGroup_class_table_offset = 0x8; static constexpr dart::compiler::target::word IsolateGroup_cached_class_table_table_offset = 0xc; -static constexpr dart::compiler::target::word Isolate_single_step_offset = 0x1c; static constexpr dart::compiler::target::word Isolate_user_tag_offset = 0x8; static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 0xc; static constexpr dart::compiler::target::word @@ -4689,13 +4688,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0xfc; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0x60; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x414; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x418; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x2c; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x3f4; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x418; + Thread_service_extension_stream_offset = 0x41c; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x124; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -4807,6 +4806,7 @@ static constexpr dart::compiler::target::word Thread_safepoint_state_offset = 0x3e8; static constexpr dart::compiler::target::word Thread_shared_field_table_values_offset = 0x34; +static constexpr dart::compiler::target::word Thread_single_step_offset = 0x40c; static constexpr dart::compiler::target::word Thread_slow_type_test_stub_offset = 0xe0; static constexpr dart::compiler::target::word @@ -5254,14 +5254,13 @@ static constexpr dart::compiler::target::word Isolate_current_tag_offset = 0x18; static constexpr dart::compiler::target::word Isolate_default_tag_offset = 0x20; static constexpr dart::compiler::target::word Isolate_finalizers_offset = 0x30; static constexpr dart::compiler::target::word - Isolate_has_resumption_breakpoints_offset = 0x39; + Isolate_has_resumption_breakpoints_offset = 0x38; static constexpr dart::compiler::target::word IsolateGroup_object_store_offset = 0x20; static constexpr dart::compiler::target::word IsolateGroup_class_table_offset = 0x10; static constexpr dart::compiler::target::word IsolateGroup_cached_class_table_table_offset = 0x18; -static constexpr dart::compiler::target::word Isolate_single_step_offset = 0x38; static constexpr dart::compiler::target::word Isolate_user_tag_offset = 0x10; static constexpr dart::compiler::target::word LinkedHashBase_data_offset = 0x18; static constexpr dart::compiler::target::word @@ -5410,13 +5409,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0x1f8; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0xc0; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x800; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x808; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x7d0; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x808; + Thread_service_extension_stream_offset = 0x810; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -5528,6 +5527,7 @@ static constexpr dart::compiler::target::word Thread_safepoint_state_offset = 0x7b8; static constexpr dart::compiler::target::word Thread_shared_field_table_values_offset = 0x68; +static constexpr dart::compiler::target::word Thread_single_step_offset = 0x7f0; static constexpr dart::compiler::target::word Thread_slow_type_test_stub_offset = 0x1c0; static constexpr dart::compiler::target::word @@ -6123,13 +6123,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0xfc; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0x60; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x3ec; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x3f0; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x2c; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x3cc; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x3f0; + Thread_service_extension_stream_offset = 0x3f4; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x124; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -6835,13 +6835,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0x1f8; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0xc0; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x7c8; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x7d0; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x798; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x7d0; + Thread_service_extension_stream_offset = 0x7d8; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -7547,13 +7547,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0xfc; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0x60; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x3dc; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x3e0; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x2c; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x3bc; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x3e0; + Thread_service_extension_stream_offset = 0x3e4; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x124; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -8258,13 +8258,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0x1f8; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0xc0; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x810; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x818; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x7e0; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x818; + Thread_service_extension_stream_offset = 0x820; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -8974,13 +8974,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0x200; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0xc8; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x7d0; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x7d8; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x60; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x7a0; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x7d8; + Thread_service_extension_stream_offset = 0x7e0; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x250; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -9687,13 +9687,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0x200; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0xc8; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x818; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x820; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x60; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x7e8; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x820; + Thread_service_extension_stream_offset = 0x828; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x250; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -10400,13 +10400,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0xfc; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0x60; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x414; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x418; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x2c; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x3f4; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x418; + Thread_service_extension_stream_offset = 0x41c; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x124; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -11113,13 +11113,13 @@ static constexpr dart::compiler::target::word Thread_call_to_runtime_entry_point_offset = 0x1f8; static constexpr dart::compiler::target::word Thread_call_to_runtime_stub_offset = 0xc0; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x800; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 0x808; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 0x7d0; static constexpr dart::compiler::target::word - Thread_service_extension_stream_offset = 0x808; + Thread_service_extension_stream_offset = 0x810; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = @@ -11702,15 +11702,13 @@ static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset = static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset = 0x18; static constexpr dart::compiler::target::word - AOT_Isolate_has_resumption_breakpoints_offset = 0x1d; + AOT_Isolate_has_resumption_breakpoints_offset = 0x1c; static constexpr dart::compiler::target::word AOT_IsolateGroup_object_store_offset = 0x10; static constexpr dart::compiler::target::word AOT_IsolateGroup_class_table_offset = 0x8; static constexpr dart::compiler::target::word AOT_IsolateGroup_cached_class_table_table_offset = 0xc; -static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset = - 0x1c; static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 0x8; static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset = 0xc; @@ -11868,13 +11866,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0x60; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x3ec; + 0x3f0; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x2c; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x3cc; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x3f0; + AOT_Thread_service_extension_stream_offset = 0x3f4; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x124; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -11991,6 +11989,8 @@ static constexpr dart::compiler::target::word AOT_Thread_safepoint_state_offset = 0x3c0; static constexpr dart::compiler::target::word AOT_Thread_shared_field_table_values_offset = 0x34; +static constexpr dart::compiler::target::word AOT_Thread_single_step_offset = + 0x3e4; static constexpr dart::compiler::target::word AOT_Thread_slow_type_test_stub_offset = 0xe0; static constexpr dart::compiler::target::word @@ -12499,15 +12499,13 @@ static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset = static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset = 0x30; static constexpr dart::compiler::target::word - AOT_Isolate_has_resumption_breakpoints_offset = 0x39; + AOT_Isolate_has_resumption_breakpoints_offset = 0x38; static constexpr dart::compiler::target::word AOT_IsolateGroup_object_store_offset = 0x20; static constexpr dart::compiler::target::word AOT_IsolateGroup_class_table_offset = 0x10; static constexpr dart::compiler::target::word AOT_IsolateGroup_cached_class_table_table_offset = 0x18; -static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset = - 0x38; static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 0x10; static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset = @@ -12666,13 +12664,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0xc0; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x7c8; + 0x7d0; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x798; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x7d0; + AOT_Thread_service_extension_stream_offset = 0x7d8; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -12789,6 +12787,8 @@ static constexpr dart::compiler::target::word AOT_Thread_safepoint_state_offset = 0x780; static constexpr dart::compiler::target::word AOT_Thread_shared_field_table_values_offset = 0x68; +static constexpr dart::compiler::target::word AOT_Thread_single_step_offset = + 0x7b8; static constexpr dart::compiler::target::word AOT_Thread_slow_type_test_stub_offset = 0x1c0; static constexpr dart::compiler::target::word @@ -13304,15 +13304,13 @@ static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset = static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset = 0x30; static constexpr dart::compiler::target::word - AOT_Isolate_has_resumption_breakpoints_offset = 0x39; + AOT_Isolate_has_resumption_breakpoints_offset = 0x38; static constexpr dart::compiler::target::word AOT_IsolateGroup_object_store_offset = 0x20; static constexpr dart::compiler::target::word AOT_IsolateGroup_class_table_offset = 0x10; static constexpr dart::compiler::target::word AOT_IsolateGroup_cached_class_table_table_offset = 0x18; -static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset = - 0x38; static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 0x10; static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset = @@ -13471,13 +13469,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0xc0; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x810; + 0x818; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x7e0; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x818; + AOT_Thread_service_extension_stream_offset = 0x820; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -13594,6 +13592,8 @@ static constexpr dart::compiler::target::word AOT_Thread_safepoint_state_offset = 0x7c8; static constexpr dart::compiler::target::word AOT_Thread_shared_field_table_values_offset = 0x68; +static constexpr dart::compiler::target::word AOT_Thread_single_step_offset = + 0x800; static constexpr dart::compiler::target::word AOT_Thread_slow_type_test_stub_offset = 0x1c0; static constexpr dart::compiler::target::word @@ -14105,15 +14105,13 @@ static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset = static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset = 0x30; static constexpr dart::compiler::target::word - AOT_Isolate_has_resumption_breakpoints_offset = 0x39; + AOT_Isolate_has_resumption_breakpoints_offset = 0x38; static constexpr dart::compiler::target::word AOT_IsolateGroup_object_store_offset = 0x20; static constexpr dart::compiler::target::word AOT_IsolateGroup_class_table_offset = 0x10; static constexpr dart::compiler::target::word AOT_IsolateGroup_cached_class_table_table_offset = 0x18; -static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset = - 0x38; static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 0x10; static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset = @@ -14272,13 +14270,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0xc8; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x7d0; + 0x7d8; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x60; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x7a0; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x7d8; + AOT_Thread_service_extension_stream_offset = 0x7e0; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x250; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -14395,6 +14393,8 @@ static constexpr dart::compiler::target::word AOT_Thread_safepoint_state_offset = 0x788; static constexpr dart::compiler::target::word AOT_Thread_shared_field_table_values_offset = 0x70; +static constexpr dart::compiler::target::word AOT_Thread_single_step_offset = + 0x7c0; static constexpr dart::compiler::target::word AOT_Thread_slow_type_test_stub_offset = 0x1c8; static constexpr dart::compiler::target::word @@ -14906,15 +14906,13 @@ static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset = static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset = 0x30; static constexpr dart::compiler::target::word - AOT_Isolate_has_resumption_breakpoints_offset = 0x39; + AOT_Isolate_has_resumption_breakpoints_offset = 0x38; static constexpr dart::compiler::target::word AOT_IsolateGroup_object_store_offset = 0x20; static constexpr dart::compiler::target::word AOT_IsolateGroup_class_table_offset = 0x10; static constexpr dart::compiler::target::word AOT_IsolateGroup_cached_class_table_table_offset = 0x18; -static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset = - 0x38; static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 0x10; static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset = @@ -15073,13 +15071,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0xc8; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x818; + 0x820; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x60; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x7e8; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x820; + AOT_Thread_service_extension_stream_offset = 0x828; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x250; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -15196,6 +15194,8 @@ static constexpr dart::compiler::target::word AOT_Thread_safepoint_state_offset = 0x7d0; static constexpr dart::compiler::target::word AOT_Thread_shared_field_table_values_offset = 0x70; +static constexpr dart::compiler::target::word AOT_Thread_single_step_offset = + 0x808; static constexpr dart::compiler::target::word AOT_Thread_slow_type_test_stub_offset = 0x1c8; static constexpr dart::compiler::target::word @@ -15709,15 +15709,13 @@ static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset = static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset = 0x18; static constexpr dart::compiler::target::word - AOT_Isolate_has_resumption_breakpoints_offset = 0x1d; + AOT_Isolate_has_resumption_breakpoints_offset = 0x1c; static constexpr dart::compiler::target::word AOT_IsolateGroup_object_store_offset = 0x10; static constexpr dart::compiler::target::word AOT_IsolateGroup_class_table_offset = 0x8; static constexpr dart::compiler::target::word AOT_IsolateGroup_cached_class_table_table_offset = 0xc; -static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset = - 0x1c; static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 0x8; static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset = 0xc; @@ -15875,13 +15873,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0x60; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x414; + 0x418; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x2c; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x3f4; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x418; + AOT_Thread_service_extension_stream_offset = 0x41c; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x124; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -15998,6 +15996,8 @@ static constexpr dart::compiler::target::word AOT_Thread_safepoint_state_offset = 0x3e8; static constexpr dart::compiler::target::word AOT_Thread_shared_field_table_values_offset = 0x34; +static constexpr dart::compiler::target::word AOT_Thread_single_step_offset = + 0x40c; static constexpr dart::compiler::target::word AOT_Thread_slow_type_test_stub_offset = 0xe0; static constexpr dart::compiler::target::word @@ -16507,15 +16507,13 @@ static constexpr dart::compiler::target::word AOT_Isolate_default_tag_offset = static constexpr dart::compiler::target::word AOT_Isolate_finalizers_offset = 0x30; static constexpr dart::compiler::target::word - AOT_Isolate_has_resumption_breakpoints_offset = 0x39; + AOT_Isolate_has_resumption_breakpoints_offset = 0x38; static constexpr dart::compiler::target::word AOT_IsolateGroup_object_store_offset = 0x20; static constexpr dart::compiler::target::word AOT_IsolateGroup_class_table_offset = 0x10; static constexpr dart::compiler::target::word AOT_IsolateGroup_cached_class_table_table_offset = 0x18; -static constexpr dart::compiler::target::word AOT_Isolate_single_step_offset = - 0x38; static constexpr dart::compiler::target::word AOT_Isolate_user_tag_offset = 0x10; static constexpr dart::compiler::target::word AOT_LinkedHashBase_data_offset = @@ -16674,13 +16672,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0xc0; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x800; + 0x808; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x7d0; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x808; + AOT_Thread_service_extension_stream_offset = 0x810; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -16797,6 +16795,8 @@ static constexpr dart::compiler::target::word AOT_Thread_safepoint_state_offset = 0x7b8; static constexpr dart::compiler::target::word AOT_Thread_shared_field_table_values_offset = 0x68; +static constexpr dart::compiler::target::word AOT_Thread_single_step_offset = + 0x7f0; static constexpr dart::compiler::target::word AOT_Thread_slow_type_test_stub_offset = 0x1c0; static constexpr dart::compiler::target::word @@ -17464,13 +17464,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0x60; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x3ec; + 0x3f0; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x2c; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x3cc; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x3f0; + AOT_Thread_service_extension_stream_offset = 0x3f4; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x124; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -18253,13 +18253,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0xc0; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x7c8; + 0x7d0; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x798; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x7d0; + AOT_Thread_service_extension_stream_offset = 0x7d8; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -19049,13 +19049,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0xc0; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x810; + 0x818; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x7e0; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x818; + AOT_Thread_service_extension_stream_offset = 0x820; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -19841,13 +19841,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0xc8; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x7d0; + 0x7d8; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x60; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x7a0; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x7d8; + AOT_Thread_service_extension_stream_offset = 0x7e0; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x250; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -20633,13 +20633,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0xc8; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x818; + 0x820; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x60; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x7e8; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x820; + AOT_Thread_service_extension_stream_offset = 0x828; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x250; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -21426,13 +21426,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0x60; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x414; + 0x418; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x2c; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x3f4; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x418; + AOT_Thread_service_extension_stream_offset = 0x41c; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x124; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -22216,13 +22216,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_call_to_runtime_stub_offset = 0xc0; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 0x800; + 0x808; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 0x58; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 0x7d0; static constexpr dart::compiler::target::word - AOT_Thread_service_extension_stream_offset = 0x808; + AOT_Thread_service_extension_stream_offset = 0x810; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 0x248; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h index bd3817c35d8..3955ccdef8f 100644 --- a/runtime/vm/compiler/runtime_offsets_list.h +++ b/runtime/vm/compiler/runtime_offsets_list.h @@ -174,7 +174,6 @@ FIELD(IsolateGroup, object_store_offset) \ FIELD(IsolateGroup, class_table_offset) \ FIELD(IsolateGroup, cached_class_table_table_offset) \ - NOT_IN_PRODUCT(FIELD(Isolate, single_step_offset)) \ FIELD(Isolate, user_tag_offset) \ FIELD(LinkedHashBase, data_offset) \ FIELD(ImmutableLinkedHashBase, data_offset) \ @@ -319,6 +318,7 @@ FIELD(Thread, saved_shadow_call_stack_offset) \ FIELD(Thread, safepoint_state_offset) \ FIELD(Thread, shared_field_table_values_offset) \ + NOT_IN_PRODUCT(FIELD(Thread, single_step_offset)) \ FIELD(Thread, slow_type_test_stub_offset) \ FIELD(Thread, slow_type_test_entry_point_offset) \ FIELD(Thread, stack_limit_offset) \ diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc index cab4fd79d61..74702c021cd 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm.cc @@ -2328,8 +2328,7 @@ void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub( Label stepping, done_stepping; if (optimized == kUnoptimized) { __ Comment("Check single stepping"); - __ LoadIsolate(R8); - __ ldrb(R8, Address(R8, target::Isolate::single_step_offset())); + __ ldrb(R8, Address(THR, target::Thread::single_step_offset())); __ CompareImmediate(R8, 0); __ b(&stepping, NE); __ Bind(&done_stepping); @@ -2681,8 +2680,7 @@ void StubCodeCompiler::GenerateZeroArgsUnoptimizedStaticCallStub() { #if !defined(PRODUCT) // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(R8); - __ ldrb(R8, Address(R8, target::Isolate::single_step_offset())); + __ ldrb(R8, Address(THR, target::Thread::single_step_offset())); __ CompareImmediate(R8, 0); __ b(&stepping, NE); __ Bind(&done_stepping); @@ -2899,8 +2897,7 @@ void StubCodeCompiler::GenerateDebugStepCheckStub() { #else // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(R1); - __ ldrb(R1, Address(R1, target::Isolate::single_step_offset())); + __ ldrb(R1, Address(THR, target::Thread::single_step_offset())); __ CompareImmediate(R1, 0); __ b(&stepping, NE); __ Bind(&done_stepping); @@ -3220,8 +3217,7 @@ void StubCodeCompiler::GenerateUnoptimizedIdenticalWithNumberCheckStub() { #if !defined(PRODUCT) // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(R1); - __ ldrb(R1, Address(R1, target::Isolate::single_step_offset())); + __ ldrb(R1, Address(THR, target::Thread::single_step_offset())); __ CompareImmediate(R1, 0); __ b(&stepping, NE); __ Bind(&done_stepping); diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc index cf649f4de8a..ff164eff5bb 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm64.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc @@ -2723,8 +2723,7 @@ void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub( Label stepping, done_stepping; if (optimized == kUnoptimized) { __ Comment("Check single stepping"); - __ LoadIsolate(R6); - __ LoadFromOffset(R6, R6, target::Isolate::single_step_offset(), + __ LoadFromOffset(R6, THR, target::Thread::single_step_offset(), kUnsignedByte); __ CompareRegisters(R6, ZR); __ b(&stepping, NE); @@ -3095,8 +3094,7 @@ void StubCodeCompiler::GenerateZeroArgsUnoptimizedStaticCallStub() { // Check single stepping. #if !defined(PRODUCT) Label stepping, done_stepping; - __ LoadIsolate(R6); - __ LoadFromOffset(R6, R6, target::Isolate::single_step_offset(), + __ LoadFromOffset(R6, THR, target::Thread::single_step_offset(), kUnsignedByte); __ CompareImmediate(R6, 0); __ b(&stepping, NE); @@ -3337,8 +3335,7 @@ void StubCodeCompiler::GenerateDebugStepCheckStub() { #else // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(R1); - __ LoadFromOffset(R1, R1, target::Isolate::single_step_offset(), + __ LoadFromOffset(R1, THR, target::Thread::single_step_offset(), kUnsignedByte); __ CompareImmediate(R1, 0); __ b(&stepping, NE); @@ -3597,8 +3594,7 @@ void StubCodeCompiler::GenerateUnoptimizedIdenticalWithNumberCheckStub() { #if !defined(PRODUCT) // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(R1); - __ LoadFromOffset(R1, R1, target::Isolate::single_step_offset(), + __ LoadFromOffset(R1, THR, target::Thread::single_step_offset(), kUnsignedByte); __ CompareImmediate(R1, 0); __ b(&stepping, NE); diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc index 78109a04dd9..421b7bd3cac 100644 --- a/runtime/vm/compiler/stub_code_compiler_ia32.cc +++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc @@ -2065,8 +2065,7 @@ void StubCodeCompiler::GenerateNArgsCheckInlineCacheStubForEntryKind( Label stepping, done_stepping; if (optimized == kUnoptimized) { __ Comment("Check single stepping"); - __ LoadIsolate(EAX); - __ cmpb(Address(EAX, target::Isolate::single_step_offset()), Immediate(0)); + __ cmpb(Address(THR, target::Thread::single_step_offset()), Immediate(0)); __ j(NOT_EQUAL, &stepping); __ Bind(&done_stepping); } @@ -2382,8 +2381,7 @@ static void GenerateZeroArgsUnoptimizedStaticCallForEntryKind( #if !defined(PRODUCT) // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(EAX); - __ cmpb(Address(EAX, target::Isolate::single_step_offset()), Immediate(0)); + __ cmpb(Address(THR, target::Thread::single_step_offset()), Immediate(0)); __ j(NOT_EQUAL, &stepping, Assembler::kNearJump); __ Bind(&done_stepping); #endif @@ -2601,9 +2599,7 @@ void StubCodeCompiler::GenerateDebugStepCheckStub() { #else // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(EAX); - __ movzxb(EAX, Address(EAX, target::Isolate::single_step_offset())); - __ cmpl(EAX, Immediate(0)); + __ cmpb(Address(THR, target::Thread::single_step_offset()), Immediate(0)); __ j(NOT_EQUAL, &stepping, Assembler::kNearJump); __ Bind(&done_stepping); __ ret(); @@ -3099,9 +3095,7 @@ void StubCodeCompiler::GenerateUnoptimizedIdenticalWithNumberCheckStub() { #if !defined(PRODUCT) // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(EAX); - __ movzxb(EAX, Address(EAX, target::Isolate::single_step_offset())); - __ cmpl(EAX, Immediate(0)); + __ cmpb(Address(THR, target::Thread::single_step_offset()), Immediate(0)); __ j(NOT_EQUAL, &stepping); __ Bind(&done_stepping); #endif diff --git a/runtime/vm/compiler/stub_code_compiler_riscv.cc b/runtime/vm/compiler/stub_code_compiler_riscv.cc index b181e8051d4..6379382a037 100644 --- a/runtime/vm/compiler/stub_code_compiler_riscv.cc +++ b/runtime/vm/compiler/stub_code_compiler_riscv.cc @@ -2300,8 +2300,7 @@ void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub( Label stepping, done_stepping; if (optimized == kUnoptimized) { __ Comment("Check single stepping"); - __ LoadIsolate(TMP); - __ LoadFromOffset(TMP, TMP, target::Isolate::single_step_offset(), + __ LoadFromOffset(TMP, THR, target::Thread::single_step_offset(), kUnsignedByte); __ bnez(TMP, &stepping); __ Bind(&done_stepping); @@ -2655,8 +2654,7 @@ void StubCodeCompiler::GenerateZeroArgsUnoptimizedStaticCallStub() { // Check single stepping. #if !defined(PRODUCT) Label stepping, done_stepping; - __ LoadIsolate(TMP); - __ LoadFromOffset(TMP, TMP, target::Isolate::single_step_offset(), + __ LoadFromOffset(TMP, THR, target::Thread::single_step_offset(), kUnsignedByte); __ bnez(TMP, &stepping, Assembler::kNearJump); __ Bind(&done_stepping); @@ -2813,8 +2811,7 @@ void StubCodeCompiler::GenerateDebugStepCheckStub() { #else // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(A1); - __ LoadFromOffset(A1, A1, target::Isolate::single_step_offset(), + __ LoadFromOffset(A1, THR, target::Thread::single_step_offset(), kUnsignedByte); __ bnez(A1, &stepping, compiler::Assembler::kNearJump); __ Bind(&done_stepping); @@ -3084,8 +3081,7 @@ void StubCodeCompiler::GenerateUnoptimizedIdenticalWithNumberCheckStub() { #if !defined(PRODUCT) // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(TMP); - __ LoadFromOffset(TMP, TMP, target::Isolate::single_step_offset(), + __ LoadFromOffset(TMP, THR, target::Thread::single_step_offset(), kUnsignedByte); __ bnez(TMP, &stepping); __ Bind(&done_stepping); diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc index 3d88d63a222..6dfdbe68035 100644 --- a/runtime/vm/compiler/stub_code_compiler_x64.cc +++ b/runtime/vm/compiler/stub_code_compiler_x64.cc @@ -2631,8 +2631,7 @@ void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub( Label stepping, done_stepping; if (optimized == kUnoptimized) { __ Comment("Check single stepping"); - __ LoadIsolate(RAX); - __ cmpb(Address(RAX, target::Isolate::single_step_offset()), Immediate(0)); + __ cmpb(Address(THR, target::Thread::single_step_offset()), Immediate(0)); __ j(NOT_EQUAL, &stepping); __ Bind(&done_stepping); } @@ -2969,9 +2968,7 @@ void StubCodeCompiler::GenerateZeroArgsUnoptimizedStaticCallStub() { #if !defined(PRODUCT) // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(RAX); - __ movzxb(RAX, Address(RAX, target::Isolate::single_step_offset())); - __ cmpq(RAX, Immediate(0)); + __ cmpb(Address(THR, target::Thread::single_step_offset()), Immediate(0)); #if defined(DEBUG) static auto const kJumpLength = Assembler::kFarJump; #else @@ -3212,9 +3209,7 @@ void StubCodeCompiler::GenerateDebugStepCheckStub() { #else // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(RAX); - __ movzxb(RAX, Address(RAX, target::Isolate::single_step_offset())); - __ cmpq(RAX, Immediate(0)); + __ cmpb(Address(THR, target::Thread::single_step_offset()), Immediate(0)); __ j(NOT_EQUAL, &stepping, Assembler::kNearJump); __ Bind(&done_stepping); __ ret(); @@ -3500,9 +3495,7 @@ void StubCodeCompiler::GenerateUnoptimizedIdenticalWithNumberCheckStub() { #if !defined(PRODUCT) // Check single stepping. Label stepping, done_stepping; - __ LoadIsolate(RAX); - __ movzxb(RAX, Address(RAX, target::Isolate::single_step_offset())); - __ cmpq(RAX, Immediate(0)); + __ cmpb(Address(THR, target::Thread::single_step_offset()), Immediate(0)); __ j(NOT_EQUAL, &stepping); __ Bind(&done_stepping); #endif diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index a7ad3513e4f..be5e4ee8e35 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc @@ -377,7 +377,6 @@ ObjectPtr Api::UnwrapHandle(Dart_Handle object) { Thread* thread = Thread::Current(); ASSERT(thread->execution_state() == Thread::kThreadInVM); ASSERT(thread->IsDartMutatorThread()); - ASSERT(thread->isolate() != nullptr); ASSERT(FinalizablePersistentHandle::ptr_offset() == 0 && PersistentHandle::ptr_offset() == 0 && LocalHandle::ptr_offset() == 0); #endif @@ -483,17 +482,17 @@ Dart_Handle Api::NewArgumentError(const char* format, ...) { } bool Api::IsValid(Dart_Handle handle) { - Isolate* isolate = Isolate::Current(); Thread* thread = Thread::Current(); ASSERT(thread->IsDartMutatorThread()); - CHECK_ISOLATE(isolate); + IsolateGroup* isolate_group = thread->isolate_group(); + CHECK_ISOLATE_GROUP(isolate_group); // Check against all of the handles in the current isolate as well as the // read-only handles. return thread->IsValidHandle(handle) || - isolate->group()->api_state()->IsActivePersistentHandle( + isolate_group->api_state()->IsActivePersistentHandle( reinterpret_cast(handle)) || - isolate->group()->api_state()->IsActiveWeakPersistentHandle( + isolate_group->api_state()->IsActiveWeakPersistentHandle( reinterpret_cast(handle)) || Dart::IsReadOnlyApiHandle(handle) || Dart::IsReadOnlyHandle(reinterpret_cast(handle)); @@ -854,7 +853,7 @@ DART_EXPORT Dart_Handle Dart_NewUnhandledExceptionError(Dart_Handle exception) { DART_EXPORT void Dart_PropagateError(Dart_Handle handle) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); const Object& obj = Object::Handle(thread->zone(), Api::UnwrapHandle(handle)); if (!obj.IsError()) { @@ -921,9 +920,9 @@ DART_EXPORT bool Dart_IdentityEquals(Dart_Handle obj1, Dart_Handle obj2) { DART_EXPORT Dart_Handle Dart_HandleFromPersistent(Dart_PersistentHandle object) { Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); - ApiState* state = isolate->group()->api_state(); + IsolateGroup* isolate_group = thread->isolate_group(); + CHECK_ISOLATE_GROUP(isolate_group); + ApiState* state = isolate_group->api_state(); ASSERT(state != nullptr); TransitionNativeToVM transition(thread); NoSafepointScope no_safepoint_scope; @@ -934,9 +933,9 @@ Dart_HandleFromPersistent(Dart_PersistentHandle object) { DART_EXPORT Dart_Handle Dart_HandleFromWeakPersistent(Dart_WeakPersistentHandle object) { Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); - ApiState* state = isolate->group()->api_state(); + IsolateGroup* isolate_group = thread->isolate_group(); + CHECK_ISOLATE_GROUP(isolate_group); + ApiState* state = isolate_group->api_state(); ASSERT(state != nullptr); TransitionNativeToVM transition(thread); NoSafepointScope no_safepoint_scope; @@ -950,9 +949,9 @@ Dart_HandleFromWeakPersistent(Dart_WeakPersistentHandle object) { static Dart_Handle HandleFromFinalizable(Dart_FinalizableHandle object) { Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); - ApiState* state = isolate->group()->api_state(); + IsolateGroup* isolate_group = thread->isolate_group(); + CHECK_ISOLATE_GROUP(isolate_group); + ApiState* state = isolate_group->api_state(); ASSERT(state != nullptr); TransitionNativeToVM transition(thread); NoSafepointScope no_safepoint_scope; @@ -963,8 +962,10 @@ static Dart_Handle HandleFromFinalizable(Dart_FinalizableHandle object) { DART_EXPORT Dart_PersistentHandle Dart_NewPersistentHandle(Dart_Handle object) { DARTSCOPE(Thread::Current()); - Isolate* I = T->isolate(); - ApiState* state = I->group()->api_state(); + Thread* thread = Thread::Current(); + IsolateGroup* isolate_group = thread->isolate_group(); + CHECK_ISOLATE_GROUP(isolate_group); + ApiState* state = isolate_group->api_state(); ASSERT(state != nullptr); const Object& old_ref = Object::Handle(Z, Api::UnwrapHandle(object)); PersistentHandle* new_ref = state->AllocatePersistentHandle(); @@ -975,8 +976,10 @@ DART_EXPORT Dart_PersistentHandle Dart_NewPersistentHandle(Dart_Handle object) { DART_EXPORT void Dart_SetPersistentHandle(Dart_PersistentHandle obj1, Dart_Handle obj2) { DARTSCOPE(Thread::Current()); - Isolate* I = T->isolate(); - ApiState* state = I->group()->api_state(); + Thread* thread = Thread::Current(); + IsolateGroup* isolate_group = thread->isolate_group(); + CHECK_ISOLATE_GROUP(isolate_group); + ApiState* state = isolate_group->api_state(); ASSERT(state != nullptr); ASSERT(state->IsValidPersistentHandle(obj1)); const Object& obj2_ref = Object::Handle(Z, Api::UnwrapHandle(obj2)); @@ -1999,8 +2002,9 @@ DART_EXPORT Dart_Handle Dart_RunLoop() { bool result; { Thread* T = Thread::Current(); - I = T->isolate(); CHECK_API_SCOPE(T); + I = T->isolate(); + CHECK_ISOLATE(I); CHECK_CALLBACK_STATE(T); } API_TIMELINE_BEGIN_END(Thread::Current()); @@ -2087,8 +2091,9 @@ DART_EXPORT bool Dart_RunLoopAsync(bool errors_are_fatal, DART_EXPORT Dart_Handle Dart_HandleMessage() { Thread* T = Thread::Current(); - Isolate* I = T->isolate(); CHECK_API_SCOPE(T); + Isolate* I = T->isolate(); + CHECK_ISOLATE(I); CHECK_CALLBACK_STATE(T); API_TIMELINE_BEGIN_END(T); TransitionNativeToVM transition(T); @@ -2103,8 +2108,9 @@ DART_EXPORT bool Dart_HandleServiceMessages() { return true; #else Thread* T = Thread::Current(); - Isolate* I = T->isolate(); CHECK_API_SCOPE(T); + Isolate* I = T->isolate(); + CHECK_ISOLATE(I); CHECK_CALLBACK_STATE(T); API_TIMELINE_DURATION(T); TransitionNativeToVM transition(T); @@ -2351,7 +2357,7 @@ DART_EXPORT Dart_Handle Dart_ObjectIsType(Dart_Handle object, DART_EXPORT bool Dart_IsInstance(Dart_Handle object) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); REUSABLE_OBJECT_HANDLESCOPE(thread); Object& ref = thread->ObjectHandle(); @@ -2361,42 +2367,42 @@ DART_EXPORT bool Dart_IsInstance(Dart_Handle object) { DART_EXPORT bool Dart_IsNumber(Dart_Handle object) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return IsNumberClassId(Api::ClassId(object)); } DART_EXPORT bool Dart_IsInteger(Dart_Handle object) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return IsIntegerClassId(Api::ClassId(object)); } DART_EXPORT bool Dart_IsDouble(Dart_Handle object) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return Api::ClassId(object) == kDoubleCid; } DART_EXPORT bool Dart_IsBoolean(Dart_Handle object) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return Api::ClassId(object) == kBoolCid; } DART_EXPORT bool Dart_IsString(Dart_Handle object) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return IsStringClassId(Api::ClassId(object)); } DART_EXPORT bool Dart_IsStringLatin1(Dart_Handle object) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return IsOneByteStringClassId(Api::ClassId(object)); } @@ -2419,42 +2425,42 @@ DART_EXPORT bool Dart_IsMap(Dart_Handle object) { DART_EXPORT bool Dart_IsLibrary(Dart_Handle object) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return Api::ClassId(object) == kLibraryCid; } DART_EXPORT bool Dart_IsType(Dart_Handle handle) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return IsTypeClassId(Api::ClassId(handle)); } DART_EXPORT bool Dart_IsFunction(Dart_Handle handle) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return Api::ClassId(handle) == kFunctionCid; } DART_EXPORT bool Dart_IsVariable(Dart_Handle handle) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return Api::ClassId(handle) == kFieldCid; } DART_EXPORT bool Dart_IsTypeVariable(Dart_Handle handle) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return Api::ClassId(handle) == kTypeParameterCid; } DART_EXPORT bool Dart_IsClosure(Dart_Handle object) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return Api::ClassId(object) == kClosureCid; } @@ -2473,7 +2479,7 @@ DART_EXPORT bool Dart_IsTearOff(Dart_Handle object) { DART_EXPORT bool Dart_IsTypedData(Dart_Handle handle) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); intptr_t cid = Api::ClassId(handle); return IsTypedDataClassId(cid) || IsExternalTypedDataClassId(cid) || @@ -2482,7 +2488,7 @@ DART_EXPORT bool Dart_IsTypedData(Dart_Handle handle) { DART_EXPORT bool Dart_IsByteBuffer(Dart_Handle handle) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); return Api::ClassId(handle) == kByteBufferCid; } @@ -2616,8 +2622,7 @@ DART_EXPORT Dart_Handle Dart_IntegerFitsIntoInt64(Dart_Handle integer, // Fast path for Smis and Mints. Thread* thread = Thread::Current(); API_TIMELINE_DURATION(thread); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); + CHECK_ISOLATE_GROUP(thread->isolate_group()); if (Api::IsSmi(integer)) { *fits = true; return Api::Success(); @@ -2637,8 +2642,7 @@ DART_EXPORT Dart_Handle Dart_IntegerFitsIntoUint64(Dart_Handle integer, bool* fits) { // Fast path for Smis. Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); + CHECK_ISOLATE_GROUP(thread->isolate_group()); API_TIMELINE_DURATION(thread); if (Api::IsSmi(integer)) { *fits = (Api::SmiValue(integer) >= 0); @@ -2658,8 +2662,7 @@ DART_EXPORT Dart_Handle Dart_IntegerFitsIntoUint64(Dart_Handle integer, DART_EXPORT Dart_Handle Dart_NewInteger(int64_t value) { // Fast path for Smis. Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); + CHECK_ISOLATE_GROUP(thread->isolate_group()); API_TIMELINE_DURATION(thread); DARTSCOPE(thread); CHECK_CALLBACK_STATE(thread); @@ -2694,8 +2697,7 @@ DART_EXPORT Dart_Handle Dart_IntegerToInt64(Dart_Handle integer, int64_t* value) { // Fast path for Smis. Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); + CHECK_ISOLATE_GROUP(thread->isolate_group()); if (Api::IsSmi(integer)) { *value = Api::SmiValue(integer); return Api::Success(); @@ -2715,8 +2717,7 @@ DART_EXPORT Dart_Handle Dart_IntegerToUint64(Dart_Handle integer, uint64_t* value) { // Fast path for Smis. Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); + CHECK_ISOLATE_GROUP(thread->isolate_group()); if (Api::IsSmi(integer)) { intptr_t smi_value = Api::SmiValue(integer); if (smi_value >= 0) { @@ -2844,8 +2845,7 @@ DART_EXPORT Dart_Handle Dart_False() { } DART_EXPORT Dart_Handle Dart_NewBoolean(bool value) { - Isolate* isolate = Isolate::Current(); - CHECK_ISOLATE(isolate); + CHECK_ISOLATE_GROUP(IsolateGroup::Current()); return value ? Api::True() : Api::False(); } @@ -3057,7 +3057,7 @@ DART_EXPORT Dart_Handle Dart_StringToUTF16(Dart_Handle str, DART_EXPORT Dart_Handle Dart_StringStorageSize(Dart_Handle str, intptr_t* size) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); if (size == nullptr) { RETURN_NULL_ERROR(size); @@ -3078,7 +3078,7 @@ DART_EXPORT Dart_Handle Dart_StringGetProperties(Dart_Handle object, intptr_t* str_len, void** peer) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); { ReusableObjectHandleScope reused_obj_handle(thread); @@ -4173,8 +4173,7 @@ DART_EXPORT Dart_Handle Dart_TypedDataReleaseData(Dart_Handle object) { DART_EXPORT Dart_Handle Dart_GetDataFromByteBuffer(Dart_Handle object) { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); intptr_t class_id = Api::ClassId(object); if (class_id != kByteBufferCid) { @@ -4847,8 +4846,7 @@ DART_EXPORT Dart_Handle Dart_SetField(Dart_Handle container, DART_EXPORT Dart_Handle Dart_ThrowException(Dart_Handle exception) { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); + CHECK_ISOLATE_GROUP(thread->isolate_group()); CHECK_CALLBACK_STATE(thread); if (::Dart_IsError(exception)) { ::Dart_PropagateError(exception); @@ -4881,8 +4879,7 @@ DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception, Dart_Handle stacktrace) { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); + CHECK_ISOLATE_GROUP(thread->isolate_group()); CHECK_CALLBACK_STATE(thread); TransitionNativeToVM transition(thread); { @@ -4923,7 +4920,7 @@ DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception, DART_EXPORT Dart_Handle Dart_GetNativeInstanceFieldCount(Dart_Handle obj, int* count) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); { ReusableObjectHandleScope reused_obj_handle(thread); @@ -4941,7 +4938,7 @@ DART_EXPORT Dart_Handle Dart_GetNativeInstanceField(Dart_Handle obj, int index, intptr_t* value) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); bool is_null = false; { @@ -5409,17 +5406,17 @@ DART_EXPORT void Dart_SetDoubleReturnValue(Dart_NativeArguments args, DART_EXPORT Dart_Handle Dart_SetLibraryTagHandler(Dart_LibraryTagHandler handler) { - Isolate* isolate = Isolate::Current(); - CHECK_ISOLATE(isolate); - isolate->group()->set_library_tag_handler(handler); + IsolateGroup* isolate_group = IsolateGroup::Current(); + CHECK_ISOLATE_GROUP(isolate_group); + isolate_group->set_library_tag_handler(handler); return Api::Success(); } DART_EXPORT Dart_Handle Dart_SetDeferredLoadHandler(Dart_DeferredLoadHandler handler) { - Isolate* isolate = Isolate::Current(); - CHECK_ISOLATE(isolate); - isolate->group()->set_deferred_load_handler(handler); + IsolateGroup* isolate_group = IsolateGroup::Current(); + CHECK_ISOLATE_GROUP(isolate_group); + isolate_group->set_deferred_load_handler(handler); return Api::Success(); } @@ -5479,11 +5476,10 @@ DART_EXPORT Dart_Handle Dart_LoadScriptFromKernel(const uint8_t* buffer, DART_EXPORT Dart_Handle Dart_RootLibrary() { Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); + IsolateGroup* isolate_group = thread->isolate_group(); + CHECK_ISOLATE_GROUP(isolate_group); TransitionNativeToVM transition(thread); - return Api::NewHandle(thread, - isolate->group()->object_store()->root_library()); + return Api::NewHandle(thread, isolate_group->object_store()->root_library()); } DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library) { @@ -5989,7 +5985,7 @@ DART_EXPORT Dart_Handle Dart_GetPeer(Dart_Handle object, void** peer) { RETURN_NULL_ERROR(peer); } Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); REUSABLE_OBJECT_HANDLESCOPE(thread); Object& obj = thread->ObjectHandle(); @@ -6009,7 +6005,7 @@ DART_EXPORT Dart_Handle Dart_GetPeer(Dart_Handle object, void** peer) { DART_EXPORT Dart_Handle Dart_SetPeer(Dart_Handle object, void* peer) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); TransitionNativeToVM transition(thread); REUSABLE_OBJECT_HANDLESCOPE(thread); Object& obj = thread->ObjectHandle(); @@ -6255,9 +6251,9 @@ DART_EXPORT bool Dart_IsReloading() { return false; #else Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); - CHECK_ISOLATE(isolate); - return isolate->group()->IsReloading(); + IsolateGroup* isolate_group = thread->isolate_group(); + CHECK_ISOLATE_GROUP(isolate_group); + return isolate_group->IsReloading(); #endif } @@ -6929,7 +6925,7 @@ DART_EXPORT Dart_Handle Dart_GetDefaultUserTag() { DART_EXPORT Dart_Handle Dart_NewUserTag(const char* label) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); DARTSCOPE(thread); if (label == nullptr) { return Api::NewError( @@ -6941,7 +6937,7 @@ DART_EXPORT Dart_Handle Dart_NewUserTag(const char* label) { DART_EXPORT Dart_Handle Dart_SetCurrentUserTag(Dart_Handle user_tag) { Thread* thread = Thread::Current(); - CHECK_ISOLATE(thread->isolate()); + CHECK_ISOLATE_GROUP(thread->isolate_group()); DARTSCOPE(thread); const UserTag& tag = Api::UnwrapUserTagHandle(Z, user_tag); if (tag.IsNull()) { diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h index 4b22165b9dc..17d82194ca0 100644 --- a/runtime/vm/dart_api_impl.h +++ b/runtime/vm/dart_api_impl.h @@ -60,12 +60,10 @@ const char* CanonicalFunction(const char* func); } \ } while (0) -// Checks that the current isolate is not nullptr and that it has an API scope. +// Checks that the current thread has an API scope. #define CHECK_API_SCOPE(thread) \ do { \ Thread* tmpT = (thread); \ - Isolate* tmpI = tmpT == nullptr ? nullptr : tmpT->isolate(); \ - CHECK_ISOLATE(tmpI); \ if (tmpT->api_top_scope() == nullptr) { \ FATAL( \ "%s expects to find a current scope. Did you forget to call " \ diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc index 20c88a704b5..b08537cf738 100644 --- a/runtime/vm/debugger.cc +++ b/runtime/vm/debugger.cc @@ -1527,7 +1527,7 @@ void Debugger::DeoptimizeWorld() { if (FLAG_trace_deoptimization) { THR_Print("Deopt for debugger\n"); } - isolate_->set_has_attempted_stepping(true); + isolate_->group()->set_has_attempted_stepping(true); DeoptimizeFunctionsOnStack(); @@ -1617,17 +1617,18 @@ void Debugger::RunWithStoppedDeoptimizedWorld(std::function fun) { } void Debugger::NotifySingleStepping(bool value) { + RELEASE_ASSERT(isolate_->mutator_thread() != nullptr); if (value) { // Setting breakpoint requires unoptimized code, make sure we stop all // isolates to prevent racing reoptimization. RunWithStoppedDeoptimizedWorld([&] { - isolate_->set_single_step(value); + isolate_->mutator_thread()->set_single_step(value); // Ensure other isolates in the isolate group keep // unoptimized code unoptimized, won't attempt to optimize it. group_debugger()->RegisterSingleSteppingDebugger(Thread::Current(), this); }); } else { - isolate_->set_single_step(value); + isolate_->mutator_thread()->set_single_step(value); group_debugger()->UnregisterSingleSteppingDebugger(Thread::Current(), this); } } @@ -1653,19 +1654,18 @@ static ArrayPtr DeoptimizeToArray(Thread* thread, StackFrame* frame, const Code& code) { ASSERT(code.is_optimized() && !code.is_force_optimized()); - Isolate* isolate = thread->isolate(); // Create the DeoptContext for this deoptimization. DeoptContext* deopt_context = new DeoptContext(frame, code, DeoptContext::kDestIsAllocated, nullptr, nullptr, true, false /* deoptimizing_code */); - isolate->set_deopt_context(deopt_context); + thread->set_deopt_context(deopt_context); deopt_context->FillDestFrame(); deopt_context->MaterializeDeferredObjects(); const Array& dest_frame = Array::Handle(thread->zone(), deopt_context->DestFrameAsArray()); - isolate->set_deopt_context(nullptr); + thread->set_deopt_context(nullptr); delete deopt_context; return dest_frame.ptr(); @@ -3591,7 +3591,7 @@ static bool IsAtAsyncJump(ActivationFrame* top_frame) { } ErrorPtr Debugger::PauseStepping() { - ASSERT(isolate_->single_step()); + ASSERT(Thread::Current()->single_step()); // Don't pause recursively. if (IsPaused()) { return Error::null(); diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc index 8aa97b40650..3f535bb79de 100644 --- a/runtime/vm/exceptions.cc +++ b/runtime/vm/exceptions.cc @@ -765,7 +765,9 @@ static void ThrowExceptionHelper(Thread* thread, Zone* zone = thread->zone(); auto object_store = thread->isolate_group()->object_store(); #if !defined(PRODUCT) - if (!bypass_debugger) { + Isolate* isolate = thread->isolate(); + // TODO(dartbug.com/60507): Support debugging of isolate group dart mutator. + if (!bypass_debugger && isolate != nullptr) { // Do not notify debugger on stack overflow and out of memory exceptions. // The VM would crash when the debugger calls back into the VM to // get values of variables. diff --git a/runtime/vm/ffi_callback_metadata.h b/runtime/vm/ffi_callback_metadata.h index 2f596239b71..7fb7c724721 100644 --- a/runtime/vm/ffi_callback_metadata.h +++ b/runtime/vm/ffi_callback_metadata.h @@ -12,6 +12,9 @@ namespace dart { +class Closure; +class Function; +class Isolate; class PersistentHandle; // Stores metadata related to FFI callbacks (Dart functions that are assigned a diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc index 3fefaea54af..05a1e3a66b3 100644 --- a/runtime/vm/isolate.cc +++ b/runtime/vm/isolate.cc @@ -20,7 +20,6 @@ #include "vm/dart_api_state.h" #include "vm/dart_entry.h" #include "vm/debugger.h" -#include "vm/deopt_instructions.h" #include "vm/dispatch_table.h" #include "vm/ffi_callback_metadata.h" #include "vm/flags.h" @@ -1869,8 +1868,6 @@ Isolate::~Isolate() { delete message_handler_; message_handler_ = nullptr; // Fail fast if we send messages to a dead isolate. - ASSERT(deopt_context_ == - nullptr); // No deopt in progress when isolate deleted. ASSERT(spawn_count_ == 0); // The [Thread] object should've been released on the last @@ -2792,13 +2789,6 @@ void Isolate::VisitObjectPointers(ObjectPointerVisitor* visitor, } #endif // !defined(PRODUCT) -#if !defined(DART_PRECOMPILED_RUNTIME) - // Visit objects that are being used for deoptimization. - if (deopt_context() != nullptr) { - deopt_context()->VisitObjectPointers(visitor); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - visitor->VisitPointer( reinterpret_cast(&loaded_prefixes_set_storage_)); diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h index a210c37decc..c98cf5477d0 100644 --- a/runtime/vm/isolate.h +++ b/runtime/vm/isolate.h @@ -48,7 +48,6 @@ class Become; class Capability; class CodeIndexTable; class Debugger; -class DeoptContext; class ExternalTypedData; class GroupDebugger; class HandleScope; @@ -776,19 +775,25 @@ class IsolateGroup : public IntrusiveDListEntry { Isolate* EnterTemporaryIsolate(); static void ExitTemporaryIsolate(); + Mutex* cache_mutex() { return &cache_mutex_; } void RunWithCachedCatchEntryMoves( const Code& code, intptr_t pc, std::function action); void ClearCatchEntryMovesCacheLocked(); + HandlerInfoCache* handler_info_cache() { return &handler_info_cache_; } void SetNativeAssetsCallbacks(NativeAssetsApi* native_assets_api) { native_assets_api_ = *native_assets_api; } NativeAssetsApi* native_assets_api() { return &native_assets_api_; } - Mutex* cache_mutex() { return &cache_mutex_; } - HandlerInfoCache* handler_info_cache() { return &handler_info_cache_; } + bool has_attempted_stepping() const { + return has_attempted_stepping_.load(std::memory_order_relaxed); + } + void set_has_attempted_stepping(bool value) { + has_attempted_stepping_.store(value, std::memory_order_relaxed); + } private: friend class Dart; // For `object_store_ = ` in Dart::Init @@ -945,6 +950,8 @@ class IsolateGroup : public IntrusiveDListEntry { Mutex cache_mutex_; HandlerInfoCache handler_info_cache_; CatchEntryMovesCache catch_entry_moves_cache_; + + std::atomic has_attempted_stepping_; }; // When an isolate sends-and-exits this class represent things that it passed @@ -1140,12 +1147,6 @@ class Isolate : public IntrusiveDListEntry { return has_completed_blocks_.exchange(1) == 0; } - void set_single_step(bool value) { single_step_ = value; } - bool single_step() const { return single_step_; } - static intptr_t single_step_offset() { - return OFFSET_OF(Isolate, single_step_); - } - void set_has_resumption_breakpoints(bool value) { has_resumption_breakpoints_ = value; } @@ -1263,13 +1264,6 @@ class Isolate : public IntrusiveDListEntry { intptr_t NumServiceIdZones() const; #endif // !defined(PRODUCT) - bool IsDeoptimizing() const { return deopt_context_ != nullptr; } - DeoptContext* deopt_context() const { return deopt_context_; } - void set_deopt_context(DeoptContext* value) { - ASSERT(value == nullptr || deopt_context_ == nullptr); - deopt_context_ = value; - } - FfiCallbackMetadata::Trampoline CreateAsyncFfiCallback( Zone* zone, const Function& send_function, @@ -1430,13 +1424,6 @@ class Isolate : public IntrusiveDListEntry { #undef FLAG_FOR_PRODUCT #undef DECLARE_GETTER - bool has_attempted_stepping() const { - return isolate_flags_.Read(); - } - void set_has_attempted_stepping(bool value) { - isolate_flags_.UpdateBool(value); - } - // Kills all non-system isolates. static void KillAllIsolates(LibMsgId msg_id); // Kills all system isolates, excluding the kernel service and VM service. @@ -1569,7 +1556,6 @@ class Isolate : public IntrusiveDListEntry { // Used to clear out `UntaggedFinalizerBase::isolate_` pointers on isolate // shutdown to prevent usage of dangling pointers. GrowableObjectArrayPtr finalizers_; - bool single_step_ = false; bool has_resumption_breakpoints_ = false; // End accessed from generated code. @@ -1672,7 +1658,6 @@ class Isolate : public IntrusiveDListEntry { Mutex mutex_; // Protects compiler stats. IsolateMessageHandler* message_handler_ = nullptr; intptr_t defer_finalization_count_ = 0; - DeoptContext* deopt_context_ = nullptr; FfiCallbackMetadata::Metadata* ffi_callback_list_head_ = nullptr; intptr_t ffi_callback_keep_alive_counter_ = 0; RelaxedAtomic owner_thread_ = OSThread::kInvalidThreadId; diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 76acfde42a9..74e23a0e5ef 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -25665,7 +25665,7 @@ ArrayPtr Array::MakeFixedLength(const GrowableObjectArray& growable_array, // The backing array may be a shared instance, or may not have correct // type parameters. Create a new empty array. - Heap::Space space = thread->IsDartMutatorThread() ? Heap::kNew : Heap::kOld; + Heap::Space space = thread->HasDartMutatorStack() ? Heap::kNew : Heap::kOld; Array& array = Array::Handle(zone, Array::New(0, space)); array.SetTypeArguments(type_arguments); return array.ptr(); diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc index 728d4fdd990..6cbb69f8718 100644 --- a/runtime/vm/profiler.cc +++ b/runtime/vm/profiler.cc @@ -1026,7 +1026,7 @@ class ProfilerDartStackWalker : public ProfilerStackWalker { void walk() { RELEASE_ASSERT(StubCode::HasBeenInitialized()); - if (thread_->isolate()->IsDeoptimizing()) { + if (thread_->IsDeoptimizing()) { sample_->set_ignore_sample(true); return; } @@ -1428,7 +1428,7 @@ void Profiler::SampleThread(Thread* thread, } if (thread->IsDartMutatorThread()) { - if (isolate->IsDeoptimizing()) { + if (thread->IsDeoptimizing()) { counters_.single_frame_sample_deoptimizing.fetch_add(1); SampleThreadSingleFrame(thread, sample, pc); return; diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc index aeb7ecb7708..0b54bcdbce0 100644 --- a/runtime/vm/runtime_entry.cc +++ b/runtime/vm/runtime_entry.cc @@ -1805,7 +1805,7 @@ static void TrySwitchInstanceCall(Thread* thread, #if !defined(PRODUCT) // Monomorphic/megamorphic do not check the isolate's stepping flag. - if (thread->isolate()->has_attempted_stepping()) return; + if (thread->isolate_group()->has_attempted_stepping()) return; #endif // Monomorphic/megamorphic calls are only for unoptimized code. @@ -3186,11 +3186,10 @@ DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethod, 4) { // - garbage collection // - hot reload static void HandleStackOverflowTestCases(Thread* thread) { - auto isolate = thread->isolate(); auto isolate_group = thread->isolate_group(); if (FLAG_shared_slow_path_triggers_gc) { - isolate->group()->heap()->CollectAllGarbage(GCReason::kDebugging); + isolate_group->heap()->CollectAllGarbage(GCReason::kDebugging); } bool do_deopt = false; @@ -3198,10 +3197,10 @@ static void HandleStackOverflowTestCases(Thread* thread) { bool do_reload = false; bool do_gc = false; const intptr_t isolate_reload_every = - isolate->group()->reload_every_n_stack_overflow_checks(); + isolate_group->reload_every_n_stack_overflow_checks(); if ((FLAG_deoptimize_every > 0) || (FLAG_stacktrace_every > 0) || (FLAG_gc_every > 0) || (isolate_reload_every > 0)) { - if (!Isolate::IsSystemIsolate(isolate)) { + if (!IsolateGroup::IsSystemIsolateGroup(isolate_group)) { // TODO(turnidge): To make --deoptimize_every and // --stacktrace-every faster we could move this increment/test to // the generated code. @@ -3283,7 +3282,7 @@ static void HandleStackOverflowTestCases(Thread* thread) { if (do_stacktrace) { String& var_name = String::Handle(); Instance& var_value = Instance::Handle(); - DebuggerStackTrace* stack = isolate->debugger()->StackTrace(); + DebuggerStackTrace* stack = DebuggerStackTrace::Collect(); intptr_t num_frames = stack->Length(); for (intptr_t i = 0; i < num_frames; i++) { ActivationFrame* frame = stack->FrameAt(i); @@ -3306,7 +3305,7 @@ static void HandleStackOverflowTestCases(Thread* thread) { } } if (do_gc) { - isolate->group()->heap()->CollectAllGarbage(GCReason::kDebugging); + isolate_group->heap()->CollectAllGarbage(GCReason::kDebugging); } } #endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) @@ -3427,8 +3426,8 @@ DEFINE_RUNTIME_ENTRY(InterruptOrStackOverflow, 0) { // Use the preallocated stack overflow exception to avoid calling // into dart code. - const Instance& exception = - Instance::Handle(isolate->group()->object_store()->stack_overflow()); + const Instance& exception = Instance::Handle( + thread->isolate_group()->object_store()->stack_overflow()); Exceptions::Throw(thread, exception); UNREACHABLE(); } @@ -3826,7 +3825,6 @@ DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, uword is_lazy_deopt) { #if !defined(DART_PRECOMPILED_RUNTIME) Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); StackZone zone(thread); // All registers have been saved below last-fp as if they were locals. @@ -3881,7 +3879,7 @@ DEFINE_LEAF_RUNTIME_ENTRY(intptr_t, DeoptContext* deopt_context = new DeoptContext( caller_frame, optimized_code, DeoptContext::kDestIsOriginalFrame, fpu_registers, cpu_registers, is_lazy_deopt != 0, deoptimizing_code); - isolate->set_deopt_context(deopt_context); + thread->set_deopt_context(deopt_context); // Stack size (FP - SP) in bytes. return deopt_context->DestStackAdjustment() * kWordSize; @@ -3897,10 +3895,9 @@ END_LEAF_RUNTIME_ENTRY DEFINE_LEAF_RUNTIME_ENTRY(void, DeoptimizeFillFrame, 1, uword last_fp) { #if !defined(DART_PRECOMPILED_RUNTIME) Thread* thread = Thread::Current(); - Isolate* isolate = thread->isolate(); StackZone zone(thread); - DeoptContext* deopt_context = isolate->deopt_context(); + DeoptContext* deopt_context = thread->deopt_context(); DartFrameIterator iterator(last_fp, thread, StackFrameIterator::kNoCrossThreadIteration); StackFrame* caller_frame = iterator.NextFrame(); @@ -3947,9 +3944,9 @@ DEFINE_RUNTIME_ENTRY(DeoptimizeMaterialize, 0) { ValidateFrames(); } #endif - DeoptContext* deopt_context = isolate->deopt_context(); + DeoptContext* deopt_context = thread->deopt_context(); intptr_t deopt_arg_count = deopt_context->MaterializeDeferredObjects(); - isolate->set_deopt_context(nullptr); + thread->set_deopt_context(nullptr); delete deopt_context; // Return value tells deoptimization stub to remove the given number of bytes diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc index a099665fad6..fea699c1cf9 100644 --- a/runtime/vm/thread.cc +++ b/runtime/vm/thread.cc @@ -6,6 +6,7 @@ #include "vm/cpu.h" #include "vm/dart_api_state.h" +#include "vm/deopt_instructions.h" #include "vm/growable_array.h" #include "vm/heap/safepoint.h" #include "vm/isolate.h" @@ -41,6 +42,9 @@ Thread::~Thread() { ASSERT(old_marking_stack_block_ == nullptr); ASSERT(new_marking_stack_block_ == nullptr); ASSERT(deferred_marking_stack_block_ == nullptr); + ASSERT(!ActiveMutatorStolenField::decode(safepoint_state_)); + ASSERT(deopt_context_ == + nullptr); // No deopt in progress when thread is deleted. #if defined(DART_DYNAMIC_MODULES) delete interpreter_; interpreter_ = nullptr; @@ -274,6 +278,14 @@ void Thread::AssertNonMutatorInvariants() { AssertNonDartMutatorInvariants(); } +void Thread::AssertDartMutatorInvariants() { + ASSERT(IsDartMutatorThread()); + ASSERT(isolate() == nullptr); + ASSERT(isolate_group() != nullptr); + ASSERT(task_kind_ == kMutatorTask); + DEBUG_ASSERT(!IsAnyReusableHandleScopeActive()); +} + void Thread::AssertNonDartMutatorInvariants() { ASSERT(!IsDartMutatorThread()); ASSERT(isolate() == nullptr); @@ -391,10 +403,9 @@ void Thread::EnterIsolate(Isolate* isolate) { ASSERT(thread->isolate() == isolate); ASSERT(thread->isolate_group() == isolate->group()); } else { - thread = AddActiveThread(group, isolate, /*is_dart_mutator*/ true, + thread = AddActiveThread(group, isolate, kMutatorTask, /*bypass_safepoint=*/false); - thread->SetupState(kMutatorTask); - thread->SetupMutatorState(kMutatorTask); + thread->SetupMutatorState(); thread->SetupDartMutatorState(isolate); } @@ -466,12 +477,10 @@ void Thread::ExitIsolate(bool isolate_shutdown) { } thread->set_execution_state(Thread::kThreadInNative); } else { - thread->ResetDartMutatorState(isolate); + thread->ResetDartMutatorState(); thread->ResetMutatorState(); - thread->ResetState(); SuspendDartMutatorThreadInternal(thread, VMTag::kInvalidTagId); - FreeActiveThread(thread, isolate, /*is_dart_mutator=*/true, - /*bypass_safepoint=*/false); + FreeActiveThread(thread, isolate, /*bypass_safepoint=*/false); } // To let VM's thread pool (if we run on it) know that this thread is @@ -485,13 +494,12 @@ void Thread::ExitIsolate(bool isolate_shutdown) { void Thread::EnterIsolateGroupAsHelper(IsolateGroup* isolate_group, TaskKind kind, bool bypass_safepoint) { - Thread* thread = AddActiveThread(isolate_group, /*isolate=*/nullptr, - /*is_dart_mutator=*/false, bypass_safepoint); + Thread* thread = AddActiveThread(isolate_group, /*isolate=*/nullptr, kind, + bypass_safepoint); RELEASE_ASSERT(thread != nullptr); - thread->SetupState(kind); // Even if [bypass_safepoint] is true, a thread may need mutator state (e.g. // parallel scavenger threads write to the [Thread]s storebuffer) - thread->SetupMutatorState(kind); + thread->SetupMutatorState(); ResumeThreadInternal(thread); thread->AssertNonDartMutatorInvariants(); @@ -504,19 +512,48 @@ void Thread::ExitIsolateGroupAsHelper(bool bypass_safepoint) { // Even if [bypass_safepoint] is true, a thread may need mutator state (e.g. // parallel scavenger threads write to the [Thread]s storebuffer) thread->ResetMutatorState(); - thread->ResetState(); SuspendThreadInternal(thread, VMTag::kInvalidTagId); - FreeActiveThread(thread, /*isolate=*/nullptr, /*is_dart_mutator=*/false, - bypass_safepoint); + FreeActiveThread(thread, /*isolate=*/nullptr, bypass_safepoint); +} + +void Thread::EnterIsolateGroupAsMutator(IsolateGroup* isolate_group, + bool bypass_safepoint) { + Thread* thread = AddActiveThread(isolate_group, /*isolate=*/nullptr, + kMutatorTask, bypass_safepoint); + RELEASE_ASSERT(thread != nullptr); + // Even if [bypass_safepoint] is true, a thread may need mutator state (e.g. + // parallel scavenger threads write to the [Thread]s storebuffer) + thread->SetupMutatorState(); + thread->SetupDartMutatorStateDependingOnSnapshot(isolate_group); + + ResumeThreadInternal(thread); +#if defined(USING_SIMULATOR) + thread->SetStackLimit(Simulator::Current()->overflow_stack_limit()); +#else + thread->SetStackLimit(OSThread::Current()->overflow_stack_limit()); +#endif + + thread->AssertDartMutatorInvariants(); +} + +void Thread::ExitIsolateGroupAsMutator(bool bypass_safepoint) { + Thread* thread = Thread::Current(); + thread->AssertDartMutatorInvariants(); + + // Even if [bypass_safepoint] is true, a thread may need mutator state (e.g. + // parallel scavenger threads write to the [Thread]s storebuffer) + thread->ResetDartMutatorState(); + thread->ResetMutatorState(); + thread->ClearStackLimit(); + SuspendThreadInternal(thread, VMTag::kInvalidTagId); + FreeActiveThread(thread, /*isolate=*/nullptr, bypass_safepoint); } void Thread::EnterIsolateGroupAsNonMutator(IsolateGroup* isolate_group, TaskKind kind) { - Thread* thread = - AddActiveThread(isolate_group, /*isolate=*/nullptr, - /*is_dart_mutator=*/false, /*bypass_safepoint=*/true); - ASSERT(thread != nullptr); - thread->SetupState(kind); + Thread* thread = AddActiveThread(isolate_group, /*isolate=*/nullptr, kind, + /*bypass_safepoint=*/true); + RELEASE_ASSERT(thread != nullptr); ResumeThreadInternal(thread); thread->AssertNonMutatorInvariants(); @@ -527,10 +564,8 @@ void Thread::ExitIsolateGroupAsNonMutator() { ASSERT(thread != nullptr); thread->AssertNonMutatorInvariants(); - thread->ResetState(); SuspendThreadInternal(thread, VMTag::kInvalidTagId); - FreeActiveThread(thread, /*isolate=*/nullptr, /*is_dart_mutator=*/false, - /*bypass_safepoint=*/true); + FreeActiveThread(thread, /*isolate=*/nullptr, /*bypass_safepoint=*/true); } void Thread::ResumeDartMutatorThreadInternal(Thread* thread) { @@ -591,7 +626,7 @@ void Thread::SuspendThreadInternal(Thread* thread, VMTag::VMTagId tag) { Thread* Thread::AddActiveThread(IsolateGroup* group, Isolate* isolate, - bool is_dart_mutator, + TaskKind task_kind, bool bypass_safepoint) { // NOTE: We cannot just use `Dart::vm_isolate() == this` here, since during // VM startup it might not have been set at this point. @@ -610,11 +645,12 @@ Thread* Thread::AddActiveThread(IsolateGroup* group, Thread* thread = thread_registry->GetFreeThreadLocked(is_vm_isolate); thread->AssertEmptyThreadInvariants(); + thread->SetupStateLocked(task_kind); thread->isolate_ = isolate; // May be nullptr. thread->isolate_group_ = group; thread->scheduled_dart_mutator_isolate_ = isolate; - if (is_dart_mutator) { + if (isolate != nullptr && task_kind == kMutatorTask) { ASSERT(thread_registry->threads_lock()->IsOwnedByCurrentThread()); isolate->mutator_thread_ = thread; } @@ -631,7 +667,6 @@ Thread* Thread::AddActiveThread(IsolateGroup* group, void Thread::FreeActiveThread(Thread* thread, Isolate* isolate, - bool is_dart_mutator, bool bypass_safepoint) { ASSERT(!thread->HasActiveState()); ASSERT(!thread->IsAtSafepoint()); @@ -672,13 +707,14 @@ void Thread::FreeActiveThread(Thread* thread, thread->isolate_ = nullptr; thread->isolate_group_ = nullptr; thread->scheduled_dart_mutator_isolate_ = nullptr; - if (is_dart_mutator) { + if (isolate != nullptr && thread->task_kind() == kMutatorTask) { ASSERT(thread_registry->threads_lock()->IsOwnedByCurrentThread()); isolate->mutator_thread_ = nullptr; } thread->set_execution_state(Thread::kThreadInNative); thread->stack_limit_.store(0); thread->safepoint_state_ = 0; + thread->ResetStateLocked(); thread->AssertEmptyThreadInvariants(); thread_registry->ReturnThreadLocked(thread); @@ -762,7 +798,8 @@ ErrorPtr Thread::HandleInterrupts(uword interrupt_bits) { heap()->CheckFinalizeMarking(this); #if !defined(PRODUCT) - if (isolate()->TakeHasCompletedBlocks()) { + // TODO(dartbug.com/60508): Allow profiling of isolate-group-shared code. + if (isolate() != nullptr && isolate()->TakeHasCompletedBlocks()) { Profiler::ProcessCompletedBlocks(isolate()); } #endif // !defined(PRODUCT) @@ -1000,6 +1037,13 @@ void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor, } #endif +#if !defined(DART_PRECOMPILED_RUNTIME) + // Visit objects that are being used for deoptimization. + if (deopt_context() != nullptr) { + deopt_context()->VisitObjectPointers(visitor); + } +#endif // !defined(DART_PRECOMPILED_RUNTIME) + // Visit the api local scope as it has all the api local handles. ApiLocalScope* scope = api_top_scope_; while (scope != nullptr) { @@ -1008,7 +1052,7 @@ void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor, } // Only the mutator thread can run Dart code. - if (IsDartMutatorThread()) { + if (HasDartMutatorStack()) { // The MarkTask, which calls this method, can run on a different thread. We // therefore assume the mutator is at a safepoint and we can iterate its // stack. @@ -1484,16 +1528,16 @@ bool Thread::CanAcquireSafepointLocks() const { this) >= SafepointLevel::kGCAndDeoptAndReload; } -void Thread::SetupState(TaskKind kind) { +void Thread::SetupStateLocked(TaskKind kind) { task_kind_ = kind; } -void Thread::ResetState() { +void Thread::ResetStateLocked() { task_kind_ = kUnknownTask; vm_tag_ = VMTag::kInvalidTagId; } -void Thread::SetupMutatorState(TaskKind kind) { +void Thread::SetupMutatorState() { ASSERT(store_buffer_block_ == nullptr); if (isolate_group()->old_marking_stack() != nullptr) { @@ -1507,7 +1551,7 @@ void Thread::SetupMutatorState(TaskKind kind) { // TODO(koda): Use StoreBufferAcquire once we properly flush // before Scavenge. - if (kind == kMutatorTask) { + if (task_kind_ == kMutatorTask) { StoreBufferAcquire(); } else { store_buffer_block_ = isolate_group()->store_buffer()->PopEmptyBlock(); @@ -1560,7 +1604,7 @@ void Thread::SetupDartMutatorStateDependingOnSnapshot(IsolateGroup* group) { shared_field_table_values_ = group->shared_field_table()->table(); } -void Thread::ResetDartMutatorState(Isolate* isolate) { +void Thread::ResetDartMutatorState() { ASSERT(execution_state() == Thread::kThreadInVM); is_unwind_in_progress_ = false; diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h index b2c562fecf1..e04b8cc0d52 100644 --- a/runtime/vm/thread.h +++ b/runtime/vm/thread.h @@ -35,11 +35,12 @@ namespace dart { class AbstractType; class ApiLocalScope; class Array; +class Bytecode; class CompilerState; class CompilerTimings; class Class; class Code; -class Bytecode; +class DeoptContext; class Error; class ExceptionHandlers; class Field; @@ -346,6 +347,17 @@ struct TsanUtils { } }; +class MutatorThreadVisitor { + public: + MutatorThreadVisitor() {} + virtual ~MutatorThreadVisitor() {} + + virtual void VisitMutatorThread(Thread* isolate) = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(MutatorThreadVisitor); +}; + // A VM thread; may be executing Dart code or performing helper tasks like // garbage collection or compilation. The Thread structure associated with // a thread is allocated by EnsureInit before entering an isolate, and destroyed @@ -378,6 +390,7 @@ class Thread : public ThreadState { // across `Thread::ExitIsolate()` and `Thread::EnterIsolate()`. bool HasActiveState(); void AssertNonMutatorInvariants(); + void AssertDartMutatorInvariants(); void AssertNonDartMutatorInvariants(); void AssertEmptyStackInvariants(); void AssertEmptyThreadInvariants(); @@ -396,6 +409,10 @@ class Thread : public ThreadState { TaskKind kind); static void ExitIsolateGroupAsNonMutator(); + static void EnterIsolateGroupAsMutator(IsolateGroup* isolate_group, + bool bypass_safepoint); + static void ExitIsolateGroupAsMutator(bool bypass_safepoint); + // Empties the store buffer block into the isolate. void ReleaseStoreBuffer(); void AcquireMarkingStack(); @@ -488,8 +505,12 @@ class Thread : public ThreadState { return OFFSET_OF(Thread, exit_through_ffi_); } - TaskKind task_kind() const { return task_kind_; } - void set_task_kind(TaskKind kind) { task_kind_ = kind; } + TaskKind task_kind() const { + return task_kind_.load(std::memory_order_acquire); + } + void set_task_kind(TaskKind kind) { + task_kind_.store(kind, std::memory_order_release); + } // Retrieves and clears the stack overflow flags. These are set by // the generated code before the slow path runtime routine for a @@ -562,8 +583,12 @@ class Thread : public ThreadState { return OFFSET_OF(Thread, shared_field_table_values_); } - bool IsDartMutatorThread() const { - return scheduled_dart_mutator_isolate_ != nullptr; + bool IsDartMutatorThread() const { return task_kind_ == kMutatorTask; } + + bool HasDartMutatorStack() const { + // The thread with dart mutator task might be temporarily + // occupied by a gc task. + return IsDartMutatorThread() || scheduled_dart_mutator_isolate_ != nullptr; } // Returns the dart mutator [Isolate] this thread belongs to or nullptr. @@ -1295,6 +1320,19 @@ class Thread : public ThreadState { } #endif + void set_single_step(bool value) { single_step_ = value; } + bool single_step() const { return single_step_; } + static intptr_t single_step_offset() { + return OFFSET_OF(Thread, single_step_); + } + + bool IsDeoptimizing() const { return deopt_context_ != nullptr; } + DeoptContext* deopt_context() const { return deopt_context_; } + void set_deopt_context(DeoptContext* value) { + ASSERT(value == nullptr || deopt_context_ == nullptr); + deopt_context_ = value; + } + private: template T* AllocateReusableHandle(); @@ -1436,6 +1474,8 @@ class Thread : public ThreadState { TsanUtils* tsan_utils_ = nullptr; + bool single_step_ = false; + // ---- End accessed from generated code. ---- // The layout of Thread object up to this point should not depend @@ -1444,7 +1484,7 @@ class Thread : public ThreadState { // DART_PRECOMPILED_RUNTIME. uword true_end_ = 0; - TaskKind task_kind_; + std::atomic task_kind_; TimelineStream* const dart_stream_; StreamInfo* const service_extension_stream_; mutable Monitor thread_lock_; @@ -1555,6 +1595,8 @@ class Thread : public ThreadState { bytecode::BytecodeLoader* bytecode_loader_ = nullptr; #endif + DeoptContext* deopt_context_ = nullptr; + explicit Thread(bool is_vm_isolate); void StoreBufferRelease( @@ -1576,15 +1618,15 @@ class Thread : public ThreadState { void EnterSafepointUsingLock(); void ExitSafepointUsingLock(); - void SetupState(TaskKind kind); - void ResetState(); + void SetupStateLocked(TaskKind kind); + void ResetStateLocked(); - void SetupMutatorState(TaskKind kind); + void SetupMutatorState(); void ResetMutatorState(); void SetupDartMutatorState(Isolate* isolate); void SetupDartMutatorStateDependingOnSnapshot(IsolateGroup* group); - void ResetDartMutatorState(Isolate* isolate); + void ResetDartMutatorState(); static void SuspendDartMutatorThreadInternal(Thread* thread, VMTag::VMTagId tag); @@ -1593,7 +1635,7 @@ class Thread : public ThreadState { static void SuspendThreadInternal(Thread* thread, VMTag::VMTagId tag); static void ResumeThreadInternal(Thread* thread); - // Adds a new active mutator thread to thread registry while associating it + // Adds a new active thread to thread registry while associating it // with the given isolate (group). // // All existing safepoint operations are waited for before adding the thread @@ -1603,15 +1645,14 @@ class Thread : public ThreadState { // safepoint (but can access `Thread::isolate()`). static Thread* AddActiveThread(IsolateGroup* group, Isolate* isolate, - bool is_dart_mutator, + TaskKind task_kind, bool bypass_safepoint); - // Releases a active mutator threads from the thread registry. + // Releases an active thread from the thread registry. // // Thread needs to be at-safepoint. static void FreeActiveThread(Thread* thread, Isolate* isolate, - bool is_dart_mutator, bool bypass_safepoint); static void SetCurrent(Thread* current) { OSThread::SetCurrentTLS(current); } diff --git a/runtime/vm/thread_registry.cc b/runtime/vm/thread_registry.cc index b4b09f79746..c134d6fa513 100644 --- a/runtime/vm/thread_registry.cc +++ b/runtime/vm/thread_registry.cc @@ -51,7 +51,7 @@ void ThreadRegistry::VisitObjectPointers( if (thread->isolate_group() == isolate_group_of_interest) { // The mutator thread is visited by the isolate itself (see // [IsolateGroup::VisitStackPointers]). - if (!thread->IsDartMutatorThread()) { + if (!thread->HasDartMutatorStack()) { thread->VisitObjectPointers(visitor, validate_frames); } } @@ -121,7 +121,6 @@ intptr_t ThreadRegistry::StealActiveMutators(ThreadPool* pool) { Thread* thread = active_list_; while (thread != nullptr) { if (thread->TryStealActiveMutator()) { - ASSERT(thread->IsDartMutatorThread()); pool->MarkWorkerAsBlocked(thread->os_thread()); count++; } diff --git a/sdk/lib/_internal/js_dev_runtime/patch/internal_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/internal_patch.dart index 9a1fb48a72f..1933373afd5 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/internal_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/internal_patch.dart @@ -113,3 +113,11 @@ Future loadDynamicModule({Uri? uri, Uint8List? bytes}) { } return completer.future; } + +@patch +@pragma("vm:entry-point") +abstract interface class IsolateGroup { + @patch + static Object _runSync(Object computation) => + throw UnsupportedError("_runSync"); +} diff --git a/sdk/lib/_internal/js_runtime/lib/internal_patch.dart b/sdk/lib/_internal/js_runtime/lib/internal_patch.dart index 96bf78cb247..8b2907c481e 100644 --- a/sdk/lib/_internal/js_runtime/lib/internal_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/internal_patch.dart @@ -91,3 +91,11 @@ T unsafeCast(dynamic v) => v; @patch Future loadDynamicModule({Uri? uri, Uint8List? bytes}) => throw 'Unsupported operation'; + +@patch +@pragma("vm:entry-point") +abstract interface class IsolateGroup { + @patch + static Object _runSync(Object computation) => + throw UnsupportedError("_runSync"); +} diff --git a/sdk/lib/_internal/vm/lib/concurrent_patch.dart b/sdk/lib/_internal/vm/lib/concurrent_patch.dart index 5fa7bc0845f..fb483342025 100644 --- a/sdk/lib/_internal/vm/lib/concurrent_patch.dart +++ b/sdk/lib/_internal/vm/lib/concurrent_patch.dart @@ -37,7 +37,7 @@ abstract interface class ConditionVariable { factory ConditionVariable._() => _ConditionVariableImpl(); } -@pragma('vm:entry-point') +@pragma("vm:entry-point") base class _ConditionVariableImpl extends NativeFieldWrapperClass1 implements ConditionVariable { _ConditionVariableImpl() { diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart index ff2b2317c37..0dd8ced4b3b 100644 --- a/sdk/lib/_internal/vm/lib/internal_patch.dart +++ b/sdk/lib/_internal/vm/lib/internal_patch.dart @@ -474,3 +474,11 @@ Future loadDynamicModule({Uri? uri, Uint8List? bytes}) { @pragma("vm:external-name", "Internal_loadDynamicModule") external Object? _loadDynamicModule(Uint8List bytes); + +@patch +@pragma("vm:entry-point") +abstract interface class IsolateGroup { + @patch + @Native(symbol: "IsolateGroup_runSync") + external static Object _runSync(Object computation); +} diff --git a/sdk/lib/_internal/wasm/lib/internal_patch.dart b/sdk/lib/_internal/wasm/lib/internal_patch.dart index 4a162a425a4..1841d662c70 100644 --- a/sdk/lib/_internal/wasm/lib/internal_patch.dart +++ b/sdk/lib/_internal/wasm/lib/internal_patch.dart @@ -224,3 +224,11 @@ external void pushWasmArray( /// slot in the array, which may cause memory leaks. Callers should manually /// clear non-nullable reference element slots in the array when popping. external T popWasmArray(WasmArray array, int length); + +@patch +@pragma("vm:entry-point") +abstract interface class IsolateGroup { + @patch + static Object _runSync(Object computation) => + throw UnsupportedError("_runSync"); +} diff --git a/sdk/lib/internal/internal.dart b/sdk/lib/internal/internal.dart index 231592ed767..a0983ab143a 100644 --- a/sdk/lib/internal/internal.dart +++ b/sdk/lib/internal/internal.dart @@ -1152,3 +1152,12 @@ external Future loadDynamicModule({Uri? uri, Uint8List? bytes}); class TypeTest { bool test(Object? v) => v is T; } + +/// Should be moved to dart:isolate when --experimental-shared-data +/// flag is removed. +abstract interface class IsolateGroup { + external static Object _runSync(Object computation); + + /// Runs [computation] in isolate-group shared context. + static R runSync(R computation()) => _runSync(computation) as R; +} diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status index 29792595919..1a8b0bf988f 100644 --- a/tests/ffi/ffi.status +++ b/tests/ffi/ffi.status @@ -60,6 +60,7 @@ function_callbacks_structs_by_value_generated_test/*: Skip # Test harness doesn' function_callbacks_structs_by_value_native_callable_generated_test/*: Skip # Test harness doesn't support multitest with Fuchsia function_callbacks_subtype_test/*: Skip # Test harness doesn't support multitest with Fuchsia native_assets/*: Skip # Source not available in the emulator +run_isolate_group_run_test: Skip # gen_snapshot requires experimental-shared-data flag static_checks/*: SkipByDesign # Expecting compile time failures in multi tests doesn't work on the Fuchsia test runner. unaligned_test/*: Skip # Test harness doesn't support multitest with Fuchsia vmspecific_enable_ffi_test/*: Skip # Test harness doesn't support multitest with Fuchsia diff --git a/tests/ffi/run_isolate_group_run_test.dart b/tests/ffi/run_isolate_group_run_test.dart new file mode 100644 index 00000000000..e08ea8ac275 --- /dev/null +++ b/tests/ffi/run_isolate_group_run_test.dart @@ -0,0 +1,68 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// +// Tests IsolateGroup.runSync - what works, what doesn't. +// +// VMOptions=--experimental-shared-data +// VMOptions=--experimental-shared-data --use-slow-path +// VMOptions=--experimental-shared-data --use-slow-path --stacktrace-every=100 +// VMOptions=--experimental-shared-data --dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects +// VMOptions=--experimental-shared-data --test_il_serialization +// VMOptions=--experimental-shared-data --profiler --profile_vm=true +// VMOptions=--experimental-shared-data --profiler --profile_vm=false + +import 'package:dart_internal/isolate_group.dart' show IsolateGroup; +import 'dart:concurrent'; +import 'dart:isolate'; + +import "package:expect/expect.dart"; + +var foo = 42; + +@pragma('vm:never-inline') +updateFoo() { + foo = 56; +} + +main() { + Expect.equals(42, IsolateGroup.runSync(() => 42)); + + Expect.listEquals([1, 2, 3], IsolateGroup.runSync(() => [1, 2, 3])); + + Expect.throws( + () { + IsolateGroup.runSync(() { + throw "error"; + }); + }, + (e) => e == "error", + 'Expect thrown error', + ); + + // Documenting current limitations. + Expect.notEquals(() { + IsolateGroup.runSync(() { + return Isolate.current; + }); + }, Isolate.current); + // + // Following crashes VM since field_table is not set up on + // isolate group mutator thread. + // + // Expect.throws(() { + // IsolateGroup.runSync(() { + // print('42'); + // }); + // }, (e) => e is Error && e.toString().contains("Unsupported operation")); + + // updateFoo(); + // Expect.equals( + // IsolateGroup.runSync(() { + // return foo; + // }), + // 42, + // ); + + print("All tests completed :)"); +}