Skip to content
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

☂️ Migrate iOS embedder objective-c code to ARC (Auto Reference Counting) #137801

Closed
4 tasks done
Tracked by #112232
cyanglaz opened this issue Nov 2, 2023 · 10 comments
Closed
4 tasks done
Tracked by #112232
Assignees
Labels
engine flutter/engine repository. See also e: labels. P2 Important issues not at the top of the work list platform-ios iOS applications specifically team-ios Owned by iOS platform team triaged-ios Triaged by iOS platform team

Comments

@cyanglaz
Copy link
Contributor

cyanglaz commented Nov 2, 2023

Most of the files in ios Embedder and some shared darwin codes use MRC(Manual Reference Counting).

Manual Reference Counting is easy to make memory management mistake with. Objecgtive-C with Manual Reference Counting is not pleasant to work with, often scaring away contributors.

Migrate all the objective-C code to ARC will boosts Flutter's stability on iOS and making contributing to Flutter iOS embedder more efficient.

This is an umbrella issue tracks all the work needs to be done to migrate the iOS embedder to ARC:

  1. Temporarily enable Objective-C smart pointers (scoped_nsobject, scoped_block etc) to work with both ARC and MRC.
  2. Migrate all Objective-C files to ARC.
  3. [iOS] Eliminate ARC __bridge casts where possible #155943
  4. Remove the support of Objective-C smart pointers
@cyanglaz cyanglaz added platform-ios iOS applications specifically engine flutter/engine repository. See also e: labels. P1 High-priority issues at the top of the work list fyi-engine For the attention of Engine team team-ios Owned by iOS platform team labels Nov 2, 2023
@chinmaygarde
Copy link
Member

Is there a general issue for this that include macOS?

@chinmaygarde chinmaygarde added the triaged-engine Triaged by Engine team label Nov 6, 2023
@cyanglaz
Copy link
Contributor Author

cyanglaz commented Nov 6, 2023

Is there a general issue for this that include macOS?

macOS is already in ARC so I didn't create an issue for macOS. I can't think of any impact it could cause on macOS. Loop in @cbracken for might insights.

@vashworth vashworth added the triaged-ios Triaged by iOS platform team label Nov 6, 2023
@cbracken
Copy link
Member

cbracken commented Nov 7, 2023

Correct -- we're already building with ARC for macOS. I can't remember if the shared code in '//flutter/platform/darwin/common' is built with ARC enabled or not.

@cbracken
Copy link
Member

cbracken commented Nov 7, 2023

@flutter-triage-bot flutter-triage-bot bot removed fyi-engine For the attention of Engine team triaged-engine Triaged by Engine team labels Nov 7, 2023
auto-submit bot pushed a commit to flutter/engine that referenced this issue Nov 15, 2023
Introduce weak_nsobject from chromium. 

There are some usages of weak_ptr wrapping Objective-C ids, weak_ptr is not really designed for ids and such usages are blocking the arc migration. 

This PR mostly copies the weak_nsobject from chromium, at the same hash that we copied the ARC/MRC compatible scoped_nsobject: https://chromium.googlesource.com/chromium/src/+/fd625125b8a6a3aceaf09993a5f74cfe5368b17f

To match how we used weak_ptr for those ids, I made some changes to the weak_nsobject:
- WeakNSObjects needs to be generated by a WeakNSObjectFactory. The WeakNSObjectFactory is owned by the objc class and acts as the generator of the WeakNSObjects. All the WeakNSObjects' derefing thread should be the same of the WeakNSObjectFactory's creation thread.
- chromuim's WeakNSObjects can be detached from the thread and re-attached to a new thread. To match our weak_ptr behavior, I changed WeakNSObjects to be only accessed from a single thread, the same as weak_ptr

This PR also moves the FlutterEngine to use WeakNSObject and updated related classes.

part of flutter/flutter#137801

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
auto-submit bot pushed a commit to flutter/engine that referenced this issue Nov 17, 2023
Move all tests in flutter_test_ios_mrc to arc

Part of flutter/flutter#137801

Changes mostly involves trivial mrc to arc changes. non-trivial changes are commented inline. 

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
@jmagman jmagman added P2 Important issues not at the top of the work list and removed P1 High-priority issues at the top of the work list labels Jan 9, 2024
auto-submit bot pushed a commit to flutter/engine that referenced this issue Apr 10, 2024
…rScreenAndSceneIfLoaded to ARC (#51984)

Smart pointers support ARC as of #47612, and the unit tests were migrated in #48162.

Migrate `FlutterRestorationPlugin`, `FlutterTextureRegistryRelay`, and `UIViewController+FlutterScreenAndSceneIfLoaded` from MRC to ARC.  These files do not themselves import any MRC files, making them leaf nodes in the dependency graph of MRC files.  

Doing a few at a time to make the dependency graph manageable, and to easily revert if this causes retain cycles or other memory management issues.

Part of flutter/flutter#137801.
auto-submit bot pushed a commit to flutter/engine that referenced this issue Apr 11, 2024
Framework template updated in flutter/flutter#146481.  See [gen_keycodes README](https://github.com/flutter/flutter/tree/master/dev/tools/gen_keycodes ) for details.

Fixes flutter/flutter#146480 `-Wobjc-redundant-literal-use` error.

Note `-Wobjc-redundant-literal-use` is already on for clang-tidy 
https://github.com/flutter/engine/blob/6dc91bff96a56513a57ed5dd036fb16d25c945fd/.clang-tidy#L13 but in this case it's only true triggered when the file is compiled with ARC.  When I migrated this file to ARC as part of flutter/flutter#137801, it triggered the error.
auto-submit bot pushed a commit to flutter/engine that referenced this issue Apr 12, 2024
Smart pointers support ARC as of #47612, and the unit tests were migrated in #48162.

Migrate `FlutterEmbedderKeyResponder` from MRC to ARC.  Clean up some header imports which made this seem like it depended on not-yet-migrated MRC files.

Part of flutter/flutter#137801.
auto-submit bot pushed a commit to flutter/engine that referenced this issue Nov 14, 2024
Extracts backend-specific code in EmbedderConfigBuilder to separate translation units. In particular, this allows for less conditional header includes, and more specifically, for code relating to the Metal backend to include headers that include Objective-C types -- today we cast these all to void* to avoid declaring them in headers, which requires special handling for ARC.

An alternative approach would have been to extract backend-specific subclasses, but there are test suites such as EmbedderTestMultiBackend that are executed against multiple backends, which currently make that approach impractical, though that should likely be the long-term goal.

Issue: flutter/flutter#137801

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
auto-submit bot pushed a commit to flutter/engine that referenced this issue Nov 17, 2024
FlutterEngineGroup keeps an array of all live FlutterEngine instances it has created such that after the first engine, it can spawn further engines using the first.

Previously we manually managed this array by adding engines to it upon creation, then having [FlutterEngine dealloc] emit a notification such that FlutterEngineGroup can listen for it, and remove instances from the array upon reception of the notification.

Instead, we now use an NSPointerArray of of weak pointers such that pointers are automatically nilled out by ARC after the last strong reference is collected. This eliminates the need for the manual notification during dealloc.

Unfortunately, NSPointerArray is "clever" and assumes that if the array has not been mutated to store a nil pointer since its last compact call, it must not contain a nil pointer and can thus skip compaction. Under ARC, weak pointers are automatically nilled out when the last strong reference is released, so the above heuristic is no longer valid. We work around the issue by storing a nil pointer before calling compact.

See http://www.openradar.me/15396578 for the radar tracking this bug.

I'm not thrilled with the fact that we're replacing one sort of TODO with another, but the code is much simpler and avoids relying on a trip through the notification center, which seems objectively better.

Issue: flutter/flutter#155943
Issue: flutter/flutter#137801

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
cbracken added a commit to cbracken/flutter_engine that referenced this issue Nov 17, 2024
Previously, FlutterViewController.engine was declared as a weak readonly
property, but we explicitly declared the `FlutterEngine* _engine` ivar
as a strong reference in the implementation.

This changes the property declaration to be strong and eliminates the
now unnecessary ivar.

There is also no semantic change to FlutterViewController itself, since
the `_engine` ivar had been manually declared as a strong reference.

There is no semantic change for users of FlutterViewController.engine
since whether a user acquires a strong or weak reference to the engine
is determined by whether they declare the pointer to which they assign
it as strong or weak.

This also eliminates the need for the `engine` getter, which was only
present to prevent a warning that the strong ivar didn't match the weak
property declaration.

No changes to tests since this introduces no semantic changes.

Issue: flutter/flutter#137801
@cbracken
Copy link
Member

Just realised I hadn't updated this in a while. The entire codebase, other than impeller, is migrated to ARC. ScopedBlock, scoped_nsobject, scoped_nsprotocol, etc. have all been deleted. Once impeller is migrated, I'll close this issue.

auto-submit bot pushed a commit to flutter/engine that referenced this issue Nov 17, 2024
Previously, FlutterViewController.engine was declared as a weak readonly property, but we explicitly declared the `FlutterEngine* _engine` ivar as a strong reference in the implementation. This changes the property declaration to be strong and eliminates the now unnecessary ivar.

There is also no semantic change to FlutterViewController itself, since the `_engine` ivar had been manually declared as a strong reference.

There is no semantic change for users of FlutterViewController.engine since whether a user acquires a strong or weak reference to the engine is determined by whether they declare the pointer to which they assign it as strong or weak.

This also eliminates the need for the `engine` getter, which was only present to prevent a warning that the strong ivar didn't match the weak property declaration.

No changes to tests since this introduces no semantic changes.

Issue: flutter/flutter#137801

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
@chinmaygarde
Copy link
Member

Impeller is and always has been ARC only.

@cbracken
Copy link
Member

Ah that's why I didn't spot it in the targets explicitly!

Well... in that case, I think we're done. Just one more patch.

cbracken added a commit to cbracken/flutter_engine that referenced this issue Nov 18, 2024
Ensure that all Objective-C code in the codebase are being built with
the standard set of Flutter Objective-C compiler flags with ARC enabled.

Also bumps the cflags config up to the top of the first block within
each target in which Objective-C sources appear, so that the location is
consistent.

Issue: flutter/flutter#137801
cbracken added a commit to cbracken/flutter_engine that referenced this issue Nov 18, 2024
Enables the `-fobjc-arc` compiler flag for Objective-C and Objective-C++
translation units.

Eliminates the flutter_cflags_objc[c]_arc settings, since they're now
redundant.

All Obj-C/Obj-C++ code in our codebase has now been migrated to ARC.

Issue: flutter/flutter#137801
cbracken added a commit to cbracken/flutter_engine that referenced this issue Nov 18, 2024
Enables the `-fobjc-arc` compiler flag for Objective-C and Objective-C++
translation units.

Eliminates the flutter_cflags_objc[c]_arc settings, since they're now
redundant.

All Obj-C/Obj-C++ code in our codebase has now been migrated to ARC.

Issue: flutter/flutter#137801
cbracken added a commit to flutter/engine that referenced this issue Nov 18, 2024
Enables the `-fobjc-arc` compiler flag for Objective-C and Objective-C++
translation units.

Eliminates the flutter_cflags_objc[c]_arc settings, since they're now
redundant.

All Obj-C/Obj-C++ code in our codebase has now been migrated to ARC.

Issue: flutter/flutter#137801
@cbracken
Copy link
Member

We should also make sure delegates pointers are all weak where necessary: #156222

@cbracken
Copy link
Member

DONE!

cbracken added a commit to cbracken/flutter_engine that referenced this issue Nov 19, 2024
Extracts backend-specific code in DlSurfaceProvider to separate
translation units. In particular, this allows for less conditional
header includes, and more specifically, allows code relating to the Metal
backend to include headers that include ARC-managed Objective-C types.
Today we cast these all to void* (and manage refcounting manually) since
these headers are included in dl_surface_provider.cc, which is a pure
C++ translation unit.

Issue: flutter/flutter#137801
auto-submit bot pushed a commit to flutter/engine that referenced this issue Nov 19, 2024
Extracts backend-specific code in DlSurfaceProvider to separate translation units. In particular, this allows for less conditional header includes, and more specifically, allows code relating to the Metal backend to include headers that include ARC-managed Objective-C types. Today we cast these all to void* (and manage refcounting manually) since these headers are included in dl_surface_provider.cc, which is a pure C++ translation unit.

No test changes since this patch includes no semantic changes.

Issue: flutter/flutter#137801

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
cbracken added a commit to cbracken/flutter_engine that referenced this issue Nov 19, 2024
Previously, we could not include any Objective-C types in
test_metal_context.h, since that file was transitively included in pure
C++ translation units. All users have been refactored into
backend-specific files, and all Metal-related files are Objective-C++
files.

We now use Metal types directly in the header, without the workarounds.

Issue: flutter/flutter#158998
Issue: flutter/flutter#137801
auto-submit bot pushed a commit to flutter/engine that referenced this issue Nov 19, 2024
Previously, we could not include any Objective-C types in test_metal_context.h, since that file was transitively included in pure C++ translation units. All users have been refactored into backend-specific files, and all Metal-related files are Objective-C++ files.

We now use Metal types directly in the header, without the workarounds.

Issue: flutter/flutter#158998
Issue: flutter/flutter#137801

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
cbracken added a commit to cbracken/flutter_engine that referenced this issue Nov 20, 2024
Moves code specific to each graphics backend into the (existing)
translation unit associated with that backend.

Previously, we could not include any Objective-C types in
shell_test_platform_view_metal.h, since that file was included into
shell_test_platform_view.cc, which is pure C++. To work around this, we
had encapsulated Objective-C Metal types in a `DarwinContextMetal`
struct hidden in the implementation file with a pointer to it
forward-declared in the header.

We now use Metal types directly in the header, without the workarounds.

Issue: flutter/flutter#158998
Issue: flutter/flutter#137801
cbracken added a commit to cbracken/flutter_engine that referenced this issue Nov 22, 2024
Moves code specific to each graphics backend into the (existing)
translation unit associated with that backend.

Previously, we could not include any Objective-C types in
shell_test_platform_view_metal.h, since that file was included into
shell_test_platform_view.cc, which is pure C++. To work around this, we
had encapsulated Objective-C Metal types in a `DarwinContextMetal`
struct hidden in the implementation file with a pointer to it
forward-declared in the header.

We now use Metal types directly in the header, without the workarounds.

Issue: flutter/flutter#158998
Issue: flutter/flutter#137801
cbracken added a commit to cbracken/flutter_engine that referenced this issue Nov 22, 2024
Moves code specific to each graphics backend into the (existing)
translation unit associated with that backend.

Previously, we could not include any Objective-C types in
shell_test_platform_view_metal.h, since that file was included into
shell_test_platform_view.cc, which is pure C++. To work around this, we
had encapsulated Objective-C Metal types in a `DarwinContextMetal`
struct hidden in the implementation file with a pointer to it
forward-declared in the header.

We now use Metal types directly in the header, without the workarounds.

Issue: flutter/flutter#158998
Issue: flutter/flutter#137801
auto-submit bot pushed a commit to flutter/engine that referenced this issue Nov 22, 2024
Moves code specific to each graphics backend into the (existing) translation unit associated with that backend.

Previously, we could not include any Objective-C types in `shell_test_platform_view_metal.h`, since that file was included into `shell_test_platform_view.cc`, which is pure C++. To work around this, we had encapsulated Objective-C Metal types in a `DarwinContextMetal` struct hidden in the implementation file with a pointer to it forward-declared in the header.

We now use Metal types directly in the header, without the workarounds.

Issue: flutter/flutter#158998
Issue: flutter/flutter#137801

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
Copy link

github-actions bot commented Dec 4, 2024

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Dec 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
engine flutter/engine repository. See also e: labels. P2 Important issues not at the top of the work list platform-ios iOS applications specifically team-ios Owned by iOS platform team triaged-ios Triaged by iOS platform team
Projects
None yet
Development

No branches or pull requests

6 participants
@chinmaygarde @cbracken @jmagman @cyanglaz @vashworth and others