Summary:
The impact of this has proven impressive, and safe. Ship in code and remove feature-flag.
Changelog: [Internal]
Reviewed By: philIip
Differential Revision: D30269561
fbshipit-source-id: 9bb72567cfd881928d14d9bee43cf32b390664fb
Summary:
Update FabricUIManager methods for `SurfaceHandler` to start usual rendering or prerendering based on presence of the view instead of using two methods with same logic.
Changelog: [Internal]
Reviewed By: sshic
Differential Revision: D30346502
fbshipit-source-id: 297f2b4a16dc7af7c36379252bd73e6dc953ff59
Summary:
ReactSoftException makes it seem like the class is an Exception, when it's actually a logger. This rename I think is more appropriate.
Changelog: [Internal]
Reviewed By: JoshuaGross
Differential Revision: D30251735
fbshipit-source-id: 550bd543388e698774ec31753200bd3f722d8c17
Summary:
EZ diff that adds a few TODOs to unify component names between JS - Android - iOS - C++
see task: T97384889
changelog: [internal] internal
Reviewed By: sammy-SC
Differential Revision: D30139942
fbshipit-source-id: 91f51d04e7e7ecba7f059f94a121be43d820647d
Summary:
This diff extends the FabricUIManager.getInspectorDataForInstance to return the props of the React Native component associated to the view passed as a parameter.
changelog: [internal] internal
Reviewed By: sammy-SC
Differential Revision: D30095406
fbshipit-source-id: 50fdba6636a1f5042dbc113e341c3cb2534a1b04
Summary:
Unfortunately, parsing some props requires stateful context - namely, PlatformColor on Android. We explored several different options but they all seemed inferior to the approach of using ContextContainer, and most would require using global state.
By introducing this change everywhere as early as possible, we can avoid later pain. It is likely that some prop, on some platform, will require this mechanism. We'll be ready for it!
Because we can pass a constref of the ContextContainer through to all props and because the context and context data is never retained by prop parsers, perf and memory hit should be ~0.
This diff contains core changes only. Leaf changes to all props structs and conversions files will be in next diff(s).
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D29838789
fbshipit-source-id: f5090e7f02eb6e8fbe0ef4dd201e7d12104a3e3c
Summary:
In T94154173, when calling ```EventEmitterWrapper->invoke()```, hybrid function ```invokeEvent``` is null, even if we checked that ```mHybridData``` is valid before calling ```invokeEvent```.
**Theory:**
```invoke()``` is called from ```mqt_js``` thread, ```desotry()``` is called from ```main``` thread, which cause multi-thread access of```mHybridData```.
So if ```desotry()``` is called after ```isValid()``` check and before calling ```invokeEvent()```, ```invokeEvent``` could be destroyed and is null.
I can reproduce with above theory:
{F633411001}
**Fix:**
Make functions synchronized so ```mHybridData``` can be thread safe.
Changelog:
[Android][Fixed] - Make mHybridData thread safe
Reviewed By: RSNara
Differential Revision: D29792453
fbshipit-source-id: 8b4c754d53ece933be7b2cf99c6cd026b39e24ad
Summary:
This diff exposes a new API in FabricUIManager called getInspectorDataForInstance. The goal of this method is to return React metadata for a Native view.
This data will be used from partner teams to build tools that uses React metadata in RN
Data returned from React: P429701924
changelog: [internal] internal
allow-large-files
Reviewed By: JoshuaGross
Differential Revision: D29747864
fbshipit-source-id: 8cb55573be08cb530f7e3c83eed8b4fcf43e7781
Summary:
I'm hunting down the source of a perf regression on a screen and think that having these systrace sections could be handy for this and future investigations.
Changelog: [internal]
Reviewed By: mdvacca
Differential Revision: D29802969
fbshipit-source-id: f4030261da8888ddeb32ae41b9cf2b25af6a5583
Summary:
Always create a new EventEmitter specifically for Fabric when initializing the Fabric JSI module.
Previously, we were (sometimes!) reusing the EventEmitter being used for the old renderer and they were shared. There doesn't seem to be a compelling reason to continue doing this, and Fabric has optimized EventEmitters that we can use instead.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D29724537
fbshipit-source-id: 1b2c7a7d656e3fb86ddf98a6cf0f2e67dcbf8aef
Summary:
It is possible for receiveEvent to be called concurrently with/after destruction of FabricUIManager. Drop events if we are able to detect that case.
Changelog: [Internal]
Reviewed By: sshic
Differential Revision: D29596271
fbshipit-source-id: 1fa50d9c3cff0bf578316d905966e1bdfffe94d1
Summary:
Immediately destroy EventEmitterWrapper on update instead of waiting for Java GC. This can resolve JSI::~Pointer deallocation crashes by clearing out EventEmitter and therefore EventTarget sooner, before RN teardown.
Changelog: [Internal]
Reviewed By: fkgozali
Differential Revision: D29415386
fbshipit-source-id: 05517bfd9e2cc2bd1b8c58d4f84c84f6f547268a
Summary:
Changelog: [internal]
Reland of D29131766 (https://github.com/facebook/react-native/commit/18165367b0347fc46cd52a6ac00afcf62d05cb30) which had to reverted because it caused binary size regression in instagram.
Size check for `automation_instagram_stablesize_release` and `automation_igtv_release`
{F626711916}
Reviewed By: JoshuaGross
Differential Revision: D29263302
fbshipit-source-id: cc8f5609ebaed9ddf666f7c57cdbf3dbf77a8f78
Summary:
Because of T92179998, T93607943, and T93394807, we are still seeking resolution to tricky crashes wrt the use of EventEmitters.
I believe the recent spike is because of two recent changes: we pass in EventEmitters earlier, during PreAllocation; and we clean them up earlier, during stopSurface, to avoid jsi::~Pointer crashes.
Additionally, the gating previously added around the PreAllocation path was incorrect and led to more nullptrs being passed around as EventEmitters.
To mitigate these issues:
1) I am adding/fixing gating to preallocation and early cleanup paths
2) I am making EventEmitterWrapper more resilient by ensuring EventEmitter is non-null before invoking it.
3) I am making sure that in more cases, we pass a non-null EventEmitter pointer to Java.
4) I am backing out the synchronization in EventEmitterWrapper (java side) as that did not resolve the issue and is a pessimisation
There are older, unchanged paths that could still be passing in nullptr as the EventEmitter (Update and Create). As those have not changed recently, I'm not going to fix those cases and instead, we can now rely on the caller to ensure that the EventEmitter is non-null before calling.
Changelog: [internal]
Differential Revision: D29252806
fbshipit-source-id: 5c68d95fa2465afe45e0083a0685c8c1abf31619
Summary:
Because of the "disable preallocation of virtual views" experiment, for some reason, some views are being preallocated multiple times instead of not being preallocated at all.
This isn't really a problem for CreateView, and Preallocate is actually more strict here than it needs to be. I'm going to downgrade this to a soft error and will continue to analyze more. This is more of a perf issue than a correctness issue, so this should be fine.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D29206416
fbshipit-source-id: 9490a1a705c2b39def3a3e56086634439543515e
Summary:
Changelog: [internal]
We should be calling invokeUnique if event can be coalesced, not the other way around.
Reviewed By: JoshuaGross
Differential Revision: D29194528
fbshipit-source-id: 36e4ae71254420ef47deea436cad20eec09712fc
Summary:
Changelog: [internal]
Why does the crash happen?
We call method on invalid address. We crash on `std::weak_ptr::lock` because that's the first accessed ivar.
In D29020768 (https://github.com/facebook/react-native/commit/25e8fbe8ffa1c91522e91819a781434093f8b759), eventEmitter may be destroyed before an event is dispatched. Calling destroy on hybrid object destroys only C++ part.
Reviewed By: JoshuaGross
Differential Revision: D29194906
fbshipit-source-id: ae8d9d90aa8d98d69d29884e80d6b930b1e66870
Summary:
Changelog: [internal]
RuntimeScheduler needs to be created and registered in the runtime before any JS is allowed to run. This diff moves the registration right after the runtime is initialised.
This diff removes funnelling of Fabric events through RuntimeScheduler. This will be added in subsequent diff to keep the complexity low.
Reviewed By: JoshuaGross
Differential Revision: D29131766
fbshipit-source-id: cbc650f6fbce95e4b9c2c9695e8e0aba5beac635
Summary:
Changelog: [internal]
Remove `RuntimeScheduler` from `SchedulerToolbox` and all of its uses.
`RuntimeScheduler` needs to be allocated before `Scheduler` and therefore its presence in the toolbox is redundant.
Reviewed By: JoshuaGross
Differential Revision: D29134769
fbshipit-source-id: fa00c5dcc4b565d6941e6d742c6aefade37b31c4
Summary:
The mount items executed before the view attach can fail with the RetryableMountingLayerException, which we should either retry or skip the item. This change updates logic for such items to catch these exceptions.
Instead of passing `MountingManager` to execute the items, this change now passes a reference to the `MountItemDispatcher` (abstracted through interface to resolve cycle between the manager and dispatcher). The dispatcher executes the queue directly and schedules retry together with the next batch.
Changelog: [Internal]
Reviewed By: JoshuaGross
Differential Revision: D29068063
fbshipit-source-id: 04030b21db188d5617c3448322d25ba77d5fbb9f
Summary:
This feature is still causing some number of crashes, though prod impact is not yet determined. For safety I'm adding a feature flag so we can disable this if necessary.
Changelog: [internal]
Reviewed By: kacieb
Differential Revision: D29117957
fbshipit-source-id: 3b19bac9dd00735f51f5c9cba606378b2a62975e
Summary:
PreAllocation currently always happens at revision 0 (after ShadowNode creation), and all CREATE mutations are triggered for ShadowNodes at revision 1 or higher (since CREATE mutations are generated by the differ, it means that all ShadowNodes have revision 1 or higher when CompleteRoot is called). This means that between PreAllocation and CREATE, we /always/ expect at least one clone.
It is possible for a node to be "non-view-forming" at revision 0, causing view preallocation to be skipped, and "view-forming" at revision 1 (causing the CREATE mutation to be thrown away, since all CREATE mutations of revision 0 or 1 are thrown away). This causes a crash. It is extremely marginal, but there are repros in the wild.
Thus, I'm introducing one new UIManager and Scheduler delegate method that allows the mounting layer to be notified of clones. If a clone from rev 0->1 results in a node going from non-view-forming to view-forming, we can preallocate then, as well.
This resolves this crash, and allows us to keep experimenting safely with this View PreAllocation optimization. I believe all edge-cases are accounted for.
Changelog: [Internal]
Reviewed By: sammy-SC
Differential Revision: D29043426
fbshipit-source-id: dff11d3140ded1cbb02a5518a3aeb52dc812cc50
Summary:
In T92179998, there is a crash when an EventEmitterWrapper is deallocated after the JS VM is torn down, and the EventEmitterWrapper tries to free its JSI::Pointer reference (double-free).
To make sure this happens less/not at all, free EventEmitterWrappers on ViewState when a view is deleted, instead of waiting for all of RN to be torn down.
Changelog: [Internal]
Reviewed By: fkgozali
Differential Revision: D29020768
fbshipit-source-id: 9d72a23bc9966992ef56c1e3ee523405d4333194
Summary:
This is a re-land of D28810022 (https://github.com/facebook/react-native/commit/7e9c741146e1b3aa542ecfe138765e95ddddac3f), which was reverted due to T92179998. The fix is in D28938530. This issue could also be resolved by preventing more view preallocations (D28811419 (https://github.com/facebook/react-native/commit/8ca18f0b602a08cd9a5c9f6681bb5dc74e0d34f7)).
---
EventEmitter is not transmitted from C++ to Java until an UPDATE operation is enqueued.
Practically this usually happens "right away", but in the case of an Image component, especially, the EventEmitter could be missing while events are being fired from the native side (for example, loading events).
The fix is just to pass EventEmitter in sooner, in both Create and Preallocate. There should be no ill effect since EventEmitter is nullable anyway.
One potential side-effect: since Views can be PreAllocated and potentially never deallocated until StopSurface is called, this could result in more EventEmitter objects being leaked and retained from Java. I believe the fix is to remove PreAllocated Views more aggressively.
Changelog: [Internal]
Reviewed By: sammy-SC
Differential Revision: D28938637
fbshipit-source-id: c9e290a24ed15c28881e3eead4a5f580f66b288f
Summary:
setJSResponder/clearJSResponder have been in use in prod for a while and are stable. Ship them in code.
Changelog: [Internal]
Reviewed By: sammy-SC
Differential Revision: D28889894
fbshipit-source-id: 1c42526cd890d528062eeb50761fc49cc6109d76
Summary:
Virtual views that are flattened and don't "FormsView" on-screen should not be preallocated.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D28811419
fbshipit-source-id: 949dcbf4cf3791355c58af785603b35fa50f3f02
Summary:
This hack should not be necessary. It should be fixed at Differ or LayoutAnimations level if there are existing issues there.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D28810021
fbshipit-source-id: 98b8d2ae9991ad527a3b3e90943d75063b2a4496
Summary:
EventEmitter is not transmitted from C++ to Java until an UPDATE operation is enqueued. Practically this usually happens "right away", but in the case of an Image component, especially, the EventEmitter could be missing while events are being fired from the native side (for example, loading events).
The fix is just to pass EventEmitter in sooner, in both Create and Preallocate. There should be no ill effect since EventEmitter is nullable anyway.
One potential side-effect: since Views can be PreAllocated and potentially never deallocated until StopSurface is called, this could result in more EventEmitter objects being leaked and retained from Java. I believe the fix is to remove PreAllocated Views more aggressively.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D28810022
fbshipit-source-id: ae4c8b4eefe619d9a99fa5f90f612d6dd4880da5
Summary:
Adds logs to indicate that MountItem was queued instead of executed.
Also moves logging of preMount items to dispatcher for consistent logging with other items.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D28690203
fbshipit-source-id: 14d24f0bebb97a810127f5187b4d46f66b6c836f
Summary:
TL;DR: simplify and delete a bunch of stuff that shouldn't be necessary in Fabric.
I discovered that this event dispatcher (and the older one this is based on) is triple-queueing: we queue events into "staging", and then post "dispatch events" to only run /on the JS thread/. Even in Fabric. Then, each of these events is emitted into C++ where they are queued /again/! This refactor eliminates one more level of queueing - instead of scheduling dispatch for the JS thread, we just emit them directly to C++ when they're received in Java.
Unfortunately, the EventDispatcher is also used to drive AsyncEventBeat in C++:
1. EventBeatManager.onBatchEventDispatched: https://fburl.com/diffusion/qf6dyhsw
In the C++ impl, it indirectly will drive the AsyncEventBeat/AsyncEventBeatV2.
2. onBatchEventDispatched is ONLY called from EventDispatcherImpl: https://fburl.com/codesearch/mxk8ifyj
3. Which is queued and only runs on the JS thread: https://fburl.com/codesearch/czvbst4u
This means the AsyncEventBeat is only ticked when the JS thread is free, and ticks will be skipped when the JS thread is occupied for long periods.
Now, in this refactor, when this class is used it will drive AsyncEventBeat on every UI tick. This is also potentially not correct. On iOS (Fabric), AsyncEventBeat is driven when the UI thread is "about to sleep".
For now I'm not going to worry about that detail - it is significant, but Fabric+Android is currently /not doing the right thing/ and it's not clear that we want to maintain iOS behavior. This is something we need to discuss further and figure out.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D28654033
fbshipit-source-id: b3cb9b706343c8dd3c4cf84f24388908c57e2138
Summary:
EventDispatcherImpl uses synchronized blocks all over to make it thread-safe. I'm concerned about the perf implications of this and creating contention between JS and UI threads.
This is locked behind a feature flag.
Enabled only for Fabric in StaticViewConfig mode, and a feature flag, for now.
Changelog: [Internal]
Reviewed By: mdvacca
Differential Revision: D28591331
fbshipit-source-id: ea8f93a2e1343ce37fa78690dcb62fe03594120f
Summary:
This diff creates a ReactFeatureFlag to initialize MapBufferSo file during Fabric initialization.
This is necessary to be able to compare properly Mapbuffer vs ReadableNativeMap (because ReadableNativeMap c++ files is already included in the bridge so file)
changelog: [internal]
Reviewed By: JoshuaGross
Differential Revision: D28436044
fbshipit-source-id: 338e1bb72b5313dc29a309e1b0e979e7c8bd1c18