sdk icon indicating copy to clipboard operation
sdk copied to clipboard

MethodRecognizer recognized wrong function as MethodRecognizer::kMathLog

Open akemimadoka opened this issue 1 year ago • 2 comments
trafficstars

Reproduce steps:

Save the code as test.dart:

import "dart:developer";

// Uncomment to get correct behavior

// import "dart:math" as math;

// @pragma("vm:entry-point")
// final l = math.log;

void main() {
  log("Hello");
}

Build a config with assert enabled: python3 tools/build.py --no-goma --mode debug --arch x64 create_sdk

Use it to compile test.dart to aot elf:

sdk/out/DebugX64/dart sdk/pkg/vm/bin/gen_kernel.dart --aot --tfa --platform sdk/out/DebugX64/dart-sdk/lib/_internal/vm_platform_strong.dill -o test.dill test.dart

sdk/out/DebugX64/gen_snapshot --print-flow-graph --snapshot_kind=app-aot-elf --elf=test_elf test.dill 2> test.il

gen_snapshot will fail with error:

../../runtime/vm/compiler/frontend/kernel_to_il.cc: 812: error: Recognized method ::._log@5383715 is not marked with the vm:recognized pragma.
version=3.4.0 (stable) (Mon May 6 07:59:58 2024 -0700) on "linux_x64"
pid=1778956, thread=1778956, isolate_group=isolate(0x5555563a18a0), isolate=(nil)((nil))
os=linux, arch=x64, comp=no, sim=no
isolate_instructions=0, vm_instructions=0
fp=7fffffffa1b0, sp=7fffffffa080, pc=555555c80b0c
  pc 0x0000555555c80b0c fp 0x00007fffffffa1b0 dart::Profiler::DumpStackTrace+0x7c
  pc 0x00005555559c8da4 fp 0x00007fffffffa290 dart::Assert::Fail+0x84
  pc 0x00005555561cea27 fp 0x00007fffffffa560 dart::kernel::FlowGraphBuilder::BuildGraph+0x2f7
  pc 0x000055555612e077 fp 0x00007fffffffaa80 dart::CallSiteInliner::TryInliningImpl+0xb27
  pc 0x0000555556124e28 fp 0x00007fffffffab10 dart::CallSiteInliner::TryInlining+0xe8
  pc 0x00005555561335ce fp 0x00007fffffffac00 dart::CallSiteInliner::InlineStaticCalls+0x59e
  pc 0x000055555612921f fp 0x00007fffffffad50 dart::CallSiteInliner::InlineCalls+0x31f
  pc 0x0000555556128d41 fp 0x00007fffffffae40 dart::FlowGraphInliner::Inline+0x1e1
  pc 0x000055555618f6c4 fp 0x00007fffffffaea0 dart::CompilerPass_Inlining::DoBody+0x44
  pc 0x000055555618ed46 fp 0x00007fffffffaf70 dart::CompilerPass::Run+0x126
  pc 0x000055555618f247 fp 0x00007fffffffaf90 dart::CompilerPass::RunPipeline+0x97
  pc 0x00005555560358ba fp 0x00007fffffffb6e0 dart::PrecompileParsedFunctionHelper::Compile+0x4aa
  pc 0x0000555556036697 fp 0x00007fffffffbfa0 dart::PrecompileFunctionHelper+0x387
  pc 0x0000555556030bdc fp 0x00007fffffffc0c0 dart::Precompiler::CompileFunction+0x1ac
  pc 0x000055555602f5ce fp 0x00007fffffffc160 dart::Precompiler::ProcessFunction+0x18e
  pc 0x0000555556029bb4 fp 0x00007fffffffc1b0 dart::Precompiler::Iterate+0x94
  pc 0x000055555602645e fp 0x00007fffffffcb30 dart::Precompiler::DoCompileAll+0x189e
  pc 0x0000555556024b16 fp 0x00007fffffffcfc0 dart::Precompiler::CompileAll+0xb6
  pc 0x000055555626bf88 fp 0x00007fffffffd190 Dart_Precompile+0x1b8
  pc 0x000055555599b431 fp 0x00007fffffffd300 dart::bin::main+0x8d1
-- End of DumpStackTrace
=== Crash occurred when compiling dart:developer_::_log in AOT mode in unknown pass
=== Flow Graph not available

If use config which does not enable assert:

python3 tools/build.py --no-goma --mode product --arch x64 create_sdk

sdk/out/ProductX64/dart sdk/pkg/vm/bin/gen_kernel.dart --aot --tfa --platform sdk/out/ProductX64/dart-sdk/lib/_internal/vm_platform_strong.dill -o test.dill test.dart

sdk/out/ProductX64/gen_snapshot --print-flow-graph --snapshot_kind=app-aot-elf --elf=test_elf test.dill 2> test.il

The function log of dart:developer in test.il is:

