diff --git a/runtime/docs/compiler/aot/entry_point_pragma.md b/runtime/docs/compiler/aot/entry_point_pragma.md index 3694a98444b..fc68848a9d8 100644 --- a/runtime/docs/compiler/aot/entry_point_pragma.md +++ b/runtime/docs/compiler/aot/entry_point_pragma.md @@ -35,7 +35,7 @@ Any one of the following forms may be attached to a class: ```dart @pragma("vm:entry-point") @pragma("vm:entry-point", true/false) -@pragma("vm:entry-point", !const bool.formEnvironment("dart.vm.product")) +@pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product")) class C { ... } ``` @@ -54,7 +54,7 @@ getters, setters and constructors): ```dart @pragma("vm:entry-point") @pragma("vm:entry-point", true/false) -@pragma("vm:entry-point", !const bool.formEnvironment("dart.vm.product")) +@pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product")) @pragma("vm:entry-point", "get") @pragma("vm:entry-point", "call") void foo() { ... } @@ -83,7 +83,7 @@ three forms may be attached to static fields. @pragma("vm:entry-point") @pragma("vm:entry-point", null) @pragma("vm:entry-point", true/false) -@pragma("vm:entry-point", !const bool.formEnvironment("dart.vm.product")) +@pragma("vm:entry-point", !const bool.fromEnvironment("dart.vm.product")) @pragma("vm:entry-point", "get"/"set") int foo; ``` diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart index a3e51a4bad6..181fd2b9059 100644 --- a/runtime/observatory/lib/src/service/object.dart +++ b/runtime/observatory/lib/src/service/object.dart @@ -1042,9 +1042,9 @@ abstract class VM extends ServiceObjectOwner implements M.VM { nativeZoneMemoryUsage = map['_nativeZoneMemoryUsage']; } pid = map['pid']; - mallocUsed = map['_mallocUsed']; - mallocCapacity = map['_mallocCapacity']; - mallocImplementation = map['_mallocImplementation']; + mallocUsed = map['_mallocUsed'] ?? -1; + mallocCapacity = map['_mallocCapacity'] ?? -1; + mallocImplementation = map['_mallocImplementation'] ?? 'unknown'; embedder = map['_embedder']; currentMemory = map['_currentMemory']; maxRSS = map['_maxRSS']; diff --git a/runtime/observatory/tests/service/developer_extension_test.dart b/runtime/observatory/tests/service/developer_extension_test.dart index 9b18926ce0c..2983cf45da7 100644 --- a/runtime/observatory/tests/service/developer_extension_test.dart +++ b/runtime/observatory/tests/service/developer_extension_test.dart @@ -43,10 +43,15 @@ Future Handler(String method, Map paremeters) { } void test() { + Expect.isFalse(extensionStreamHasListener); + postEvent('Disabled event', {'foo': 'bar'}); + registerExtension('ext..delay', Handler); debugger(); + Expect.isTrue(extensionStreamHasListener); postEvent('ALPHA', {'cat': 'dog'}); debugger(); + registerExtension('ext..error', Handler); registerExtension('ext..exception', Handler); registerExtension('ext..success', Handler); @@ -56,7 +61,7 @@ void test() { } catch (e) { exceptionThrown = true; } - // This check is running in the target process so we can't used package:test. + // This check is running in the target process so we can't use package:test. Expect.isTrue(exceptionThrown); } diff --git a/runtime/observatory_2/tests/service_2/developer_extension_test.dart b/runtime/observatory_2/tests/service_2/developer_extension_test.dart index 61cab8ff4c2..e6df8972d20 100644 --- a/runtime/observatory_2/tests/service_2/developer_extension_test.dart +++ b/runtime/observatory_2/tests/service_2/developer_extension_test.dart @@ -55,7 +55,7 @@ void test() { } catch (e) { exceptionThrown = true; } - // This check is running in the target process so we can't used package:test. + // This check is running in the target process so we can't use package:test. Expect.isTrue(exceptionThrown); } diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc index 905570f7aa7..a7699015535 100644 --- a/runtime/vm/compiler/frontend/kernel_to_il.cc +++ b/runtime/vm/compiler/frontend/kernel_to_il.cc @@ -952,6 +952,7 @@ bool FlowGraphBuilder::IsRecognizedMethodForFlowGraph( case MethodRecognizer::kReachabilityFence: case MethodRecognizer::kUtf8DecoderScan: case MethodRecognizer::kHas63BitSmis: + case MethodRecognizer::kExtensionStreamHasListener: #define CASE(method, slot) case MethodRecognizer::k##method: LOAD_NATIVE_FIELD(CASE) STORE_NATIVE_FIELD(CASE) @@ -1488,6 +1489,17 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod( #else body += Constant(Bool::False()); #endif // defined(ARCH_IS_64_BIT) + } break; + case MethodRecognizer::kExtensionStreamHasListener: { +#ifdef PRODUCT + body += Constant(Bool::False()); +#else + body += LoadServiceExtensionStream(); + body += RawLoadField(compiler::target::StreamInfo::enabled_offset()); + // StreamInfo::enabled_ is a std::atomic. This is effectively + // relaxed order access, which is acceptable for this use case. + body += IntToBool(); +#endif // PRODUCT } break; case MethodRecognizer::kFfiAsExternalTypedDataInt8: case MethodRecognizer::kFfiAsExternalTypedDataInt16: @@ -4077,6 +4089,14 @@ Fragment FlowGraphBuilder::LoadIsolate() { return body; } +Fragment FlowGraphBuilder::LoadServiceExtensionStream() { + Fragment body; + body += LoadThread(); + body += + LoadUntagged(compiler::target::Thread::service_extension_stream_offset()); + return body; +} + // TODO(http://dartbug.com/47487): Support unboxed output value. Fragment FlowGraphBuilder::BoolToInt() { // TODO(http://dartbug.com/36855) Build IfThenElseInstr, instead of letting diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h index 2a92d6ae212..eeab45d479d 100644 --- a/runtime/vm/compiler/frontend/kernel_to_il.h +++ b/runtime/vm/compiler/frontend/kernel_to_il.h @@ -282,6 +282,9 @@ class FlowGraphBuilder : public BaseFlowGraphBuilder { // Loads the (untagged) isolate address. Fragment LoadIsolate(); + // Loads the (untagged) service extension stream address. + Fragment LoadServiceExtensionStream(); + // Converts a true to 1 and false to 0. Fragment BoolToInt(); diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h index 7055a025d60..0331e006143 100644 --- a/runtime/vm/compiler/recognized_methods_list.h +++ b/runtime/vm/compiler/recognized_methods_list.h @@ -268,6 +268,7 @@ namespace dart { V(_RootZone, runUnary, RootZoneRunUnary, 0xb607f8bf) \ V(_FutureListener, handleValue, FutureListenerHandleValue, 0x438115a8) \ V(::, has63BitSmis, Has63BitSmis, 0xf61b56f1) \ + V(::, get:extensionStreamHasListener, ExtensionStreamHasListener, 0xfab46343)\ // List of intrinsics: // (class-name, function-name, intrinsification method, fingerprint). diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h index 41ad454c44f..f36cdc73647 100644 --- a/runtime/vm/compiler/runtime_api.h +++ b/runtime/vm/compiler/runtime_api.h @@ -1068,6 +1068,11 @@ class TimelineStream : public AllStatic { static word enabled_offset(); }; +class StreamInfo : public AllStatic { + public: + static word enabled_offset(); +}; + class VMHandles : public AllStatic { public: static constexpr intptr_t kOffsetOfRawPtrInHandle = kWordSize; @@ -1099,6 +1104,7 @@ class Thread : public AllStatic { static uword exit_through_runtime_call(); static uword exit_through_ffi(); static word dart_stream_offset(); + static word service_extension_stream_offset(); static word predefined_symbols_address_offset(); static word optimize_entry_offset(); static word deoptimize_entry_offset(); diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h index 04a65b3697a..49c7e2649fe 100644 --- a/runtime/vm/compiler/runtime_offsets_extracted.h +++ b/runtime/vm/compiler/runtime_offsets_extracted.h @@ -240,6 +240,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 8; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 4; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 4; static constexpr dart::compiler::target::word String_hash_offset = 8; static constexpr dart::compiler::target::word String_length_offset = 4; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4; @@ -287,6 +288,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 44; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 796; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 820; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 312; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 224; @@ -330,7 +333,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 788; static constexpr dart::compiler::target::word Thread_isolate_offset = 40; -static constexpr dart::compiler::target::word Thread_isolate_group_offset = 820; +static constexpr dart::compiler::target::word Thread_isolate_group_offset = 824; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 64; static constexpr dart::compiler::target::word @@ -832,6 +835,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; @@ -880,6 +884,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 1592; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 1632; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424; @@ -924,7 +930,7 @@ static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 1576; static constexpr dart::compiler::target::word Thread_isolate_offset = 80; static constexpr dart::compiler::target::word Thread_isolate_group_offset = - 1632; + 1640; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -1427,6 +1433,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 8; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 4; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 4; static constexpr dart::compiler::target::word String_hash_offset = 8; static constexpr dart::compiler::target::word String_length_offset = 4; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4; @@ -1474,6 +1481,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 44; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 764; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 788; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 312; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 224; @@ -1517,7 +1526,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 756; static constexpr dart::compiler::target::word Thread_isolate_offset = 40; -static constexpr dart::compiler::target::word Thread_isolate_group_offset = 788; +static constexpr dart::compiler::target::word Thread_isolate_group_offset = 792; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 64; static constexpr dart::compiler::target::word @@ -2016,6 +2025,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; @@ -2064,6 +2074,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 1656; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 1696; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424; @@ -2108,7 +2120,7 @@ static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 1640; static constexpr dart::compiler::target::word Thread_isolate_offset = 80; static constexpr dart::compiler::target::word Thread_isolate_group_offset = - 1696; + 1704; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -2613,6 +2625,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; @@ -2661,6 +2674,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 1592; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 1632; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424; @@ -2705,7 +2720,7 @@ static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 1576; static constexpr dart::compiler::target::word Thread_isolate_offset = 80; static constexpr dart::compiler::target::word Thread_isolate_group_offset = - 1632; + 1640; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -3209,6 +3224,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; @@ -3257,6 +3273,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 1656; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 1696; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424; @@ -3301,7 +3319,7 @@ static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 1640; static constexpr dart::compiler::target::word Thread_isolate_offset = 80; static constexpr dart::compiler::target::word Thread_isolate_group_offset = - 1696; + 1704; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -3805,6 +3823,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 8; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 4; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 4; static constexpr dart::compiler::target::word String_hash_offset = 8; static constexpr dart::compiler::target::word String_length_offset = 4; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4; @@ -3852,6 +3871,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 44; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 836; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 860; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 312; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 224; @@ -3895,7 +3916,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 828; static constexpr dart::compiler::target::word Thread_isolate_offset = 40; -static constexpr dart::compiler::target::word Thread_isolate_group_offset = 860; +static constexpr dart::compiler::target::word Thread_isolate_group_offset = 864; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 64; static constexpr dart::compiler::target::word @@ -4399,6 +4420,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; @@ -4447,6 +4469,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 1648; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 1688; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424; @@ -4491,7 +4515,7 @@ static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 1632; static constexpr dart::compiler::target::word Thread_isolate_offset = 80; static constexpr dart::compiler::target::word Thread_isolate_group_offset = - 1688; + 1696; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -4991,6 +5015,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 8; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 4; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 4; static constexpr dart::compiler::target::word String_hash_offset = 8; static constexpr dart::compiler::target::word String_length_offset = 4; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4; @@ -5038,6 +5063,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 44; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 796; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 820; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 312; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 224; @@ -5081,7 +5108,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 788; static constexpr dart::compiler::target::word Thread_isolate_offset = 40; -static constexpr dart::compiler::target::word Thread_isolate_group_offset = 820; +static constexpr dart::compiler::target::word Thread_isolate_group_offset = 824; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 64; static constexpr dart::compiler::target::word @@ -5577,6 +5604,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; @@ -5625,6 +5653,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 1592; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 1632; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424; @@ -5669,7 +5699,7 @@ static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 1576; static constexpr dart::compiler::target::word Thread_isolate_offset = 80; static constexpr dart::compiler::target::word Thread_isolate_group_offset = - 1632; + 1640; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -6166,6 +6196,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 8; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 4; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 4; static constexpr dart::compiler::target::word String_hash_offset = 8; static constexpr dart::compiler::target::word String_length_offset = 4; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4; @@ -6213,6 +6244,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 44; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 764; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 788; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 312; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 224; @@ -6256,7 +6289,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 756; static constexpr dart::compiler::target::word Thread_isolate_offset = 40; -static constexpr dart::compiler::target::word Thread_isolate_group_offset = 788; +static constexpr dart::compiler::target::word Thread_isolate_group_offset = 792; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 64; static constexpr dart::compiler::target::word @@ -6749,6 +6782,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; @@ -6797,6 +6831,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 1656; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 1696; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424; @@ -6841,7 +6877,7 @@ static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 1640; static constexpr dart::compiler::target::word Thread_isolate_offset = 80; static constexpr dart::compiler::target::word Thread_isolate_group_offset = - 1696; + 1704; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -7340,6 +7376,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; @@ -7388,6 +7425,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 1592; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 1632; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424; @@ -7432,7 +7471,7 @@ static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 1576; static constexpr dart::compiler::target::word Thread_isolate_offset = 80; static constexpr dart::compiler::target::word Thread_isolate_group_offset = - 1632; + 1640; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -7930,6 +7969,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; @@ -7978,6 +8018,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 1656; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 1696; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424; @@ -8022,7 +8064,7 @@ static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 1640; static constexpr dart::compiler::target::word Thread_isolate_offset = 80; static constexpr dart::compiler::target::word Thread_isolate_group_offset = - 1696; + 1704; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -8520,6 +8562,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 8; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 4; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 4; static constexpr dart::compiler::target::word String_hash_offset = 8; static constexpr dart::compiler::target::word String_length_offset = 4; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4; @@ -8567,6 +8610,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 44; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 836; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 860; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 312; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 224; @@ -8610,7 +8655,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 828; static constexpr dart::compiler::target::word Thread_isolate_offset = 40; -static constexpr dart::compiler::target::word Thread_isolate_group_offset = 860; +static constexpr dart::compiler::target::word Thread_isolate_group_offset = 864; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 64; static constexpr dart::compiler::target::word @@ -9108,6 +9153,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; @@ -9156,6 +9202,8 @@ static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word Thread_double_truncate_round_supported_offset = 1648; +static constexpr dart::compiler::target::word + Thread_service_extension_stream_offset = 1688; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 424; @@ -9200,7 +9248,7 @@ static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = 1632; static constexpr dart::compiler::target::word Thread_isolate_offset = 80; static constexpr dart::compiler::target::word Thread_isolate_group_offset = - 1688; + 1696; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -9735,6 +9783,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 8; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 4; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 4; static constexpr dart::compiler::target::word AOT_String_hash_offset = 8; static constexpr dart::compiler::target::word AOT_String_length_offset = 4; static constexpr dart::compiler::target::word @@ -9786,6 +9835,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 44; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 796; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 820; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 312; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -9831,7 +9882,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 788; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 820; + 824; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 64; static constexpr dart::compiler::target::word @@ -10401,6 +10452,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_String_hash_offset = 4; static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word @@ -10452,6 +10504,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 1592; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 1632; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -10497,7 +10551,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 1576; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 1632; + 1640; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -11073,6 +11127,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_String_hash_offset = 4; static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word @@ -11124,6 +11179,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 1656; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 1696; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -11169,7 +11226,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 1640; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 1696; + 1704; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -11742,6 +11799,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_String_hash_offset = 4; static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word @@ -11793,6 +11851,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 1592; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 1632; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -11838,7 +11898,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 1576; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 1632; + 1640; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -12410,6 +12470,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_String_hash_offset = 4; static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word @@ -12461,6 +12522,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 1656; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 1696; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -12506,7 +12569,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 1640; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 1696; + 1704; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -13079,6 +13142,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 8; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 4; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 4; static constexpr dart::compiler::target::word AOT_String_hash_offset = 8; static constexpr dart::compiler::target::word AOT_String_length_offset = 4; static constexpr dart::compiler::target::word @@ -13130,6 +13194,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 44; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 836; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 860; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 312; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -13175,7 +13241,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 828; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 860; + 864; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 64; static constexpr dart::compiler::target::word @@ -13747,6 +13813,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_String_hash_offset = 4; static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word @@ -13798,6 +13865,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 1648; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 1688; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -13843,7 +13912,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 1632; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 1688; + 1696; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -14411,6 +14480,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 8; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 4; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 4; static constexpr dart::compiler::target::word AOT_String_hash_offset = 8; static constexpr dart::compiler::target::word AOT_String_length_offset = 4; static constexpr dart::compiler::target::word @@ -14462,6 +14532,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 44; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 796; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 820; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 312; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -14507,7 +14579,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 788; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 820; + 824; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 64; static constexpr dart::compiler::target::word @@ -15070,6 +15142,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_String_hash_offset = 4; static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word @@ -15121,6 +15194,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 1592; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 1632; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -15166,7 +15241,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 1576; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 1632; + 1640; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -15735,6 +15810,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_String_hash_offset = 4; static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word @@ -15786,6 +15862,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 1656; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 1696; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -15831,7 +15909,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 1640; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 1696; + 1704; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -16397,6 +16475,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_String_hash_offset = 4; static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word @@ -16448,6 +16527,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 1592; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 1632; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -16493,7 +16574,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 1576; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 1632; + 1640; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -17058,6 +17139,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_String_hash_offset = 4; static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word @@ -17109,6 +17191,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 1656; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 1696; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -17154,7 +17238,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 1640; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 1696; + 1704; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word @@ -17720,6 +17804,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 8; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 4; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 4; static constexpr dart::compiler::target::word AOT_String_hash_offset = 8; static constexpr dart::compiler::target::word AOT_String_length_offset = 4; static constexpr dart::compiler::target::word @@ -17771,6 +17856,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 44; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 836; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 860; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 312; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -17816,7 +17903,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 828; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 40; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 860; + 864; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 64; static constexpr dart::compiler::target::word @@ -18381,6 +18468,7 @@ static constexpr dart::compiler::target::word AOT_StoreBufferBlock_pointers_offset = 16; static constexpr dart::compiler::target::word AOT_StoreBufferBlock_top_offset = 8; +static constexpr dart::compiler::target::word AOT_StreamInfo_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_String_hash_offset = 4; static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word @@ -18432,6 +18520,8 @@ static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_double_truncate_round_supported_offset = 1648; +static constexpr dart::compiler::target::word + AOT_Thread_service_extension_stream_offset = 1688; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = 600; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = @@ -18477,7 +18567,7 @@ static constexpr dart::compiler::target::word AOT_Thread_exit_through_ffi_offset = 1632; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_isolate_group_offset = - 1688; + 1696; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 128; static constexpr dart::compiler::target::word diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h index 1e03be5f276..65982cf1f2c 100644 --- a/runtime/vm/compiler/runtime_offsets_list.h +++ b/runtime/vm/compiler/runtime_offsets_list.h @@ -186,6 +186,7 @@ FIELD(SingleTargetCache, upper_limit_offset) \ FIELD(StoreBufferBlock, pointers_offset) \ FIELD(StoreBufferBlock, top_offset) \ + FIELD(StreamInfo, enabled_offset) \ FIELD(String, hash_offset) \ FIELD(String, length_offset) \ FIELD(SubtypeTestCache, cache_offset) \ @@ -213,6 +214,7 @@ FIELD(Thread, dart_stream_offset) \ FIELD(Thread, dispatch_table_array_offset) \ FIELD(Thread, double_truncate_round_supported_offset) \ + FIELD(Thread, service_extension_stream_offset) \ FIELD(Thread, optimize_entry_offset) \ FIELD(Thread, optimize_stub_offset) \ FIELD(Thread, deoptimize_entry_offset) \ diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 9162e8b0e75..1ae59b4e438 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -6,6 +6,7 @@ #include +#include "compiler/method_recognizer.h" #include "include/dart_api.h" #include "lib/stacktrace.h" #include "platform/assert.h" @@ -8097,31 +8098,66 @@ void Function::SetIsOptimizable(bool value) const { } bool Function::ForceOptimize() const { - return IsFfiFromAddress() || IsFfiGetAddress() || IsFfiLoad() || - IsFfiStore() || IsFfiTrampoline() || IsFfiAsExternalTypedData() || - IsTypedDataViewFactory() || IsUtf8Scan() || IsGetNativeField() || - IsFinalizerForceOptimized(); + return RecognizedKindForceOptimize() || IsFfiTrampoline() || + IsTypedDataViewFactory(); } -bool Function::IsFinalizerForceOptimized() const { - // Either because of unboxed/untagged data, or because we don't want the GC - // to trigger in between. +bool Function::RecognizedKindForceOptimize() const { switch (recognized_kind()) { + // Uses unboxed/untagged data not supported in unoptimized. case MethodRecognizer::kFinalizerBase_getIsolateFinalizers: case MethodRecognizer::kFinalizerBase_setIsolate: case MethodRecognizer::kFinalizerBase_setIsolateFinalizers: case MethodRecognizer::kFinalizerEntry_getExternalSize: - // Unboxed/untagged representation not supported in unoptimized. - return true; + case MethodRecognizer::kExtensionStreamHasListener: + case MethodRecognizer::kFfiLoadInt8: + case MethodRecognizer::kFfiLoadInt16: + case MethodRecognizer::kFfiLoadInt32: + case MethodRecognizer::kFfiLoadInt64: + case MethodRecognizer::kFfiLoadUint8: + case MethodRecognizer::kFfiLoadUint16: + case MethodRecognizer::kFfiLoadUint32: + case MethodRecognizer::kFfiLoadUint64: + case MethodRecognizer::kFfiLoadFloat: + case MethodRecognizer::kFfiLoadFloatUnaligned: + case MethodRecognizer::kFfiLoadDouble: + case MethodRecognizer::kFfiLoadDoubleUnaligned: + case MethodRecognizer::kFfiLoadPointer: + case MethodRecognizer::kFfiStoreInt8: + case MethodRecognizer::kFfiStoreInt16: + case MethodRecognizer::kFfiStoreInt32: + case MethodRecognizer::kFfiStoreInt64: + case MethodRecognizer::kFfiStoreUint8: + case MethodRecognizer::kFfiStoreUint16: + case MethodRecognizer::kFfiStoreUint32: + case MethodRecognizer::kFfiStoreUint64: + case MethodRecognizer::kFfiStoreFloat: + case MethodRecognizer::kFfiStoreFloatUnaligned: + case MethodRecognizer::kFfiStoreDouble: + case MethodRecognizer::kFfiStoreDoubleUnaligned: + case MethodRecognizer::kFfiStorePointer: + case MethodRecognizer::kFfiFromAddress: + case MethodRecognizer::kFfiGetAddress: + case MethodRecognizer::kFfiAsExternalTypedDataInt8: + case MethodRecognizer::kFfiAsExternalTypedDataInt16: + case MethodRecognizer::kFfiAsExternalTypedDataInt32: + case MethodRecognizer::kFfiAsExternalTypedDataInt64: + case MethodRecognizer::kFfiAsExternalTypedDataUint8: + case MethodRecognizer::kFfiAsExternalTypedDataUint16: + case MethodRecognizer::kFfiAsExternalTypedDataUint32: + case MethodRecognizer::kFfiAsExternalTypedDataUint64: + case MethodRecognizer::kFfiAsExternalTypedDataFloat: + case MethodRecognizer::kFfiAsExternalTypedDataDouble: + case MethodRecognizer::kGetNativeField: + case MethodRecognizer::kUtf8DecoderScan: + // Prevent the GC from running so that the operation is atomic from + // a GC point of view. Always double check implementation in + // kernel_to_il.cc that no GC can happen in between the relevant IL + // instructions. + // TODO(https://dartbug.com/48527): Support inlining. case MethodRecognizer::kFinalizerBase_exchangeEntriesCollectedWithNull: - // Prevent the GC from running so that the operation is atomic from - // a GC point of view. Always double check implementation in - // kernel_to_il.cc that no GC can happen in between the relevant IL - // instructions. - // TODO(https://dartbug.com/48527): Support inlining. - return true; + // Both unboxed/untagged data and atomic-to-GC operation. case MethodRecognizer::kFinalizerEntry_allocate: - // Both of the above reasons. return true; default: return false; @@ -14538,6 +14574,7 @@ void Library::CheckFunctionFingerprints() { all_libs.Add(&Library::ZoneHandle(Library::InternalLibrary())); all_libs.Add(&Library::ZoneHandle(Library::FfiLibrary())); all_libs.Add(&Library::ZoneHandle(Library::NativeWrappersLibrary())); + all_libs.Add(&Library::ZoneHandle(Library::DeveloperLibrary())); INTERNAL_LIB_INTRINSIC_LIST(CHECK_FINGERPRINTS_ASM_INTRINSIC); OTHER_RECOGNIZED_LIST(CHECK_FINGERPRINTS_OTHER); POLYMORPHIC_TARGET_LIST(CHECK_FINGERPRINTS); diff --git a/runtime/vm/object.h b/runtime/vm/object.h index 7d9ffe061d3..3bd1912e2b2 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -3240,7 +3240,8 @@ class Function : public Object { // run. bool ForceOptimize() const; - bool IsFinalizerForceOptimized() const; + // Whether this function's |recognized_kind| requires optimization. + bool RecognizedKindForceOptimize() const; bool CanBeInlined() const; @@ -3549,44 +3550,6 @@ class Function : public Object { UntaggedFunction::kFfiTrampoline; } - bool IsFfiLoad() const { - const auto kind = recognized_kind(); - return MethodRecognizer::kFfiLoadInt8 <= kind && - kind <= MethodRecognizer::kFfiLoadPointer; - } - - bool IsFfiStore() const { - const auto kind = recognized_kind(); - return MethodRecognizer::kFfiStoreInt8 <= kind && - kind <= MethodRecognizer::kFfiStorePointer; - } - - bool IsFfiFromAddress() const { - const auto kind = recognized_kind(); - return kind == MethodRecognizer::kFfiFromAddress; - } - - bool IsFfiGetAddress() const { - const auto kind = recognized_kind(); - return kind == MethodRecognizer::kFfiGetAddress; - } - - bool IsFfiAsExternalTypedData() const { - const auto kind = recognized_kind(); - return MethodRecognizer::kFfiAsExternalTypedDataInt8 <= kind && - kind <= MethodRecognizer::kFfiAsExternalTypedDataDouble; - } - - bool IsGetNativeField() const { - const auto kind = recognized_kind(); - return kind == MethodRecognizer::kGetNativeField; - } - - bool IsUtf8Scan() const { - const auto kind = recognized_kind(); - return kind == MethodRecognizer::kUtf8DecoderScan; - } - // Recognise async functions like: // user_func async { // // ... diff --git a/runtime/vm/service.h b/runtime/vm/service.h index 6bf1e40ccbc..7dc4d4569b1 100644 --- a/runtime/vm/service.h +++ b/runtime/vm/service.h @@ -5,6 +5,8 @@ #ifndef RUNTIME_VM_SERVICE_H_ #define RUNTIME_VM_SERVICE_H_ +#include + #include "include/dart_tools_api.h" #include "vm/allocation.h" @@ -73,17 +75,20 @@ class StreamInfo { const char* id() const { return id_; } - void set_enabled(bool value) { enabled_ = value; } - bool enabled() const { return enabled_; } + void set_enabled(bool value) { enabled_ = value ? 1 : 0; } + bool enabled() const { return !!enabled_; } void set_include_private_members(bool value) { include_private_members_ = value; } bool include_private_members() const { return include_private_members_; } + // This may get access by multiple threads, but relaxed access is ok. + static intptr_t enabled_offset() { return OFFSET_OF(StreamInfo, enabled_); } + private: const char* id_; - bool enabled_; + std::atomic enabled_; bool include_private_members_; }; diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc index e8ad780c06d..573e775d5a4 100644 --- a/runtime/vm/thread.cc +++ b/runtime/vm/thread.cc @@ -19,6 +19,7 @@ #include "vm/os_thread.h" #include "vm/profiler.h" #include "vm/runtime_entry.h" +#include "vm/service.h" #include "vm/stub_code.h" #include "vm/symbols.h" #include "vm/thread_interrupter.h" @@ -39,15 +40,15 @@ DECLARE_FLAG(bool, trace_service_verbose); Thread::~Thread() { // We should cleanly exit any isolate before destruction. - ASSERT(isolate_ == NULL); - ASSERT(store_buffer_block_ == NULL); - ASSERT(marking_stack_block_ == NULL); + ASSERT(isolate_ == nullptr); + ASSERT(store_buffer_block_ == nullptr); + ASSERT(marking_stack_block_ == nullptr); // There should be no top api scopes at this point. - ASSERT(api_top_scope() == NULL); + ASSERT(api_top_scope() == nullptr); // Delete the resusable api scope if there is one. if (api_reusable_scope_ != nullptr) { delete api_reusable_scope_; - api_reusable_scope_ = NULL; + api_reusable_scope_ = nullptr; } DO_IF_TSAN(delete tsan_utils_); @@ -60,21 +61,21 @@ Thread::~Thread() { #define REUSABLE_HANDLE_SCOPE_INIT(object) #endif // defined(DEBUG) -#define REUSABLE_HANDLE_INITIALIZERS(object) object##_handle_(NULL), +#define REUSABLE_HANDLE_INITIALIZERS(object) object##_handle_(nullptr), Thread::Thread(bool is_vm_isolate) : ThreadState(false), stack_limit_(0), write_barrier_mask_(UntaggedObject::kGenerationalBarrierMask), heap_base_(0), - isolate_(NULL), - dispatch_table_array_(NULL), + isolate_(nullptr), + dispatch_table_array_(nullptr), saved_stack_limit_(0), stack_overflow_flags_(0), - heap_(NULL), + heap_(nullptr), top_exit_frame_info_(0), - store_buffer_block_(NULL), - marking_stack_block_(NULL), + store_buffer_block_(nullptr), + marking_stack_block_(nullptr), vm_tag_(0), unboxed_int64_runtime_arg_(0), unboxed_double_runtime_arg_(0.0), @@ -86,32 +87,37 @@ Thread::Thread(bool is_vm_isolate) safepoint_state_(0), ffi_callback_code_(GrowableObjectArray::null()), ffi_callback_stack_return_(TypedData::null()), - api_top_scope_(NULL), + api_top_scope_(nullptr), double_truncate_round_supported_( TargetCPUFeatures::double_truncate_round_supported() ? 1 : 0), tsan_utils_(DO_IF_TSAN(new TsanUtils()) DO_IF_NOT_TSAN(nullptr)), task_kind_(kUnknownTask), - dart_stream_(NULL), + dart_stream_(nullptr), + service_extension_stream_(nullptr), thread_lock_(), - api_reusable_scope_(NULL), + api_reusable_scope_(nullptr), no_callback_scope_depth_(0), #if defined(DEBUG) no_safepoint_scope_depth_(0), #endif reusable_handles_(), stack_overflow_count_(0), - hierarchy_info_(NULL), - type_usage_info_(NULL), + hierarchy_info_(nullptr), + type_usage_info_(nullptr), sticky_error_(Error::null()), REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS) REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT) #if defined(USING_SAFE_STACK) saved_safestack_limit_(0), #endif - next_(NULL) { + next_(nullptr) { #if defined(SUPPORT_TIMELINE) dart_stream_ = Timeline::GetDartStream(); - ASSERT(dart_stream_ != NULL); + ASSERT(dart_stream_ != nullptr); +#endif +#ifndef PRODUCT + service_extension_stream_ = &Service::extension_stream; + ASSERT(service_extension_stream_ != nullptr); #endif #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value) \ member_name = default_init_value; @@ -276,8 +282,8 @@ bool Thread::EnterIsolate(Isolate* isolate, bool is_nested_reenter) { Thread* thread = isolate->ScheduleThread(kIsMutatorThread, is_nested_reenter, kBypassSafepoint); - if (thread != NULL) { - ASSERT(thread->store_buffer_block_ == NULL); + if (thread != nullptr) { + ASSERT(thread->store_buffer_block_ == nullptr); ASSERT(thread->isolate() == isolate); ASSERT(thread->isolate_group() == isolate->group()); thread->FinishEntering(kMutatorTask); @@ -316,7 +322,7 @@ bool Thread::EnterIsolateAsHelper(Isolate* isolate, const bool kIsNestedReenter = false; Thread* thread = isolate->ScheduleThread(kIsMutatorThread, kIsNestedReenter, bypass_safepoint); - if (thread != NULL) { + if (thread != nullptr) { ASSERT(!thread->IsMutatorThread()); ASSERT(thread->isolate() == isolate); ASSERT(thread->isolate_group() == isolate->group()); @@ -336,7 +342,7 @@ void Thread::ExitIsolateAsHelper(bool bypass_safepoint) { thread->PrepareLeaving(); Isolate* isolate = thread->isolate(); - ASSERT(isolate != NULL); + ASSERT(isolate != nullptr); const bool kIsMutatorThread = false; const bool kIsNestedExit = false; isolate->UnscheduleThread(thread, kIsMutatorThread, kIsNestedExit, @@ -348,7 +354,7 @@ bool Thread::EnterIsolateGroupAsHelper(IsolateGroup* isolate_group, bool bypass_safepoint) { ASSERT(kind != kMutatorTask); Thread* thread = isolate_group->ScheduleThread(bypass_safepoint); - if (thread != NULL) { + if (thread != nullptr) { ASSERT(!thread->IsMutatorThread()); ASSERT(thread->isolate() == nullptr); ASSERT(thread->isolate_group() == isolate_group); @@ -375,7 +381,7 @@ void Thread::ExitIsolateGroupAsHelper(bool bypass_safepoint) { void Thread::ReleaseStoreBuffer() { ASSERT(IsAtSafepoint()); // Prevent scheduling another GC by ignoring the threshold. - ASSERT(store_buffer_block_ != NULL); + ASSERT(store_buffer_block_ != nullptr); StoreBufferRelease(StoreBuffer::kIgnoreThreshold); // Make sure to get an *empty* block; the isolate needs all entries // at GC time. @@ -502,7 +508,7 @@ void Thread::StoreBufferAddObjectGC(ObjectPtr obj) { void Thread::StoreBufferRelease(StoreBuffer::ThresholdPolicy policy) { StoreBufferBlock* block = store_buffer_block_; - store_buffer_block_ = NULL; + store_buffer_block_ = nullptr; isolate_group()->store_buffer()->PushBlock(block, policy); } @@ -536,7 +542,7 @@ void Thread::DeferredMarkingStackAddObject(ObjectPtr obj) { void Thread::MarkingStackRelease() { MarkingStackBlock* block = marking_stack_block_; - marking_stack_block_ = NULL; + marking_stack_block_ = nullptr; write_barrier_mask_ = UntaggedObject::kGenerationalBarrierMask; isolate_group()->marking_stack()->PushBlock(block); } @@ -549,7 +555,7 @@ void Thread::MarkingStackAcquire() { void Thread::DeferredMarkingStackRelease() { MarkingStackBlock* block = deferred_marking_stack_block_; - deferred_marking_stack_block_ = NULL; + deferred_marking_stack_block_ = nullptr; isolate_group()->deferred_marking_stack()->PushBlock(block); } @@ -591,9 +597,9 @@ void Thread::ClearReusableHandles() { void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor, ValidationPolicy validation_policy) { - ASSERT(visitor != NULL); + ASSERT(visitor != nullptr); - if (zone() != NULL) { + if (zone() != nullptr) { zone()->VisitObjectPointers(visitor); } @@ -610,7 +616,7 @@ void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor, // Visit the api local scope as it has all the api local handles. ApiLocalScope* scope = api_top_scope_; - while (scope != NULL) { + while (scope != nullptr) { scope->local_handles()->VisitObjectPointers(visitor); scope = scope->previous(); } @@ -634,7 +640,7 @@ void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor, StackFrameIterator frames_iterator(top_exit_frame_info(), validation_policy, this, cross_thread_policy); StackFrame* frame = frames_iterator.NextFrame(); - while (frame != NULL) { + while (frame != nullptr) { frame->VisitObjectPointers(visitor); frame = frames_iterator.NextFrame(); } @@ -735,7 +741,7 @@ void Thread::RestoreWriteBarrierInvariant(RestoreWriteBarrierInvariantOp op) { RestoreWriteBarrierInvariantVisitor visitor(isolate_group(), this, op); ObjectStore* object_store = isolate_group()->object_store(); bool scan_next_dart_frame = false; - for (StackFrame* frame = frames_iterator.NextFrame(); frame != NULL; + for (StackFrame* frame = frames_iterator.NextFrame(); frame != nullptr; frame = frames_iterator.NextFrame()) { if (frame->IsExitFrame()) { scan_next_dart_frame = true; @@ -891,7 +897,7 @@ bool Thread::IsValidHandle(Dart_Handle object) const { bool Thread::IsValidLocalHandle(Dart_Handle object) const { ApiLocalScope* scope = api_top_scope_; - while (scope != NULL) { + while (scope != nullptr) { if (scope->local_handles()->IsValidHandle(object)) { return true; } @@ -903,7 +909,7 @@ bool Thread::IsValidLocalHandle(Dart_Handle object) const { intptr_t Thread::CountLocalHandles() const { intptr_t total = 0; ApiLocalScope* scope = api_top_scope_; - while (scope != NULL) { + while (scope != nullptr) { total += scope->local_handles()->CountHandles(); scope = scope->previous(); } @@ -913,7 +919,7 @@ intptr_t Thread::CountLocalHandles() const { int Thread::ZoneSizeInBytes() const { int total = 0; ApiLocalScope* scope = api_top_scope_; - while (scope != NULL) { + while (scope != nullptr) { total += scope->zone()->SizeInBytes(); scope = scope->previous(); } @@ -923,12 +929,12 @@ int Thread::ZoneSizeInBytes() const { void Thread::EnterApiScope() { ASSERT(MayAllocateHandles()); ApiLocalScope* new_scope = api_reusable_scope(); - if (new_scope == NULL) { + if (new_scope == nullptr) { new_scope = new ApiLocalScope(api_top_scope(), top_exit_frame_info()); - ASSERT(new_scope != NULL); + ASSERT(new_scope != nullptr); } else { new_scope->Reinit(this, api_top_scope(), top_exit_frame_info()); - set_api_reusable_scope(NULL); + set_api_reusable_scope(nullptr); } set_api_top_scope(new_scope); // New scope is now the top scope. } @@ -938,7 +944,7 @@ void Thread::ExitApiScope() { ApiLocalScope* scope = api_top_scope(); ApiLocalScope* reusable_scope = api_reusable_scope(); set_api_top_scope(scope->previous()); // Reset top scope to previous. - if (reusable_scope == NULL) { + if (reusable_scope == nullptr) { scope->Reset(this); // Reset the old scope which we just exited. set_api_reusable_scope(scope); } else { @@ -951,7 +957,7 @@ void Thread::UnwindScopes(uword stack_marker) { // Unwind all scopes using the same stack_marker, i.e. all scopes allocated // under the same top_exit_frame_info. ApiLocalScope* scope = api_top_scope_; - while (scope != NULL && scope->stack_marker() != 0 && + while (scope != nullptr && scope->stack_marker() != 0 && scope->stack_marker() == stack_marker) { api_top_scope_ = scope->previous(); delete scope; @@ -975,7 +981,7 @@ void Thread::FinishEntering(TaskKind kind) { ASSERT(store_buffer_block_ == nullptr); task_kind_ = kind; - if (isolate_group()->marking_stack() != NULL) { + if (isolate_group()->marking_stack() != nullptr) { // Concurrent mark in progress. Enable barrier for this thread. MarkingStackAcquire(); DeferredMarkingStackAcquire(); @@ -1004,17 +1010,17 @@ void Thread::PrepareLeaving() { DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread) : StackResource(thread) { - if (thread != NULL) { + if (thread != nullptr) { OSThread* os_thread = thread->os_thread(); - ASSERT(os_thread != NULL); + ASSERT(os_thread != nullptr); os_thread->DisableThreadInterrupts(); } } DisableThreadInterruptsScope::~DisableThreadInterruptsScope() { - if (thread() != NULL) { + if (thread() != nullptr) { OSThread* os_thread = thread()->os_thread(); - ASSERT(os_thread != NULL); + ASSERT(os_thread != nullptr); os_thread->EnableThreadInterrupts(); } } diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h index 15a7bd926b7..5918a360afb 100644 --- a/runtime/vm/thread.h +++ b/runtime/vm/thread.h @@ -58,6 +58,7 @@ class RuntimeEntry; class Smi; class StackResource; class StackTrace; +class StreamInfo; class String; class TimelineStream; class TypeArguments; @@ -512,6 +513,11 @@ class Thread : public ThreadState { return OFFSET_OF(Thread, dart_stream_); } + // Offset of the Dart VM Service Extension StreamInfo object. + static intptr_t service_extension_stream_offset() { + return OFFSET_OF(Thread, service_extension_stream_); + } + // Is |this| executing Dart code? bool IsExecutingDartCode() const; @@ -1173,6 +1179,7 @@ class Thread : public ThreadState { TaskKind task_kind_; TimelineStream* dart_stream_; + StreamInfo* service_extension_stream_; IsolateGroup* isolate_group_ = nullptr; mutable Monitor thread_lock_; ApiLocalScope* api_reusable_scope_; diff --git a/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart b/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart index 761bf6e7eff..c451d7fc366 100644 --- a/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart +++ b/sdk/lib/_internal/js_dev_runtime/patch/developer_patch.dart @@ -11,7 +11,6 @@ import 'dart:async'; import 'dart:convert' show json; import 'dart:isolate'; -var _issuedPostEventWarning = false; var _issuedRegisterExtensionWarning = false; final _developerSupportWarning = 'from dart:developer is only supported in ' 'build/run/test environments where the developer event method hooks have ' @@ -116,16 +115,11 @@ _invokeExtension(String methodName, String encodedJson) { }); } +@patch +bool get extensionStreamHasListener => _debuggerAttached; + @patch void _postEvent(String eventKind, String eventData) { - if (!_debuggerAttached) { - if (!_issuedPostEventWarning) { - var message = 'postEvent() $_developerSupportWarning'; - JS('', 'console.warn(#)', message); - _issuedPostEventWarning = true; - } - return; - } // TODO(46377) Update this check when we have a documented API for DDC apps. if (JS('!', r'!!#.$emitDebugEvent', dart.global_)) { // See hooks assigned by package:dwds: diff --git a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart index feb0d485b37..54f7ca1b426 100644 --- a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart +++ b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart @@ -47,6 +47,9 @@ _registerExtension(String method, ServiceExtensionHandler handler) { _extensions[method] = handler; } +@patch +bool get extensionStreamHasListener => false; + @patch void _postEvent(String eventKind, String eventData) { // TODO. diff --git a/sdk/lib/_internal/wasm/lib/developer.dart b/sdk/lib/_internal/wasm/lib/developer.dart index ba930b33edc..32d3050e6f3 100644 --- a/sdk/lib/_internal/wasm/lib/developer.dart +++ b/sdk/lib/_internal/wasm/lib/developer.dart @@ -26,6 +26,9 @@ void log(String message, Object? error, StackTrace? stackTrace}) {} +@patch +bool get extensionStreamHasListener => false; + @patch void _postEvent(String eventKind, String eventData) {} diff --git a/sdk/lib/developer/developer.dart b/sdk/lib/developer/developer.dart index e9df841ba85..2d8e15cfcd3 100644 --- a/sdk/lib/developer/developer.dart +++ b/sdk/lib/developer/developer.dart @@ -15,6 +15,7 @@ /// {@category Core} library dart.developer; +import "dart:_internal" show checkNotNullable; import 'dart:async'; import 'dart:convert'; import 'dart:isolate' show Isolate, RawReceivePort, SendPort; diff --git a/sdk/lib/developer/extension.dart b/sdk/lib/developer/extension.dart index 184a00f956b..aa106744ced 100644 --- a/sdk/lib/developer/extension.dart +++ b/sdk/lib/developer/extension.dart @@ -27,7 +27,7 @@ class ServiceExtensionResponse { errorCode = null, errorDetail = null { // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(result, "result"); + checkNotNullable(result, "result"); } /// Creates an error response to a service protocol extension RPC. @@ -42,7 +42,7 @@ class ServiceExtensionResponse { errorDetail = errorDetail { _validateErrorCode(errorCode); // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(errorDetail, "errorDetail"); + checkNotNullable(errorDetail, "errorDetail"); } /// Invalid method parameter(s) error code. @@ -83,7 +83,7 @@ class ServiceExtensionResponse { static _validateErrorCode(int errorCode) { // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(errorCode, "errorCode"); + checkNotNullable(errorCode, "errorCode"); if (errorCode == invalidParams) return; if ((errorCode >= extensionErrorMin) && (errorCode <= extensionErrorMax)) { return; @@ -129,7 +129,7 @@ typedef Future ServiceExtensionHandler( /// must always include an 'isolateId' parameter with each RPC. void registerExtension(String method, ServiceExtensionHandler handler) { // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(method, 'method'); + checkNotNullable(method, 'method'); if (!method.startsWith('ext.')) { throw new ArgumentError.value(method, 'method', 'Must begin with ext.'); } @@ -137,16 +137,38 @@ void registerExtension(String method, ServiceExtensionHandler handler) { throw new ArgumentError('Extension already registered: $method'); } // TODO: When NNBD is complete, delete the following line. - ArgumentError.checkNotNull(handler, 'handler'); + checkNotNullable(handler, 'handler'); _registerExtension(method, handler); } -/// Post an event of [eventKind] with payload of [eventData] to the `Extension` +/// Whether the "Extension" stream currently has at least one listener. +/// +/// A client of the VM service can register as a listener +/// on the extension stream using `listenStream` method. +/// The extension stream has a listener while at least one such +/// client has registered as a listener, and has not yet disconnected +/// again. +/// +/// Calling [postEvent] while the stream has listeners will attempt to +/// deliver that event to all current listeners, +/// although a listener can disconnect before the event is delivered. +/// Calling [postEvent] when the stream has no listener means that +/// no-one will receive the event, and the call is effectively a no-op. +@pragma("vm:recognized", "other") +@pragma("vm:prefer-inline") +external bool get extensionStreamHasListener; + +/// Post an event of [eventKind] with payload of [eventData] to the "Extension" /// event stream. +/// +/// If [extensionStreamHasListener] is false, this method is a no-op. void postEvent(String eventKind, Map eventData) { + if (!extensionStreamHasListener) { + return; + } // TODO: When NNBD is complete, delete the following two lines. - ArgumentError.checkNotNull(eventKind, 'eventKind'); - ArgumentError.checkNotNull(eventData, 'eventData'); + checkNotNullable(eventKind, 'eventKind'); + checkNotNullable(eventData, 'eventData'); String eventDataAsString = json.encode(eventData); _postEvent(eventKind, eventDataAsString); } diff --git a/tests/dartdevc/developer_events_test.dart b/tests/dartdevc/developer_events_test.dart index 907d801f993..22481f8f92b 100644 --- a/tests/dartdevc/developer_events_test.dart +++ b/tests/dartdevc/developer_events_test.dart @@ -122,17 +122,15 @@ void testWarningMessages() { var data0 = {'key0': 'value0'}; postEvent('kind0', data0); - // A warning message was issued about calling `postEvent()` from - // dart:developer. - expect(consoleWarnLog.single.contains('postEvent() from dart:developer'), - true); + // Nothing is listening, so this was a no-op. + expect(consoleWarnLog.isEmpty, true); postEvent('kind0', data0); var data1 = {'key1': 'value1'}; postEvent('kind1', data1); - // A warning is only issued on the first call of `postEvent()`. - expect(consoleWarnLog.length, 1); + // No warnings should be issued because postEvent is a no-op. + expect(consoleWarnLog.length, 0); consoleWarnLog.clear(); diff --git a/tests/dartdevc_2/developer_events_test.dart b/tests/dartdevc_2/developer_events_test.dart index 8bc5ed877ba..d1851215d44 100644 --- a/tests/dartdevc_2/developer_events_test.dart +++ b/tests/dartdevc_2/developer_events_test.dart @@ -122,17 +122,15 @@ void testWarningMessages() { var data0 = {'key0': 'value0'}; postEvent('kind0', data0); - // A warning message was issued about calling `postEvent()` from - // dart:developer. - expect(consoleWarnLog.single.contains('postEvent() from dart:developer'), - true); + // Nothing is listening, so this was a no-op. + expect(consoleWarnLog.isEmpty, true); postEvent('kind0', data0); var data1 = {'key1': 'value1'}; postEvent('kind1', data1); - // A warning is only issued on the first call of `postEvent()`. - expect(consoleWarnLog.length, 1); + // No warnings should be issued because postEvent is a no-op. + expect(consoleWarnLog.length, 0); consoleWarnLog.clear();