Repository navigation
Devtools benchmarks fail with dart2wasm on highest optimization level #56664
Copy link
Copy link
Closed
Labels
area-dart2wasmIssues for the dart2wasm compiler.Issues for the dart2wasm compiler.type-bugIncorrect behavior (everything from a crash to more subtle misbehavior)Incorrect behavior (everything from a crash to more subtle misbehavior)
Description
The devtools benchmarks run with the newest version of flutter causes dart2wasm to emit code that results in a typecasting failure, but only at the highest optimization levels.
Steps to Reproduce:
- Check out @kenzieschmoll 's branch here: Upgrade to latest flutter flutter/devtools#8306
- Change to the
packages/devtools_appdirectory - Run the following script:
dart ./benchmark/devtools_benchmarks_test.dart
Results:
Tests output the following exception:
Caught browser-side error: Type '(minified:Class2107) => minified:Class4570<void>' is not a subtype of type '(Object) => minified:Class4570<void>' in type cast
at _TypeError._throwAsCheckError (http://localhost:9999/main.dart.wasm:wasm-function[1117]:0x1aa4a2)
at _RouterState.restoreState closure at file:///home/runner/work/devtools/devtools/tool/flutter-sdk/packages/flutter/lib/src/widgets/router.dart:623:72 (http://localhost:9999/main.dart.wasm:wasm-function[33056]:0x4ade86)
at closure wrapper at file:///home/runner/work/devtools/devtools/tool/flutter-sdk/packages/flutter/lib/src/widgets/router.dart:623:72 trampoline (http://localhost:9999/main.dart.wasm:wasm-function[33060]:0x4adeb4)
at _RouterState._processParsedRouteInformation closure at file:///home/runner/work/devtools/devtools/tool/flutter-sdk/packages/flutter/lib/src/widgets/router.dart:759:12 inner (http://localhost:9999/main.dart.wasm:wasm-function[32757]:0x4a80cf)
at _RouterState._processParsedRouteInformation closure at file:///home/runner/work/devtools/devtools/tool/flutter-sdk/packages/flutter/lib/src/widgets/router.dart:759:12 (http://localhost:9999/main.dart.wasm:wasm-function[32754]:0x4a7fce)
at closure wrapper at file:///home/runner/work/devtools/devtools/tool/flutter-sdk/packages/flutter/lib/src/widgets/router.dart:759:12 trampoline (http://localhost:9999/main.dart.wasm:wasm-function[32756]:0x4a7ff8)
at _rootRunUnary (http://localhost:9999/main.dart.wasm:wasm-function[1550]:0x1bfa56)
at _CustomZone.runUnary (http://localhost:9999/main.dart.wasm:wasm-function[33328]:0x4b5988)
This only appears to occur at the full optimization level. Changing the web benchmarking code to compile at -O1, -O1 or -O2 does not emit this error. Unfortunately, it's difficult to tell what exactly is being cast due to the minified types.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area-dart2wasmIssues for the dart2wasm compiler.Issues for the dart2wasm compiler.type-bugIncorrect behavior (everything from a crash to more subtle misbehavior)Incorrect behavior (everything from a crash to more subtle misbehavior)
Activity
dart-github-bot commentedon Sep 6, 2024
Summary: Dart2wasm emits incorrect code when compiling Devtools benchmarks at the highest optimization level, causing a type casting error during runtime. The issue only occurs at
-O3and not at lower optimization levels.mkustermann commentedon Sep 9, 2024
I can confirm that this is happening iff
--omit-implicit-type-checksis enabled.The error being thrown looks like this:
The code looks like this:
The inner closure returns a function. That function is a tear-off of
RouterDelegate<T>.setInitialRoutePath.The
widget.routerDelegateis aDevToolsRouterDelegate:=> So at runtime this
widget.routerDelegate.setInitialRoutePathwill be(DevToolsRouteConfiguration) -> Future<void>So the closure we give to
_processRouteInformations 2nd argument is() -> ((DevToolsRouteConfiguration) -> Future<void>).That function looks like this:
=> We seemingly have
T == Object=> We expect
ValueGetter<_RouteSetter<T>>=> We expect
ValueGetter<_RouteSetter<Object>>=> We expect
ValueGetter<Future<void> Function(Object)>=> We expect
Future<void> Function(Object) Function()So we're trying to assign
() -> ((DevToolsRouteConfiguration) -> Future<void>where() -> ((Object) -> Future<void>)is expected.Not quite clear yet why this happens precisely iff
--omit-implicit-checksis enabled.mkustermann commentedon Sep 9, 2024
Turns out that because the tear-off is of a method with covariant parameters the parameter of the closure should be
Object. Though in--omit-implicit-checksit was ratherDevToolsRouteConfiguration.=> cl/384285
[dart2wasm] Fix bug in --omit-implicit-checks
kenzieschmoll commentedon Sep 11, 2024
I am still seeing this issue even with the attempted fix (which was first included in Dart 3.6.0-235.0.dev - see commit).
Repro steps:
devtools_tool serve --wasm --no-strip-wasmException:
mkustermann commentedon Sep 11, 2024
From my testing it seems very clear that this error occurs with
but no longer with
@kenzieschmoll Are you sure you're on the right flutter/flutter commits? Have you run
flutter clean & flutter packages getafterwords?kenzieschmoll commentedon Sep 11, 2024
When you run
devtools_tool serve --wasm --no-strip-wasm, do you see the error? I ranflutter cleanandflutter packages getand I still see the error when I build and serve DevTools with wasm.You no longer need to patch any code locally, just pull the latest from the Devtools master branch and run the serve command above. When Devtools loads in the browser, be sure to do a hard refresh (just clicking in the URL and hitting enter) to ensure that the browser is not caching an old version of DevTools.
mkustermann commentedon Sep 11, 2024
I still used the original instructions to reproduce (and cannot reproduce anymore after the rolled fix).
Will try with new instructions from #56664 (comment) and report back.
mkustermann commentedon Sep 11, 2024
So the instructions would be
If I follow these instructions it seems to only serve dart2js (i.e.
main.dart.js)kenzieschmoll commentedon Sep 11, 2024
Are you on the tip of flutter/devtools master and the tip of the Dart SDK? there was a commit to each that landed this morning that you would need.
kenzieschmoll commentedon Sep 11, 2024
One potential difference between running
devtools serve --wasm --no-strip-wasmand running the benchmark tests is that the former builds DevTools in release mode by default, and web_benchmarks builds Devtools in profile mode.mkustermann commentedon Sep 12, 2024
Yes.
After debugging the JS a bit it turns out the packages/devtools_app/web/flutter_bootstrap.js's
shouldUseSkwasm()returns falseThough I can manually serve via
and put
?wasm=truein thehttp://localhost:8080?wasm=trueURL. Then it uses themain.dart.wasmand it works just fine (e.g. cpu profiler).=> I see no sign in the console of the bug mentioned here.
The error this issue is about makes entirely sense given the bug I've found and fixed - I would be very surprised if another bug manifests in the same way.
=> Without clear, detailed instructions on how to reproduce this with newest flutter master there's nothing I can do.
mkustermann commentedon Sep 20, 2024
@kenzieschmoll Do you still experience this issue and have reproduction instructions? Or is the issue fixed for you as well (as I would expect)?
kenzieschmoll commentedon Sep 26, 2024
I tried to reproduce this morning and could not, so it appears this issue is fixed. Thanks!