*** BEGIN CFG
After AllocateRegisters
==== dart:developer_::_log (RegularFunction)
  0: B0[graph]:0 {
      v0 <- Constant(#null) T{Null?}
      v9 <- Constant(#4) [4, 4] T{_Smi}
      v12 <- Constant(#sequenceNumber) T{_OneByteString}
      v94 <- UnboxedConstant(#1) [1, 1] int64
}
  2: B1[function entry]:2 {
      v2 <- Parameter(2 @r10) T{*?}
}
  4:     v11 <- LoadIndexed([_List] v2, v9 T{_Smi}) T{*?}
  6:     Branch if StrictCompare:16(===, v11, v12) goto (2, 3)
  8: B2[target]:20
 10:     ParallelMove  goto:26 B8
 12: B3[target]:22
 14:     ParallelMove  goto:28 B8
 16: B8[join]:24 pred(B2, B3) {
}
 18:     CheckStackOverflow:58(stack=0, loop=0)
 20:     v69 <- StaticCall:10( _getCurrentMicros@0150898<0> , result_type = T{int}) [-9223372036854775808, 9223372036854775807] T{int}
 22:     v19 <- LoadStaticField(_nextSequenceNumber@5383715) [-9223372036854775808, 9223372036854775807] T{int}
 24:     v91 <- UnboxInt64([non-speculative], v19) [-9223372036854775808, 9223372036854775807] int64
 26:     v21 <- BinaryInt64Op(+ [tr], v91 T{int}, v94 T{_Smi}) [-9223372036854775808, 9223372036854775807] int64
 28:     v92 <- BoxInt64(v21) [-9223372036854775808, 9223372036854775807] T{int}
 30:     StoreStaticField(_nextSequenceNumber@5383715, v92 T{int})
 31:     ParallelMove rax <- C
 32:     DartReturn:70(v0)
*** END CFG

The _log invocation in this function was recognized as MethodRecognizer::kMathLog, and got optimized out

If uncomment the lines in test.dart, everything works fine:

*** BEGIN CFG
After AllocateRegisters
==== dart:developer_::_log (RegularFunction)
  0: B0[graph]:0 {
      v0 <- Constant(#null) T{Null?}
      v5 <- Constant(#0) [0, 0] T{_Smi}
      v9 <- Constant(#4) [4, 4] T{_Smi}
      v12 <- Constant(#sequenceNumber) T{_OneByteString}
      v22 <- Constant(#Hello) T{_OneByteString}
      v24 <- Constant(#) T{_OneByteString}
      v71 <- UnboxedConstant(#1) [1, 1] int64
      v73 <- UnboxedConstant(#1000) [1000, 1000] int64
}
  2: B1[function entry]:2 {
      v2 <- Parameter(2 @r10) T{*?}
}
  4:     v11 <- LoadIndexed([_List] v2, v9 T{_Smi}) T{*?}
  6:     Branch if StrictCompare:16(===, v11, v12) goto (2, 3)
  8: B2[target]:20
 10:     ParallelMove  goto:26 B8
 12: B3[target]:22
 14:     ParallelMove  goto:28 B8
 16: B8[join]:24 pred(B2, B3) {
}
 18:     CheckStackOverflow:58(stack=0, loop=0)
 20:     v53 <- StaticCall:10( _getCurrentMicros@0150898<0> , result_type = T{int}) [-9223372036854775808, 9223372036854775807] T{int}
 22:     ParallelMove rcx <- rax
 22:     v67 <- UnboxInt64([non-speculative], v53) [-9223372036854775808, 9223372036854775807] int64
 24:     v19 <- LoadStaticField(_nextSequenceNumber@5383715) [-9223372036854775808, 9223372036854775807] T{int}
 26:     ParallelMove rax <- rsi
 26:     v68 <- UnboxInt64([non-speculative], v19) [-9223372036854775808, 9223372036854775807] int64
 28:     ParallelMove rdx <- rax
 28:     v21 <- BinaryInt64Op(+ [tr], v68 T{int}, v71 T{_Smi}) [-9223372036854775808, 9223372036854775807] int64
 30:     v69 <- BoxInt64(v21) [-9223372036854775808, 9223372036854775807] T{int}
 32:     StoreStaticField(_nextSequenceNumber@5383715, v69 T{int})
 33:     ParallelMove rax <- rcx, rcx <- C
 34:     v46 <- BinaryInt64Op(~/ [tr], v67 T{int}, v73 T{_Smi}) [-9223372036854775808, 9223372036854775807] int64
 35:     ParallelMove rcx <- rax
 36:     v70 <- BoxInt64(v46 T{int}) [-9223372036854775808, 9223372036854775807] T{int}
 38:     MoveArgument(sp[7] <- v22)
 40:     MoveArgument(sp[6] <- v70 T{int})
 42:     MoveArgument(sp[5] <- v19)
 44:     MoveArgument(sp[4] <- v5)
 46:     MoveArgument(sp[3] <- v24)
 48:     MoveArgument(sp[2] <- v0)
 50:     MoveArgument(sp[1] <- v0)
 52:     MoveArgument(sp[0] <- v0)
 54:     StaticCall:68( _log@5383715<0> v22, v70 T{int}, v19, v5, v24, v0, v0, v0)
 55:     ParallelMove rax <- C
 56:     DartReturn:70(v0)
*** END CFG

The _log invocation returns back now

akemimadoka avatar Jun 14 '24 07:06 akemimadoka

area-vm, type-bug

The MethodRecognizer incorrectly identifies the log function from dart:developer as kMathLog when compiling with asserts enabled. This leads to an error during AOT compilation because the log function is not marked with the vm:recognized pragma.

dart-github-bot avatar Jun 14 '24 07:06 dart-github-bot

//cc @alexmarkov

a-siva avatar Jun 14 '24 17:06 a-siva