diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc index 888d3970aca..314c0b27915 100644 --- a/runtime/vm/compiler/assembler/assembler_arm.cc +++ b/runtime/vm/compiler/assembler/assembler_arm.cc @@ -671,7 +671,8 @@ void Assembler::ExitFullSafepoint(Register tmp1, void Assembler::TransitionNativeToGenerated(Register addr, Register state, bool exit_safepoint, - bool ignore_unwind_in_progress) { + bool ignore_unwind_in_progress, + bool set_tag) { if (exit_safepoint) { ExitFullSafepoint(addr, state, ignore_unwind_in_progress); } else { @@ -691,8 +692,10 @@ void Assembler::TransitionNativeToGenerated(Register addr, } // Mark that the thread is executing Dart code. - LoadImmediate(state, target::Thread::vm_tag_dart_id()); - StoreToOffset(state, THR, target::Thread::vm_tag_offset()); + if (set_tag) { + LoadImmediate(state, target::Thread::vm_tag_dart_id()); + StoreToOffset(state, THR, target::Thread::vm_tag_offset()); + } LoadImmediate(state, target::Thread::generated_execution_state()); StoreToOffset(state, THR, target::Thread::execution_state_offset()); diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h index b5c8ab54177..4ea9f488c28 100644 --- a/runtime/vm/compiler/assembler/assembler_arm.h +++ b/runtime/vm/compiler/assembler/assembler_arm.h @@ -622,7 +622,8 @@ class Assembler : public AssemblerBase { void TransitionNativeToGenerated(Register scratch0, Register scratch1, bool exit_safepoint, - bool ignore_unwind_in_progress = false); + bool ignore_unwind_in_progress = false, + bool set_tag = true); void EnterFullSafepoint(Register scratch0, Register scratch1); void ExitFullSafepoint(Register scratch0, Register scratch1, diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc index a3adb29960d..6f54771fe11 100644 --- a/runtime/vm/compiler/assembler/assembler_arm64.cc +++ b/runtime/vm/compiler/assembler/assembler_arm64.cc @@ -1635,7 +1635,8 @@ void Assembler::ExitFullSafepoint(Register state, void Assembler::TransitionNativeToGenerated(Register state, bool exit_safepoint, - bool ignore_unwind_in_progress) { + bool ignore_unwind_in_progress, + bool set_tag) { if (exit_safepoint) { ExitFullSafepoint(state, ignore_unwind_in_progress); } else { @@ -1655,8 +1656,10 @@ void Assembler::TransitionNativeToGenerated(Register state, } // Mark that the thread is executing Dart code. - LoadImmediate(state, target::Thread::vm_tag_dart_id()); - StoreToOffset(state, THR, target::Thread::vm_tag_offset()); + if (set_tag) { + LoadImmediate(state, target::Thread::vm_tag_dart_id()); + StoreToOffset(state, THR, target::Thread::vm_tag_offset()); + } LoadImmediate(state, target::Thread::generated_execution_state()); StoreToOffset(state, THR, target::Thread::execution_state_offset()); diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h index f73fbf0501f..73d1d54fe84 100644 --- a/runtime/vm/compiler/assembler/assembler_arm64.h +++ b/runtime/vm/compiler/assembler/assembler_arm64.h @@ -2077,7 +2077,8 @@ class Assembler : public AssemblerBase { bool enter_safepoint); void TransitionNativeToGenerated(Register scratch, bool exit_safepoint, - bool ignore_unwind_in_progress = false); + bool ignore_unwind_in_progress = false, + bool set_tag = true); void EnterFullSafepoint(Register scratch); void ExitFullSafepoint(Register scratch, bool ignore_unwind_in_progress); diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc index 90c51772665..1cf2130a43a 100644 --- a/runtime/vm/compiler/assembler/assembler_ia32.cc +++ b/runtime/vm/compiler/assembler/assembler_ia32.cc @@ -2565,7 +2565,8 @@ void Assembler::ExitFullSafepoint(Register scratch, void Assembler::TransitionNativeToGenerated(Register scratch, bool exit_safepoint, - bool ignore_unwind_in_progress) { + bool ignore_unwind_in_progress, + bool set_tag) { if (exit_safepoint) { ExitFullSafepoint(scratch, ignore_unwind_in_progress); } else { @@ -2583,7 +2584,10 @@ void Assembler::TransitionNativeToGenerated(Register scratch, } // Mark that the thread is executing Dart code. - movl(Assembler::VMTagAddress(), Immediate(target::Thread::vm_tag_dart_id())); + if (set_tag) { + movl(Assembler::VMTagAddress(), + Immediate(target::Thread::vm_tag_dart_id())); + } movl(Address(THR, target::Thread::execution_state_offset()), Immediate(target::Thread::generated_execution_state())); diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h index fa072255b37..ec36767d1ed 100644 --- a/runtime/vm/compiler/assembler/assembler_ia32.h +++ b/runtime/vm/compiler/assembler/assembler_ia32.h @@ -875,7 +875,8 @@ class Assembler : public AssemblerBase { bool enter_safepoint); void TransitionNativeToGenerated(Register scratch, bool exit_safepoint, - bool ignore_unwind_in_progress = false); + bool ignore_unwind_in_progress = false, + bool set_tag = true); void EnterFullSafepoint(Register scratch); void ExitFullSafepoint(Register scratch, bool ignore_unwind_in_progress); diff --git a/runtime/vm/compiler/assembler/assembler_riscv.cc b/runtime/vm/compiler/assembler/assembler_riscv.cc index 6b8eb2eaf11..64fd589a014 100644 --- a/runtime/vm/compiler/assembler/assembler_riscv.cc +++ b/runtime/vm/compiler/assembler/assembler_riscv.cc @@ -3854,7 +3854,8 @@ void Assembler::TransitionGeneratedToNative(Register destination, void Assembler::TransitionNativeToGenerated(Register state, bool exit_safepoint, - bool ignore_unwind_in_progress) { + bool ignore_unwind_in_progress, + bool set_tag) { if (exit_safepoint) { ExitFullSafepoint(state, ignore_unwind_in_progress); } else { @@ -3874,8 +3875,10 @@ void Assembler::TransitionNativeToGenerated(Register state, } // Mark that the thread is executing Dart code. - li(state, target::Thread::vm_tag_dart_id()); - sx(state, Address(THR, target::Thread::vm_tag_offset())); + if (set_tag) { + li(state, target::Thread::vm_tag_dart_id()); + sx(state, Address(THR, target::Thread::vm_tag_offset())); + } li(state, target::Thread::generated_execution_state()); sx(state, Address(THR, target::Thread::execution_state_offset())); diff --git a/runtime/vm/compiler/assembler/assembler_riscv.h b/runtime/vm/compiler/assembler/assembler_riscv.h index 9abfcc2c78b..622a2cde8c5 100644 --- a/runtime/vm/compiler/assembler/assembler_riscv.h +++ b/runtime/vm/compiler/assembler/assembler_riscv.h @@ -1295,7 +1295,8 @@ class Assembler : public MicroAssembler { bool enter_safepoint); void TransitionNativeToGenerated(Register scratch, bool exit_safepoint, - bool ignore_unwind_in_progress = false); + bool ignore_unwind_in_progress = false, + bool set_tag = true); void EnterFullSafepoint(Register scratch); void ExitFullSafepoint(Register scratch, bool ignore_unwind_in_progress); diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc index f0298b8096c..8def110d8d4 100644 --- a/runtime/vm/compiler/assembler/assembler_x64.cc +++ b/runtime/vm/compiler/assembler/assembler_x64.cc @@ -245,7 +245,8 @@ void Assembler::ExitFullSafepoint(bool ignore_unwind_in_progress) { } void Assembler::TransitionNativeToGenerated(bool leave_safepoint, - bool ignore_unwind_in_progress) { + bool ignore_unwind_in_progress, + bool set_tag) { if (leave_safepoint) { ExitFullSafepoint(ignore_unwind_in_progress); } else { @@ -262,7 +263,10 @@ void Assembler::TransitionNativeToGenerated(bool leave_safepoint, #endif } - movq(Assembler::VMTagAddress(), Immediate(target::Thread::vm_tag_dart_id())); + if (set_tag) { + movq(Assembler::VMTagAddress(), + Immediate(target::Thread::vm_tag_dart_id())); + } movq(Address(THR, target::Thread::execution_state_offset()), Immediate(target::Thread::generated_execution_state())); diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h index 1a19eb2986b..9d27699633b 100644 --- a/runtime/vm/compiler/assembler/assembler_x64.h +++ b/runtime/vm/compiler/assembler/assembler_x64.h @@ -325,7 +325,8 @@ class Assembler : public AssemblerBase { Register new_exit_through_ffi, bool enter_safepoint); void TransitionNativeToGenerated(bool leave_safepoint, - bool ignore_unwind_in_progress = false); + bool ignore_unwind_in_progress = false, + bool set_tag = true); // Register-register, register-address and address-register instructions. #define RR(width, name, ...) \ diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h index 0f781361d7a..2cfd859e394 100644 --- a/runtime/vm/compiler/backend/il.h +++ b/runtime/vm/compiler/backend/il.h @@ -2217,6 +2217,9 @@ class FunctionEntryInstr : public BlockEntryWithInitialDefs { // NativeParameter instead (which doesn't count as an initial definition). class NativeEntryInstr : public FunctionEntryInstr { public: + static constexpr intptr_t kVMTagOffsetFromFp = + 5 * compiler::target::kWordSize; + NativeEntryInstr(const compiler::ffi::CallbackMarshaller& marshaller, GraphEntryInstr* graph_entry, intptr_t block_id, diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc index f612746fb37..a94fdf5b781 100644 --- a/runtime/vm/compiler/backend/il_arm.cc +++ b/runtime/vm/compiler/backend/il_arm.cc @@ -1902,6 +1902,11 @@ void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { void NativeReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { EmitReturnMoves(compiler); + // Restore tag before the profiler's stack walker will no longer see the + // InvokeDartCode return address. + __ LoadFromOffset(TMP, FP, NativeEntryInstr::kVMTagOffsetFromFp); + __ StoreToOffset(TMP, THR, compiler::target::Thread::vm_tag_offset()); + __ LeaveDartFrame(); // The dummy return address is in LR, no need to pop it as on Intel. @@ -1975,6 +1980,7 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { // Save the current VMTag on the stack. __ LoadFromOffset(R0, THR, compiler::target::Thread::vm_tag_offset()); __ Push(R0); + ASSERT(kVMTagOffsetFromFp == 5 * compiler::target::kWordSize); // Save top resource. const intptr_t top_resource_offset = @@ -1998,7 +2004,9 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { // The callback trampoline (caller) has already left the safepoint for us. __ TransitionNativeToGenerated(/*scratch0=*/R0, /*scratch1=*/R1, - /*exit_safepoint=*/false); + /*exit_safepoint=*/false, + /*ignore_unwind_in_progress=*/false, + /*set_tag=*/false); // Now that the safepoint has ended, we can touch Dart objects without // handles. @@ -2039,6 +2047,11 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { }); FunctionEntryInstr::EmitNativeCode(compiler); + + // Delay setting the tag until the profiler's stack walker will see the + // InvokeDartCode return address. + __ LoadImmediate(TMP, compiler::target::Thread::vm_tag_dart_id()); + __ StoreToOffset(TMP, THR, compiler::target::Thread::vm_tag_offset()); } #define R(r) (1 << r) diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc index a956ba45399..f156685b1ef 100644 --- a/runtime/vm/compiler/backend/il_arm64.cc +++ b/runtime/vm/compiler/backend/il_arm64.cc @@ -1706,6 +1706,11 @@ void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { void NativeReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { EmitReturnMoves(compiler); + // Restore tag before the profiler's stack walker will no longer see the + // InvokeDartCode return address. + __ LoadFromOffset(TMP, FP, NativeEntryInstr::kVMTagOffsetFromFp); + __ StoreToOffset(TMP, THR, compiler::target::Thread::vm_tag_offset()); + __ LeaveDartFrame(); // The dummy return address is in LR, no need to pop it as on Intel. @@ -1794,6 +1799,7 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { // Save the top resource. __ LoadFromOffset(R0, THR, compiler::target::Thread::top_resource_offset()); __ PushPair(R0, TMP); + ASSERT(kVMTagOffsetFromFp == 5 * compiler::target::kWordSize); __ StoreToOffset(ZR, THR, compiler::target::Thread::top_resource_offset()); @@ -1812,7 +1818,9 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { __ EmitEntryFrameVerification(); // The callback trampoline (caller) has already left the safepoint for us. - __ TransitionNativeToGenerated(R0, /*exit_safepoint=*/false); + __ TransitionNativeToGenerated(R0, /*exit_safepoint=*/false, + /*ignore_unwind_in_progress=*/false, + /*set_tag=*/false); // Now that the safepoint has ended, we can touch Dart objects without // handles. @@ -1857,6 +1865,11 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { }); FunctionEntryInstr::EmitNativeCode(compiler); + + // Delay setting the tag until the profiler's stack walker will see the + // InvokeDartCode return address. + __ LoadImmediate(TMP, compiler::target::Thread::vm_tag_dart_id()); + __ StoreToOffset(TMP, THR, compiler::target::Thread::vm_tag_offset()); } #define R(r) (1 << r) diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc index 932c6f1598d..d7112cf38b5 100644 --- a/runtime/vm/compiler/backend/il_ia32.cc +++ b/runtime/vm/compiler/backend/il_ia32.cc @@ -407,8 +407,6 @@ void NativeReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { return_in_st0 = true; } - __ LeaveDartFrame(); - // EDI is the only sane choice for a temporary register here because: // // EDX is used for large return values. @@ -416,6 +414,13 @@ void NativeReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { // Could be EBX or ECX, but that would make code below confusing. const Register tmp = EDI; + // Restore tag before the profiler's stack walker will no longer see the + // InvokeDartCode return address. + __ movl(tmp, compiler::Address(EBP, NativeEntryInstr::kVMTagOffsetFromFp)); + __ movl(compiler::Assembler::VMTagAddress(), tmp); + + __ LeaveDartFrame(); + // Pop dummy return address. __ popl(tmp); @@ -1400,6 +1405,7 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { // Save the current VMTag on the stack. __ movl(ECX, compiler::Assembler::VMTagAddress()); __ pushl(ECX); + ASSERT(kVMTagOffsetFromFp == 5 * compiler::target::kWordSize); // Save top resource. __ pushl( @@ -1420,7 +1426,9 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { __ EmitEntryFrameVerification(); // The callback trampoline (caller) has already left the safepoint for us. - __ TransitionNativeToGenerated(EAX, /*exit_safepoint=*/false); + __ TransitionNativeToGenerated(EAX, /*exit_safepoint=*/false, + /*ignore_unwind_in_progress=*/false, + /*set_tag=*/false); // Now that the safepoint has ended, we can hold Dart objects with bare hands. @@ -1458,6 +1466,11 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { // Continue with Dart frame setup. FunctionEntryInstr::EmitNativeCode(compiler); + + // Delay setting the tag until the profiler's stack walker will see the + // InvokeDartCode return address. + __ movl(compiler::Assembler::VMTagAddress(), + compiler::Immediate(compiler::target::Thread::vm_tag_dart_id())); } #define R(r) (1 << r) diff --git a/runtime/vm/compiler/backend/il_riscv.cc b/runtime/vm/compiler/backend/il_riscv.cc index e393384f484..31f684363d8 100644 --- a/runtime/vm/compiler/backend/il_riscv.cc +++ b/runtime/vm/compiler/backend/il_riscv.cc @@ -1806,6 +1806,11 @@ void FfiCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { void NativeReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { EmitReturnMoves(compiler); + // Restore tag before the profiler's stack walker will no longer see the + // InvokeDartCode return address. + __ LoadFromOffset(TMP, FP, NativeEntryInstr::kVMTagOffsetFromFp); + __ StoreToOffset(TMP, THR, compiler::target::Thread::vm_tag_offset()); + __ LeaveDartFrame(); // The dummy return address is in RA, no need to pop it as on Intel. @@ -1881,6 +1886,7 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { // Save the top resource. __ LoadFromOffset(A0, THR, compiler::target::Thread::top_resource_offset()); __ PushRegisterPair(A0, TMP); + ASSERT(kVMTagOffsetFromFp == 5 * compiler::target::kWordSize); __ StoreToOffset(ZR, THR, compiler::target::Thread::top_resource_offset()); @@ -1899,7 +1905,9 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { __ EmitEntryFrameVerification(); // The callback trampoline (caller) has already left the safepoint for us. - __ TransitionNativeToGenerated(A0, /*exit_safepoint=*/false); + __ TransitionNativeToGenerated(A0, /*exit_safepoint=*/false, + /*ignore_unwind_in_progress=*/false, + /*set_tag=*/false); // Now that the safepoint has ended, we can touch Dart objects without // handles. @@ -1941,6 +1949,11 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { __ LoadFieldFromOffset(RA, RA, compiler::target::Code::entry_point_offset()); FunctionEntryInstr::EmitNativeCode(compiler); + + // Delay setting the tag until the profiler's stack walker will see the + // InvokeDartCode return address. + __ LoadImmediate(TMP, compiler::target::Thread::vm_tag_dart_id()); + __ StoreToOffset(TMP, THR, compiler::target::Thread::vm_tag_offset()); } #define R(r) (1 << r) diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc index 078b8d07876..cdbddaece4a 100644 --- a/runtime/vm/compiler/backend/il_x64.cc +++ b/runtime/vm/compiler/backend/il_x64.cc @@ -546,6 +546,11 @@ static const RegisterSet kCalleeSaveRegistersSet( void NativeReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { EmitReturnMoves(compiler); + // Restore tag before the profiler's stack walker will no longer see the + // InvokeDartCode return address. + __ movq(TMP, compiler::Address(RBP, NativeEntryInstr::kVMTagOffsetFromFp)); + __ movq(compiler::Assembler::VMTagAddress(), TMP); + __ LeaveDartFrame(); // Pop dummy return address. @@ -1627,6 +1632,7 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { // Save the current VMTag on the stack. __ movq(RAX, compiler::Assembler::VMTagAddress()); __ pushq(RAX); + ASSERT(kVMTagOffsetFromFp == 5 * compiler::target::kWordSize); // Save top resource. __ pushq( @@ -1647,7 +1653,9 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { __ EmitEntryFrameVerification(); // The callback trampoline (caller) has already left the safepoint for us. - __ TransitionNativeToGenerated(/*exit_safepoint=*/false); + __ TransitionNativeToGenerated(/*exit_safepoint=*/false, + /*ignore_unwind_in_progress=*/false, + /*set_tag=*/false); // Load the code object. const Function& target_function = marshaller_.dart_signature(); @@ -1694,6 +1702,11 @@ void NativeEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) { // Continue with Dart frame setup. FunctionEntryInstr::EmitNativeCode(compiler); + + // Delay setting the tag until the profiler's stack walker will see the + // InvokeDartCode return address. + __ movq(compiler::Assembler::VMTagAddress(), + compiler::Immediate(compiler::target::Thread::vm_tag_dart_id())); } #define R(r) (1 << r) diff --git a/tests/ffi/async_void_function_callbacks_test.dart b/tests/ffi/async_void_function_callbacks_test.dart index 0ec9558668c..300a2253338 100644 --- a/tests/ffi/async_void_function_callbacks_test.dart +++ b/tests/ffi/async_void_function_callbacks_test.dart @@ -9,7 +9,8 @@ // VMOptions=--use-slow-path --stacktrace-every=100 // VMOptions=--dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects // VMOptions=--test_il_serialization -// VMOptions=--profiler +// VMOptions=--profiler --profile_vm=true +// VMOptions=--profiler --profile_vm=false // SharedObjects=ffi_test_functions import 'dart:async'; diff --git a/tests/ffi/function_callbacks_subtype_test.dart b/tests/ffi/function_callbacks_subtype_test.dart index b8120878ead..595a1175b28 100644 --- a/tests/ffi/function_callbacks_subtype_test.dart +++ b/tests/ffi/function_callbacks_subtype_test.dart @@ -11,7 +11,8 @@ // VMOptions=--use-slow-path --stacktrace-every=100 // VMOptions=--dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects // VMOptions=--test_il_serialization -// VMOptions=--profiler +// VMOptions=--profiler --profile_vm=true +// VMOptions=--profiler --profile_vm=false // SharedObjects=ffi_test_functions import 'dart:async'; diff --git a/tests/ffi/function_callbacks_test.dart b/tests/ffi/function_callbacks_test.dart index 4f7a070245f..e56646cfb3b 100644 --- a/tests/ffi/function_callbacks_test.dart +++ b/tests/ffi/function_callbacks_test.dart @@ -10,7 +10,8 @@ // VMOptions=--use-slow-path --stacktrace-every=100 // VMOptions=--dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects // VMOptions=--test_il_serialization -// VMOptions=--profiler +// VMOptions=--profiler --profile_vm=true +// VMOptions=--profiler --profile_vm=false // SharedObjects=ffi_test_functions import 'dart:ffi'; diff --git a/tests/ffi/isolate_local_function_callbacks_test.dart b/tests/ffi/isolate_local_function_callbacks_test.dart index 20e8ac847e4..c3fe1241626 100644 --- a/tests/ffi/isolate_local_function_callbacks_test.dart +++ b/tests/ffi/isolate_local_function_callbacks_test.dart @@ -10,7 +10,8 @@ // VMOptions=--use-slow-path --stacktrace-every=100 // VMOptions=--dwarf_stack_traces --no-retain_function_objects --no-retain_code_objects // VMOptions=--test_il_serialization -// VMOptions=--profiler +// VMOptions=--profiler --profile_vm=true +// VMOptions=--profiler --profile_vm=false // SharedObjects=ffi_test_functions import 'dart:async';