-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dart Compiler removes declaration of Finalizable class #52596
Comments
FFI/Finalizable transformer converts this code into the following kernel:
The first /cc @dcharkes |
This looks suspiciously similar to reading late variables before assigned. That we solved by making a second variable that is nullable.
I'm not sure if that is possible, what about code such as: MyFinalizable a;
if (someCondition) {
a = MyFinalizable();
}
if (someOtherCondition) {
somethingThatNeedsAReachabilityFence(); // some FFI call, or something that can throw, or ...
// What do we do here?
}
a = MyFinalizable();
// ... Maybe we can't have such cases, but I can't convince myself why. |
Tried the following code:
This results in the following kernel:
So, it looks like FFI/Finalizer transformer may need to add reachabilityFence at an arbitrary place, even where the variable is not used and statically it is not guaranteed to be initialized (but may be initialized). In such cases we can resort to a nullable shadow copy of the variable, much like |
That was @mraleph's idea also, but I had a hard time proving too myself we wouldn't do premature optimizations in kernel that would violate reachability.
It's a single pass transform, so we don't see those cases up front, unless we make the transform more advanced. We can apply the nullable shadow copy always, that would work. (Though we end up in the same conversation as last time, whether this would increase register pressure because we now get two variables.) At least it would keep everything consistent. |
Users are starting to hit this, we need to look at fixing it. |
At least one such situation I can come up with is void main() {
MyFinalizable1 m1;
MyFinalizable1 m2 = ...;
if (int.parse('1') == 1) {
m1 = ...;
m2.m1 = m1;
}
if (int.parse('2') == 2) {
// someFfiCall using m2, but also using m1 if m2 happens to point to it.
}
} It is a bit of a contrived example, because now you have both m2 holding on to m1 natively and Dart holding on to m1 from Dart. However, deleting the code in this case surely doesn't conform to our specification:
https://api.flutter.dev/flutter/dart-ffi/Finalizable-class.html Any optimization we do before the flow graph would break the notion of "variable in scope" that users see in the editor. I believe it would be a bad idea to start to make exceptions to that, and change the documentation in CL for a fix using the current approach: https://dart-review.googlesource.com/c/sdk/+/312909 |
TEST=pkg/vm/test/transformations/ffi_test.dart TEST=pkg/vm/testcases/transformations/ffi/regress_52596.dart Contains `throw "Attempt to execute code removed by Dart AOT compiler (TFA)";` without the fix. Closes:#52596 Change-Id: I5de819afcf6f70be037b60432ea016bc281b742e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/312909 Commit-Queue: Daco Harkes <dacoharkes@google.com> Reviewed-by: Slava Egorov <vegorov@google.com> Auto-Submit: Daco Harkes <dacoharkes@google.com>
@dcharkes can this be closed now? Does it need a cherry-pick? |
Yes
We could do a cherry-pick, though the workaround is trivial. Do you think it's worth the churn? |
This is to avoid a few Dart compiler bugs related to Finalizable objects: - dart-lang/sdk#54414 - dart-lang/sdk#52596 - dart-lang/sdk#51538
This is to avoid a few Dart compiler bugs related to Finalizable objects: - dart-lang/sdk#54414 - dart-lang/sdk#52596 - dart-lang/sdk#51538
* Bump required sdk version to ^3.3.0 This is to avoid a few Dart compiler bugs related to Finalizable objects: - dart-lang/sdk#54414 - dart-lang/sdk#52596 - dart-lang/sdk#51538 * Update CHANGELOG
Hi, from dart 3.0 I have a problem with compiler and class who implements Finalizable
this code launch on Android in release mode result to a crash:
E/flutter (24865): [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: Attempt to execute code removed by Dart AOT compiler (TFA)
E/flutter (24865): #0 TextBox.hashCode (dart:ui/text.dart)
E/flutter (24865): #1 _runMain. (dart:ui/hooks.dart:131)
E/flutter (24865): #2 _delayEntrypointInvocation. (dart:isolate-patch/isolate_patch.dart:296)
E/flutter (24865): #3 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:189)
The dart compiler as deleted the line "A a;"
an easy fix is to add late before "late A a;"
I have try on ios, and no problem.
Thank you.
The text was updated successfully, but these errors were encountered: