Граф коммитов

209 Коммитов

Автор SHA1 Сообщение Дата
Samuel Susla 976a305412 Remove clean up resources when the app is backgrounded experiment
Summary:
Changelog: [internal]

Experiment didn't move any metrics. Let's get rid of it.

Reviewed By: mdvacca

Differential Revision: D27588183

fbshipit-source-id: 55404a3d756971ee34d4a86acd1027ed077692c0
2021-04-07 17:01:04 -07:00
Samuel Susla 34d189ae09 Introducing Leak Checker
Summary:
Changelog: [internal]

Introducing LeakChecker. A tool that checks if all native components have been cleaned up when surface is stopped.

**Known shortcomings**:
- LeakChecker is only enabled in debug builds and the existence of leaks is logged to console.
- For now, Leak Checker looks at N-1 screen. This is intentional as there is a known limitation of React that doesn't free up all shadow nodes when surface is stopped. Because of this, the use of LeakChecker is not intuitive and I'll work with React team to try to work around this.
- It doesn't help locating the leak, it only informs that leak is present. I'll be looking into ways to help locate the leak.

Reviewed By: JoshuaGross, mdvacca

Differential Revision: D26727461

fbshipit-source-id: 8350190b99f24642f8e15a3c2e1d79cfaa810d3d
2021-03-17 02:57:37 -07:00
Ramanpreet Nara d02211cbce Filter out TurboModules from extraModulesForBridge
Summary:
When the TurboModule system is enabled, all TM-compatible NativeModules should not go through the legacy system. We have this filtering elsewhere in the bridge, but not for eagerly initialized NativeModules with custom initializers (i.e: modules returned from extraModulesForBridge). This diff adds that filtering for modules returned from extraModulesForBridge.

NOTE: NativeModule initializers can still perform side-effects. So, it's still best to not create the TM-compatible NativeModule inside extraModulesForBridge. This diff just adds an additional layer of defense within the bridge.

Changelog: [Internal]

Differential Revision: D26264531

fbshipit-source-id: 26179d9094f67d6d6315a65cdb2dc614e5397bf3
2021-02-05 16:17:28 -08:00
Samuel Susla 8695980e1e Add experiment to clean up resources when the app is backgrounded
Summary:
Changelog: [internal]

Setup an experiment to measure impact of releasing resources when the app enters background.

Reviewed By: JoshuaGross, shergin

Differential Revision: D25952690

fbshipit-source-id: acfaa4a1689cc03c6020fdee62d3594859c9da3d
2021-01-20 10:08:13 -08:00
Ramanpreet Nara 1a2d1dbae8 Attach RCTViewRegistry to NativeModules
Summary:
After this diff, NativeModules can synthesize the RCTModuleRegistry, and use that to query for UIViews of components, given their reactTags.

Changelog: [Internal]

Reviewed By: shergin

Differential Revision: D25645052

fbshipit-source-id: bb17606cc4862d07b739ef2c31a5e57f59201364
2020-12-19 06:01:48 -08:00
Ramanpreet Nara 4974e293c6 Attach RCTModuleRegistry to NativeModules
Summary:
The bridge now creates the RCTModuleRegistry, and assigns it to all NativeModules it creates.

Changelog: [Internal]

Reviewed By: PeteTheHeat

Differential Revision: D25414108

fbshipit-source-id: 81c6a05bde0e52cff8ed60297f27d8aa3ff15a87
2020-12-10 20:23:16 -08:00
Janic Duplessis 0959ff36d1 Move hermes to a separate podspec (#30478)
Summary:
Hermes being a subspec of ReactCore causes some build issues when RN is included in 2 different targets. It also causes it to include a lot of additional dependencies that it doesn't need. This moves it to a separate podspec loosely based on other specs in ReactCommon.

## Changelog

[iOS] [Fixed] - Move hermes to a separate podspec

Pull Request resolved: https://github.com/facebook/react-native/pull/30478

Test Plan: Test that it builds and run properly in an app

Reviewed By: fkgozali

Differential Revision: D25308237

Pulled By: hramos

fbshipit-source-id: b4cc44ea2b1b854831e881dbbf9a2f30f6704001
2020-12-03 20:08:00 -08:00
Kevin Gozali 8663ec4f42 Unbreak iOS build due to header import failure
Summary: Changelog: [Internal]

Reviewed By: p-sun, yungsters

Differential Revision: D24749871

fbshipit-source-id: 70692b8a32f9b7a214d7192ba444c695568e2ccf
2020-11-04 21:39:18 -08:00
Mike Grabowski c95ee5ac18 feat: Enable Hermes to work on iOS (#29914)
Summary:
This PR makes it possible to build iOS applications with Hermes. Note that it doesn't work with `use_frameworks!` just yet.

Fixes https://github.com/facebook/react-native/issues/27845 (by downgrading iOS deployment target for RCT-Folly to 9.0)
Fixes https://github.com/facebook/react-native/issues/28810 (as above)

Checklist:
- [x] Adjust release scripts to create Hermes bytecode bundle
- [x] Release new Hermes npm package that includes iOS files (unreleased right now, if you want to try locally, you have to clone Hermes and `yarn link` its master to this project)
- [x] Test on a new React Native application in both Debug and Release (Device)
- [x] Test on an RNTester application in both Debug and Release (Device)
- [x] Add missing `i386` to Hermes framework and enable Bitcode
- [x] Inspect CI failures for possible regressions
- [x] Resolve Folly issue as reported https://github.com/facebook/react-native/issues/27845 and https://github.com/facebook/react-native/issues/28810
- [x] Release new Hermes and test against it that everything works

## Changelog

[IOS] [FEATURE] - Enable Hermes on iOS
[INTERNAL] - Upgrade to CocoaPods 1.10.0 to resolve Xcode 12.0 issues
[INTERNAL] - Upgrade to Xcode 12.0 on the CircleCI
[INTERNAL] - Fix building RNTester in Release mode
[INTERNAL] - Fix build-time errors of `libevent` with `use_frameworks!`
[INTERNAL] - Introduce `USE_HERMES` variable and test all RNTester configurations on the CI
[INTERNAL] - Do not fetch CocoaPods repository since we're using CDN anyway

Pull Request resolved: https://github.com/facebook/react-native/pull/29914

Test Plan:
Turn on `hermes_enabled` to true in your `Podfile`, install pods, and run the iOS application. Your app should be running Hermes now.

Preview: (note "Engine: Hermes")

<img width="395" alt="Screenshot 2020-09-09 at 19 22 32" src="https://user-images.githubusercontent.com/2464966/92631584-d7c01d80-f2d1-11ea-9b40-33d73db96a53.png">

Reviewed By: hramos

Differential Revision: D24684845

Pulled By: cpojer

fbshipit-source-id: 900cbe3bf9398a6fd4a773d552899a001bf5146b
2020-11-03 01:14:38 -08:00
Peter Argany 192e821fbd Hook up logTaggedMarkerWithInstanceKey to performance logger [2/n]
Summary:
This re-uses the same logic as `logTaggedMarker` for `logTaggedMarkerWithInstanceKey`. When no instanceKey specified, use 0.

Changelog: [Internal]

Differential Revision: D24607919

fbshipit-source-id: 4a29e5ece9a5462eb1163185d26370ee873f1412
2020-10-30 14:05:11 -07:00
Samuel Susla 96ecad4341 Trigger garbage collection when the app receive memory warning
Summary:
Changelog: [internal]

The condition inside `[RCTCxxBridge handleMemoryWarning]` was preventing JS VM from handling memory pressure if React Native was loading. This seems incorrect as loading only occurs once at the startup but memory pressure event occurs mostly after React Native was initialised. Therefore, JS VM wasn't handling memory pressure events.

Reviewed By: shergin

Differential Revision: D24646724

fbshipit-source-id: 7b4420fe675261e434c3427c8ad366ba0086a453
2020-10-30 08:18:58 -07:00
Scott Kyle 42d232901c Fix ASAN crash in RCTMessageThread
Summary:
This should fix a race condition uncovered by ASAN build that results in `m_shutdown` being referenced after destruction.

This mirrors a similar fix made in react-native-macos: ea7767a211

Changelog: [Internal]

Reviewed By: shergin

Differential Revision: D24263156

fbshipit-source-id: 5fb1e7053c107dfb7050242fce8fcf0435e5592c
2020-10-13 15:37:52 -07:00
Emily Janzer 5a1ca38305 Add ReactMarker::logTaggedMarkerWithInstanceKey
Summary:
Adding another method to ReactMarker to log a marker with both a tag and an instanceKey. The instanceKey is used to attach the event to the correct marker instance - this is used already in Java, but not in C++ yet.

The way that ReactMarker is currently set up makes this change a little more complex/confusing. For some reason I'm not totally clear on, we're using C-style exports with some platforms-specific ifdefs in ReactMarker.h (even though the impl is .cpp?). And we swap out the implementation for `logTaggedMarker` at runtime in platform-specific code (JReactMarker and RCTCxxBridge).

In this diff, I just add a new function alongside `logTaggedMarker`, `logTaggedMarkerWithInstanceKey`. I did it this way because I figured modifying `logTaggedMarker` to add an argument would be a breaking change.

Reviewed By: PeteTheHeat

Differential Revision: D23831533

fbshipit-source-id: f5b3eba1f43a80f7723fdb64cfc0a792548db2ba
2020-10-01 14:16:32 -07:00
Jayme Deffenbaugh cb719a16cc Fix Xcode warnings in React-Core pod (#29622)
Summary:
With the upgrade to React Native 0.63, we started running into nullability warnings that were breaking our build. This PR fixes those nullability warnings as well as a few other warnings in React-Core.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[iOS] [Fixed] - Fix xcodebuild warnings in React-Core

Pull Request resolved: https://github.com/facebook/react-native/pull/29622

Test Plan:
- Nullability annotations should only affect compilation, but even though RNTester compiles, I'm not fully convinced that this won't break projects downstream. It would be good to get another opinion on this.
- The change in `RCTAllocateRootViewTag` is the only real logic change in this PR. We throw an exception if the root view tag is not in the correct format, so this change seems safe after some basic manual testing in RNTester.

Reviewed By: shergin

Differential Revision: D23386678

Pulled By: appden

fbshipit-source-id: a74875195a4614c3248e8f968aa98602e3ee2de0
2020-09-09 12:48:09 -07:00
Eloy Durán 941bc0ec19 Upstream RN macOS Hermes integration bits (#29748)
Summary:
Microsoft’s RN for macOS fork supports the Hermes engine nowadays https://github.com/microsoft/react-native-macos/pull/473. As a longer term work item, we’ve started moving bits that are not invasive for iOS but _are_ a maintenance burden on us—mostly when merging—upstream. Seeing as this one is a recent addition, it seemed like a good candidate to start with.

As to the actual changes, these include:

* Sharing Android’s Hermes executor with the objc side of the codebase.
* Adding a CocoaPods subspec to build the Hermes inspector source and its dependencies (`Folly/Futures`, `libevent`).
* Adding the bits to the Xcode build phase script that creates the JS bundle for release builds to compile Hermes bytecode and source-maps…
* …coincidentally it turns out that the Xcode build phase script did _not_ by default output source-maps for iOS, which is now fixed too.

All of the Hermes bits are automatically enabled, on macOS, when providing the `hermes-engine-darwin` [npm package](https://www.npmjs.com/package/hermes-engine-darwin) and enabling the Hermes pods.

## Changelog

[General] [Added] - Upstream RN macOS Hermes integration bits

Pull Request resolved: https://github.com/facebook/react-native/pull/29748

Test Plan:
Building RNTester for iOS and Android still works as before.

To test the actual changes themselves, you’ll have to use the macOS target in RNTester in the macOS fork, or create a new application from `master`:

<img width="812" alt="Screenshot 2020-08-18 at 16 55 06" src="https://user-images.githubusercontent.com/2320/90547606-160f6480-e18c-11ea-9a98-edbbaa755800.png">

Reviewed By: TheSavior

Differential Revision: D23304618

Pulled By: fkgozali

fbshipit-source-id: 4ef0e0f60d909f3c59f9cfc87c667189df656a3b
2020-08-27 01:18:33 -07:00
Peter Argany 9d3cefbbca Delete unused RCTAdditionalJavaScriptDidLoadNotification
Summary:
This notification was never used, I'd rather not have someone start relying on it, and need to figure out how to migrate them in bridgeless mode.

Changelog:[Internal]

Reviewed By: cpojer, RSNara

Differential Revision: D22513602

fbshipit-source-id: 80b179af8408abc6646a73380b4a66cade3f75f2
2020-07-23 17:11:32 -07:00
Ramanpreet Nara e549f6984e Gate TurboModule eager initialization
Summary:
TurboModule eager initialization is a bit dangerous if we get it wrong, which we did (twice): T69449176.

This diff gates TurboModule eager init behind a MC, so that we can control (i.e: turn off/on, and do gradually rollout of) TurobModule eager initialization in isolation from the larger TurboModules experiment.

Changelog: [Internal]

Reviewed By: PeteTheHeat

Differential Revision: D22460359

fbshipit-source-id: 3b8dce0529f1739bd68b8b16d6a28aa572d82c2c
2020-07-09 16:24:31 -07:00
Ramanpreet Nara a27c295f53 Rename RCTTurboModuleLookupDelegate to RCTTurboModuleRegistry
Summary:
## Why?
1. RCTTurboModuleLookupDelegate sounds a bit nebulous.
2. In JS and Java, we use a `TurboModuleRegistry` interface to require TurboModules. So, this diff will make JS, Java, and ObjC consistent.

Changelog:
[Internal]

Reviewed By: PeteTheHeat

Differential Revision: D22405754

fbshipit-source-id: 30c85c246b39d198c5b8c6ca4432a3196ca0ebfd
2020-07-07 16:25:11 -07:00
Ramanpreet Nara 103c863eaa Eagerly initialize TurboModules before executing JS bundle
Summary:
## Context
1. In FBReactModule jsExecutorForBridge, we asynchronously initialize a list of TurboModules on the main queue: https://fburl.com/diffusion/i56wi3px
2. After initializing the bridge, we start executing the JS bundle, here: e23e9328aa/React/CxxBridge/RCTCxxBridge.mm (L414-L417). Since bridge initialization knows nothing about TurboModule eager initialization, this happens concurrently with 1, and starts requiring NativeModules/TurboModules on the JS thread.

## The Race
1. Both the main thread and the JS thread race to create a TurboModule that requires main queue setup.
2. The JS thread wins, and starts creating the TurboModule. Meanwhile, the main thread blocks, waiting on a signal here, in RCTTurboModuleManager: e23e9328aa/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm (L430)
3. The JS thread tries to dispatch_sync to the main queue to setup the TurboModule because the TurboModule requires main queue setup, here: e23e9328aa/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm (L402)
4. We deadlock.

## The fix
Succinctly, NativeModule eager initialization finishes before execute the JS bundle, but TurboModule initialization doesn't. This diff corrects that mistake.

The changes in this diff:
1. The RN application via the TurboModuleManager delegate can now optionally provide the names of all eagerly initialized TurboModules by implementing two methods `getEagerInitModuleNames`, `getEagerInitMainQueueModuleNames`.
2. The TurboModuleManager grabs these two lists from the delegate, and exposes them to its owner via the `RCTTurboModuleRegistry` protocol.
3. The RCTCxxBridge, which already owns a `id<RCTTurboModuleRegistry>` object, uses it to eagerly initialize the TurboModules in these two lists with the correct timing requirements.

This is exactly how we implement eager initialization in Android.

**Note:** Right now, phase one and two of TurboModule eager initialization happen after phase one and two of NativeModule eager initialization. We could make the timing even more correct by initializing the TurboModules at the exact same time we initialize the NativeModules. However, that would require a bit more surgery on the bridge, and the bridge delegate. I think this is good enough for now.

Changelog:
[iOS][Fixed] - Fix TurboModule eager init race

Reviewed By: PeteTheHeat

Differential Revision: D22406171

fbshipit-source-id: 4715be0bceb478a8e4aa206180c0316eaaf287e8
2020-07-07 16:25:10 -07:00
Christoph Nakazawa 382f0898cf Bytecode client for iOS
Summary: Changelog: [Internal]

Reviewed By: javache

Differential Revision: D21206851

fbshipit-source-id: 67ab59688c19870ef419711fdfd489bf0442bb54
2020-06-15 06:52:53 -07:00
Christoph Nakazawa ad879e50bc Add `RCTDevSplitBundleLoader` native module
Reviewed By: ejanzer

Differential Revision: D21302418

fbshipit-source-id: a868f6dad3306190c7add26e8f9a976866c16aef
2020-06-08 09:07:42 -07:00
Ramanpreet Nara d7ac21cec5 Remove main queue execution of constantsToExport
Summary:
## Context
- If a NativeModule requires main queue setup, its `constantsToExport` method is executed on the main queue.
- In the TurboModule system, `constantsToExport` or `getConstants` is treated like a regular synchronous NativeModule method. Therefore, it's always executed on the JS thread.

This difference in behaviour is dangerous when we're A/B testing the TurboModule infra: One could write a NativeModule that requires main queue setup, and have it expose constants that access objects/state only accessible on the UI thread. This NativeModule would work fine in the legacy infra, which could be the case if the NativeModule author is testing locally. But once it ships to prod, it may run with the TurboModule system, and crash the application. To mitigate this risk, I'm removing this special main queue execution of `constantsToExport` from the legacy infrastructure.

## Consequences
- If a NativeModule's `constantsToExport` method accesses objects/state only accessible on the UI thread, it must do so by explicitly scheduling work on the main thread. I wrote up a codemod to fix this for our OSS modules: D21797048.
- Eagerly initialized NativeModules that required main queue setup had their constants calculated eagerly. After the changes in this diff, those NativeModules will have their constants calculated lazily. I don't think this is a big deal because only a handful of NativeModules are eagerly initialized, and eagerly initialized NativeModules are going away anyway.

Changelog:
[iOS][Removed] - Main queue execution of constantsToExport in NativeModules requiring main queue setup

Reviewed By: fkgozali

Differential Revision: D21829091

fbshipit-source-id: df21fd5fd2ef45a291c07400f360bba801ae290f
2020-06-02 23:01:35 -07:00
Valentin Shergin b99bdaa218 Fabric: Calling JSVM GC on memory pressure event on iOS (second attempt)
Summary:
This change is especially important for Fabric when a lot of objects (mostly ShadowNodes) have shared ownership. Without this change, JSVM could not know that bunch of natively allocated objects should be deallocated.
Changelog: [Internal] Fabric-specific internal change.

Reviewed By: mdvacca

Differential Revision: D21798527

fbshipit-source-id: f2051721b074b99660cdfd6c5b75679b9792403e
2020-05-29 20:38:25 -07:00
Ramanpreet Nara 4830085f40 Guard all NativeModulePerfLogger calls with a null check
Summary:
## Motivation
We got this crash T67304907, which shows a `EXC_BAD_ACCESS / KERN_INVALID_ADDRESS` when calling this line:
```
  NativeModulePerfLogger::getInstance().asyncMethodCallBatchPreprocessStart();
```
There are no arguments in that call, so I figured the only error could be when we try to invoke `getInstance()` or `asyncMethodCallBatchPreprocessStart()`.

This diff:
1. Removes the `NativeModulePerfLogger::getInstance()` bit. Now NativeModulePerfLogger is used via regular static C functions. So, there's no way that simply invoking one of the logging functions crashes the application: there's no vtable lookup.
2. Inside each logging function, when perf-logging is disabled, the global perflogger should be `nullptr`. This diff makes it so that in that case, we won't execute any code in the control group of the perf-logging experiment.

## Changes
**How do we enable NativeModule perf-logging?**
- Previously:
   - `NativeModulePerfLogger::setInstance(std::make_shared<FBReactNativeModulePerfLogger>(...))`
   - `TurboModulePerfLogger::setInstance(std::make_shared<FBReactNativeModulePerfLogger>(...))`.
- Now:
   - `BridgeNativeModulePerfLogger::enableLogging(std::make_unique<FBReactNativeModulePerfLogger>(...))`
   - `TurboModulePerfLogger::enableLogging(std::make_unique<FBReactNativeModulePerfLogger>(...))`

**How do we do NativeModule perf-logging now?**
- Previously:
   -  `NativeModulePerfLogger::getInstance().command(...args)`
   -  `TurboModulePerfLogger::getInstance().command(...args)`.
- Now:
   - `BridgeNativeModulePerfLogger::command(...args)`
   - `TurboModulePerfLogger::command(...args)`.

The benefit of this approach is that each method in `BridgeNativeModulePerfLogger` is guarded with an if check. Example:

```
void moduleCreateConstructStart(const char *moduleName, int32_t id) {
  NativeModulePerfLogger *logger = g_perfLogger.get();
  if (logger != nullptr) {
    logger->moduleCreateConstructStart(moduleName, id);
  }
}
```

Therefore, we don't actually execute any code when perf-logging is disabled.

Changelog:
[Internal]

Reviewed By: fkgozali

Differential Revision: D21669888

fbshipit-source-id: 80c73754c430ce787404b563878bad146295e01f
2020-05-20 20:19:30 -07:00
Ramanpreet Nara eb2a561ecb Rename <ReactCommon/NativeModulePerfLogger.h> to <reactperflogger/NativeModulePerfLogger.h>
Summary:
## Motivation
This rename will fix the following CircleCI build failures:
- [test_ios_unit_frameworks](https://circleci.com/gh/facebook/react-native/150473?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link)
- [test_ios_detox_frameworks](https://circleci.com/gh/facebook/react-native/150474?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link)

## Investigation
We have 4 podspec targets that map to the same header namespace (i.e: `header_dir`) `ReactCommon`:
- **New:** `React-perflogger`: Directory is `ReactCommon/preflogger`, and contains `NativeModulePerfLogger.{h,cpp}`.
- `React-runtimeexecutor`: Directory is `ReactCommon/runtimeexecutor`, and contains only `RuntimeExecutor.h`
- `React-callinvoker`: Directory is `ReactCommon/callinvoker`, and contains only `CallInvoker.h`
- `ReactCommon/turbomodule/core`: Directory is `ReactCommon/turbomodule`, and contains C++ files, as well has header files.

**The problem:**
We couldn't import headers from `React-perflogger` in `ReactCommon/turbomodule/core` files.

**The cause:**
I'm not entirely sure why, but I was able to discern the following two rules by playing around with the podspecs:
1. If your podspec target has a cpp file, it'll generate a framework when `USE_FRAMEWORKS=1`.
2. Two different frameworks cannot map to the same `module_name` or `header_dir`. (Why? No clue. But something breaks silently when this is the case).

So, this is what happened when I landed `React-perflogger` (D21443610):
1. The TurboModules code generates the `ReactCommon` framework that uses the `ReactCommon` header namespace.
2. `React-runtimeexecutor` and `React-callinvoker` also used the `ReactCommon` header namespace. However, neither generate a framework because of Rule 1.
3. When I comitted `React-perflogger`, I introduced a second framework that competed with the `ReactCommon` framework (i.e: TurboModules code) for the `ReactCommon` header namespace. Rule 2 violation.

## Thoughts on renaming
- `<perflogger/NativeModulePerfLogger.h>` is too generic, and the `perflogger` namepsace is used internally within FB.
- `<react/perflogger/NativeModulePerfLogger.h>` matches our fabric header format, but I'm pretty sure that slashes aren't allowed in `header_dir`: I tested this and it didn't work. IIRC, only alphanumeric and underscore are valid characters for `header_dir` or `module_name`. So, I opted to just use `reactperflogger`.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D21598852

fbshipit-source-id: 60da5d0f7758eaf13907a080b7d8756688f40723
2020-05-15 15:25:23 -07:00
Keegan Mendonca 2b0208b399 Revert D21585006: Rename <ReactCommon/NativeModulePerfLogger.h> to <reactperflogger/NativeModulePerfLogger.h>
Differential Revision:
D21585006

Original commit changeset: e3339273af5d

fbshipit-source-id: cb4ff227edcc16842c7539bf71c912cd4ec478e0
2020-05-14 21:48:44 -07:00
Ramanpreet Nara 9f3c7af400 Rename <ReactCommon/NativeModulePerfLogger.h> to <reactperflogger/NativeModulePerfLogger.h>
Summary:
## Motivation
This rename will fix the following CircleCI build failures:
- [test_ios_unit_frameworks](https://circleci.com/gh/facebook/react-native/150473?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link)
- [test_ios_detox_frameworks](https://circleci.com/gh/facebook/react-native/150474?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link)

## Investigation
We have 4 podspec targets that map to the same header namespace (i.e: `header_dir`) `ReactCommon`:
- **New:** `React-perflogger`: Directory is `ReactCommon/preflogger`, and contains `NativeModulePerfLogger.{h,cpp}`.
- `React-runtimeexecutor`: Directory is `ReactCommon/runtimeexecutor`, and contains only `RuntimeExecutor.h`
- `React-callinvoker`: Directory is `ReactCommon/callinvoker`, and contains only `CallInvoker.h`
- `ReactCommon/turbomodule/core`: Directory is `ReactCommon/turbomodule`, and contains C++ files, as well has header files.

**The problem:**
We couldn't import headers from `React-perflogger` in `ReactCommon/turbomodule/core` files.

**The cause:**
I'm not entirely sure why, but I was able to discern the following two rules by playing around with the podspecs:
1. If your podspec target has a cpp file, it'll generate a framework when `USE_FRAMEWORKS=1`.
2. Two different frameworks cannot map to the same `module_name` or `header_dir`. (Why? No clue. But something breaks silently when this is the case).

So, this is what happened when I landed `React-perflogger` (D21443610):
1. The TurboModules code generates the `ReactCommon` framework that uses the `ReactCommon` header namespace.
2. `React-runtimeexecutor` and `React-callinvoker` also used the `ReactCommon` header namespace. However, neither generate a framework because of Rule 1.
3. When I comitted `React-perflogger`, I introduced a second framework that competed with the `ReactCommon` framework (i.e: TurboModules code) for the `ReactCommon` header namespace. Rule 2 violation.

## Thoughts on renaming
- `<perflogger/NativeModulePerfLogger.h>` is too generic, and the `perflogger` namepsace is used internally within FB.
- `<react/perflogger/NativeModulePerfLogger.h>` matches our fabric header format, but I'm pretty sure that slashes aren't allowed in `header_dir`: I tested this and it didn't work. IIRC, only alphanumeric and underscore are valid characters for `header_dir` or `module_name`. So, I opted to just use `reactperflogger`.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D21585006

fbshipit-source-id: e3339273af5dfd65a1454d87213d1221de6a4651
2020-05-14 20:54:57 -07:00
Ramanpreet Nara 0b7bcd36ef Instrument RCTModuleData create
Summary:
`RCTModuleData` holds our NativeModule classes/objects. This diff instruments `RCTModuleData` create.

Changelog: [Internal]

Reviewed By: PeteTheHeat

Differential Revision: D21415433

fbshipit-source-id: 7738f763c185e20f756d9bb2eff4a9493cde74e8
2020-05-13 20:28:16 -07:00
Valentin Shergin 179b53bd89 Back out "Fabric: Calling JSVM GC on memory pressure event on iOS"
Summary:
Reverted for now because it causes a crash.

Original commit changeset: 46e32de0f108 (D21484773)

Changelog: [Internal]

Reviewed By: sammy-SC, kacieb

Differential Revision: D21555488

fbshipit-source-id: 555a143fe8cf4c8806d910803f104271454f5797
2020-05-13 13:46:56 -07:00
Valentin Shergin aece57be29 Fabric: Calling JSVM GC on memory pressure event on iOS
Summary:
This change is especially important for Fabric when a lot of objects (mostly `ShadowNode`s) have shared ownership. Without this change, JSVM could not know that bunch of natively allocated objects should be deallocated.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: dulinriley

Differential Revision: D21484773

fbshipit-source-id: 46e32de0f108082e60df346884c9287023156149
2020-05-08 17:34:15 -07:00
Kevin Gozali 8ad810717e iOS: when the bridge has been invalidated, NativeModule lookup should just return nil
Summary:
There's a corner case where:
* The bridge gets invalidated, and native modules are cleaning up themselves (but not done yet)
* Something asks for a NativeModule instance - ideally it should just get nil at this point
* If TM Manager is invalidating, we get nil correctly, but we continue thru the old NativeModule lookup logic
* The latter will fail anyway, and would throw a redbox (RCTLogError).

So, if the bridge is invalidated, if TM Manager returns nil, we should just return nil for old NativeModule lookup.

The module of interest is RCTImageLoader, which was requested by RCTImageView on deallocation. The problem is RCTImageView got dealloc'ed **after** the bridge has been invalidated, so the lookup would always fail...

Bonus: RCTImageView should just keep a weak ref to the RCTImageLoader, so that:
* if the imageLoader is still alive on image dealloc, it can still access them (last minute "meaningless" cleanup)
* if the imageLoader is gone, then the image deallocation doesn't do anything

Changelog: [iOS] [Fixed] - Fix module lookup race condition on bridge invalidation.

Reviewed By: p-sun, sammy-SC

Differential Revision: D21371845

fbshipit-source-id: 862dc07de18ddbfb90e87e24b8dbd001147ddce4
2020-05-03 09:32:54 -07:00
Ramanpreet Nara aef0ef4b31 Export Instance::getDecoratedNativeCallInvoker from RCTCxxBridge
Summary:
`RCTTurboModuleManager` will create a native `CallInvoker` for each ObjC NativeModule. This `CallInvoker` will be used to dispatch calls from JS to native. Before passing the native `CallInvoker` to the `ObjCTurboModule`, it'll first use `RCTCxxBridge decorateNativeCallInvoker` to get a bridge-aware decorated native `CallInvoker`. That way, the bridge remains informed about async TurboModule method calls that took place since the last time it was flushed. This ensures that we don't end up dispatching `onBatchComplete` any less with TurboModules on than we do with TurboModules off.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D20831546

fbshipit-source-id: b2eb4e0097e0dabf8c4bd8fdc4c850a0858af699
2020-04-03 09:47:42 -07:00
maciej simka 6f627f684b Split loadApplicationScript into initializeRuntime and loadBundle (#27844)
Summary:
This is the first of three PRs related to enabling multi-bundle support in React Native. More details, motivation and reasoning behind it can be found in RFC [here](https://github.com/react-native-community/discussions-and-proposals/issues/152).

Logic responsible for installing globals was pulled out from `loadApplicationScript` to `initializeRuntime` since it should be ran only once, what was left was renamed to `loadBundle`.

It's based on dratwas work from [here](https://github.com/callstack/react-native/tree/feat/multibundle/split-load-application), but applied to current `master` to avoid rebasing 3-months old branch and issues that come with that.

## Changelog

[Internal] [Changed] - split `loadApplicationScript` into `initializeRuntime` and `loadBundle` to enable multi-bundle support in the future
Pull Request resolved: https://github.com/facebook/react-native/pull/27844

Test Plan: Initialized new RN app with CLI, set RN to build from source and verified the still app builds and runs OK using code from this branch.

Reviewed By: rickhanlonii

Differential Revision: D19888605

Pulled By: ejanzer

fbshipit-source-id: 24ace48ffe8978796591fe7c6cf53a61b127cce6
2020-04-01 17:52:39 -07:00
Ramanpreet Nara 9b94a541d8 Get CallInvokers from the bridge
Summary:
## Context
For now, assume TurboModules doesn't exist.

**What happens when we call an async NativeModule method?**
Everytime JS calls an async NativeModule method, we don't immediately execute it. The legacy infra pushes the call into some queue managed by `MessageQueue.js`. This queue is "flushed" or "emptied" by the following events:
- **Flushed:** A C++ -> JS call. NativeModule async methods can called with an `onSuccess` and/or `onFail` callback(s). Calling `NativeToJsBridge::invokeCallback` to invoke one of these callbacks is one way for ObjC++/C++/Java to call into JS. Another way is via JSModule method calls, which are initiated by `NativeToJsBridge::callFunction`.
- **Flushed:** When `JSIExecutor::flush` is called. Since TurboModules don't exist, this only happens when we call `JSIExecutor::loadApplicationScript`.
- **Emptied:** When more than 5 ms have passed, and the queue hasn't been flushed/emptied, on the next async NativeModule method call, we add to the queue. Afterwards, we empty it, and invoke all the NativeModule method calls.

**So, what's the difference between flushed and emptied?**
> Note: These are two terms I just made up, but the distinction is important.

If the queue was "flushed", and it contained at least one NativeModule method call, `JsToNativeBridge` dispatches the `onBatchComplete` event. On Android, the UIManager module is the only module that listens to this event. This `onBatchComplete` event doesn't fire if the queue was "emptied".

**Why does any of this matter?**
1. TurboModules exist.
2. We need the TurboModules infra to have `JsToNativeBridge` dispatch `onBatchComplete`, which depends on:
   - **Problem 1:** The queue being flushed on calls into JS from Java/C++/ObjC++.
   - **Problem 2:** There being queued up NativeModule async method calls when the queue is flushed.

In D14656466, fkgozali fixed Problem 1 by making every C++/Java/Obj -> JS call from TurboModules also execute `JSIExecutor::flush()`. This means that, with TurboModules, we flush the NativeModule async method call queue as often as we do without TurboModules. So far, so good. However, we still have one big problem: As we convert more NativeModules to TurboModules, the average size of the queue of NativeModule method calls will become smaller and smaller, because more NativeModule method calls will be TurboModule method calls. This queue will more often be empty than not. Therefore, we'll end up dispatching the `onBatchComplete` event less often with TurboModules enabled. So, somehow, when we're about to flush the NativeModule method call queue, we need `JsToNativeBridge` to understand that we've executed TurboModule method calls in the batch. These calls would have normally been queued, which would have led the queue size to be non-zero. So if, during a batch, some TurboModule async method calls were executed, `JsToNativeBridge` should dispatch `onBatchComplete`.

**So, what does this diff do?**
1. Make `Instance` responsible for creating the JS `CallInvoker`.
2. Make `NativeToJsBridge` responsible for creating the native `CallInvoker`. `Instance` calls into `NativeToJsBridge` to get  the native `CallInvoker`.
3. Hook up `CatalystInstanceImpl`, the Android bridge, with the new JS `CallInvoker`, and the new native `CallInvoker`. This fixes `onBatchComplete` on Android. iOS work is pending.

Changelog:
[Android][Fixed] - Ensure `onBatchComplete` is dispatched correctly with TurboModules

Reviewed By: mdvacca

Differential Revision: D20717931

fbshipit-source-id: bc3ccbd6c135b7f084edbc6ddb4d1e3c0c7e0875
2020-04-01 11:39:18 -07:00
Emilis Baliukonis 232517a574 Implement nativePerformanceNow to improve Profiler API results (#27885)
Summary:
When experimenting with React Profiler API (https://reactjs.org/docs/profiler.html), I noticed that durations are integers without a debugger, but they are doubles with higher precision when debugger is attached. After digging into React Profiler code, I found out that it's using `performance.now()` to accumulate execution times of individual units of work. Since this method does not exist in React Native, it falls back to Javascript `Date`, leading to imprecise results.

This PR introduces `global.nativePerformanceNow` function which returns precise native time, and a very basic `performance` polyfill with `now` function.

This will greatly improve React Profiler API results, which is essential for profiling and benchmark tools.

Solves https://github.com/facebook/react-native/issues/27274

## Changelog

[General] [Added] - Implement `nativePerformanceNow` and `performance.now()`
Pull Request resolved: https://github.com/facebook/react-native/pull/27885

Test Plan:
```
const initialTime = global.performance.now();
setTimeout(() => {
  const newTime = global.performance.now();
  console.warn('duration', newTime - initialTime);
}, 1000);
```

### Android + Hermes

![Screenshot_1580198068](https://user-images.githubusercontent.com/13116854/73245757-af0d6c80-41b5-11ea-8130-dde14ebd41a3.png)

### Android + JSC

![Screenshot_1580199089](https://user-images.githubusercontent.com/13116854/73246157-92256900-41b6-11ea-87a6-ac222383200c.png)

### iOS

![Simulator Screen Shot - iPhone 8 - 2020-01-28 at 10 06 49](https://user-images.githubusercontent.com/13116854/73245871-f136ae00-41b5-11ea-9e31-b1eff5717e62.png)

Reviewed By: ejanzer

Differential Revision: D19888289

Pulled By: rickhanlonii

fbshipit-source-id: ab8152382da9aee9b4b3c76f096e45d40f55da6c
2020-03-31 10:23:51 -07:00
Ramanpreet Nara faff19a7c6 De-jank DevLoadingView
Summary:
## Problems
Repro steps:
1. Disable Fabric (because CMD + R doesn't work with Fabric right now).
2. Open up Marketplace and hit `CMD + OPT + R`
3. **Observe:** The progress bar doesn't show up right away. It also doesn't actually show progress.
https://pxl.cl/140g1

RN Support post: https://fb.workplace.com/groups/rn.support/permalink/3437652016283389/

## Fixes
The first problem is that progress bar doesn't actually show progress.

**Fix:** Bundle load progress is updated in `RCTCxxBridge`, where we first require `RCTDevLoadingView`, and then call its `updateProgress` method. Previously, we wouldn't  lazily load `RCTDevLoadingView`, it already didn't exist. Lazily loading `RCTDevLoadingView` causes the progress view to show up. Here: https://pxl.cl/140gt

If you look at the above video, you'll notice there are two stages to the progress bar: stage 1 displays the actual progress. Stage 2 prompts that we're downloading the JS bundle. As you can see, stage 1 and stage 2 have different background colors, even though both of them are green.

**Fix:** I adjusted the JS to match the Native color. Here: https://pxl.cl/140gT

We're almost there, but the progress bar is dismissed twice?

**Fix:** I dug into the code, and the reason why was because when we hit `CMD + R`, we invalidate the bridge, and immediately re-initialize it. This means that we asynchronously invalidate the old TurboModuleManager, and immediately create a brand new one. Therefore, two `RCTDevLoadingView` modules can (and do) exist at once. So, I moved `RCTDevLoadingView` to be an instance member of `FBReactModule`, to ensure that it doesn't get cleaned up and re-created when TurboModuleManager is deleted and re-created. This finally fixed the progress bar jank:
https://pxl.cl/140hn

Changelog:
[iOS][Fixed] - Remove RCTDevLoadingView jank

Reviewed By: rickhanlonii

Differential Revision: D20607815

fbshipit-source-id: 05825c67adaf3cfda70be0fa2dc92d413dc8921b
2020-03-25 12:09:40 -07:00
Peter Argany 421bc5fc7f Remove RCTExportModule log spam
Summary:
The bridge complains if modules aren't exported, which isn't really helpful with lazily loaded modules and turbo modules.

I considered only turning this off when TurboModules is enabled, but figured we'd be killing this soon anyways... If anyone feels strongly I can go that approach.

Changelog: [iOS][Internal] Remove RCTExportModule log spam

Reviewed By: shergin

Differential Revision: D20629575

fbshipit-source-id: d32d9fe244c4d06acfee982fca7c7f63da294dc5
2020-03-25 11:57:53 -07:00
Max Ovtsin 8721ee0a6b Get ReactiveNative compiled with Clang 10 (#28362)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/28362

Fixed a few compilation errors emitted by Clang 10.

Changelog:
[iOS] [Fixed] - Get ready for Clang 10

Differential Revision: D20549970

fbshipit-source-id: dc36a85d90d3e43a05f045feb57c6ab6ded67da7
2020-03-23 13:46:37 -07:00
generatedunixname89002005287564 1dc82a89d7 Daily `arc lint --take CLANGFORMAT`
Reviewed By: zertosh

Differential Revision: D20383094

fbshipit-source-id: 1dc497a98fd3b5962542735c5243d7ac9cd40da3
2020-03-11 21:41:04 -07:00
Andy Himberger 0c2db3256f timing fix for RCTCxxBridge.executeApplicationScript (#25991)
Summary:
In one of our test apps (actually on Mac not iOS, but same code) we very consistently crash in RCTCxxBridge.executeApplicationScript when js debugging, due to a timing issue where another thread has reset _reactInstance in between the null check on self->_reactInstance and usage of it on these lines:

```
    } else if (self->_reactInstance) {
      self->_reactInstance->loadScriptFromString(std::make_unique<NSDataBigString>(script),

```
The thread doing the reset is doing so switching the executorClass to WebSocketExecutor.
In the scenario we crash, the packager has a bundle ready and quickly returns it, though its a 34MB string being passed to NSDataBigString which must be taking long enough for the other thread to get a chance to reset.

## Changelog

[iOS] [Fixed] - Fix crash in RCTCxxBridge.executeApplicationScript
Pull Request resolved: https://github.com/facebook/react-native/pull/25991

Test Plan: Ran apple code path in normal from bundle file and js debugging scenarios.

Reviewed By: shergin

Differential Revision: D19186065

Pulled By: hramos

fbshipit-source-id: ae1d4b5b50b7fb33b74aba21addc2978e917479f
2020-03-10 18:15:42 -07:00
Valentin Shergin d0871d0a9a Clang format for all React Native files
Summary:
Buckle up, this enables clang-format prettifier for all files in React Native opensource repo.

Changelog: [Internal] Clang-format codemod.

Reviewed By: mdvacca

Differential Revision: D20331210

fbshipit-source-id: 8da0f94700be0c35bfd399e0c48f1706de04f5b1
2020-03-08 23:01:17 -07:00
Ramanpreet Nara 6a9a76e420 Make RCTDevLoadingView TurboModule-compatible
Summary:
This is a redo of D16969764, with a few extensions.

## Changes
1. Move `RCTDevLoadingView.{h,m}` to `CoreModuels/RCTDevLoadingView.{h,mm}`
2. Extract ObjC API of `RCTDevLodingView` into `RCTDevLoadingViewProtocol` in `ReactInternal`.
3. Create API `RCTDevLoadingViewSetEnabled.h` in `ReactInternal` to enable/disable `RCTDevLoadingView`

Changelog:
[iOS][Added] - Make RCTDevLoadingView TurboModule-compatible

Reviewed By: PeteTheHeat

Differential Revision: D18642554

fbshipit-source-id: 6b62e27e128d98254b7a6d018399ec1c06e274fc
2020-02-27 17:06:13 -08:00
Peter Argany 824e171117 Refactor HotModuleReloadClient setup call from bridge to RCTDevSettings
Summary:
This refactors some logic which sets up HMRClient in JS. The logic should live in RCTDevSettings, so it is shared in bridge/bridgeless mode.

This also means the logic will be compiled out when `RCT_DEV_MENU` is false.

Reviewed By: RSNara

Differential Revision: D19563629

fbshipit-source-id: 5c2553be9fd686a2a178f03bb5eed7a82cbadb1b
2020-02-13 12:27:47 -08:00
Rick Hanlon 2f9d94418d Don't log for unavailable modules during reload
Summary:
Removes logging for known invalid states.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D18966536

fbshipit-source-id: 483dce1d2bf0c6c92458f618789cf98dcf92ee97
2020-01-29 04:33:04 -08:00
zhongwuzw 948cbfdacc Add autorelease pool for each run loop for JS Thread (#27395)
Summary:
Fixes https://github.com/facebook/react-native/issues/27327 , we need to create autorelease pool for each run loop in secondary thread, otherwise application may have memory issues. More details can refer to [CreatingThreads](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html)
![image](https://user-images.githubusercontent.com/5061845/70033738-05fa2980-15eb-11ea-9adb-f01bee937766.png)

## Changelog

[iOS] [Fixed] - Add autorelease pool for each run loop for JS Thread
Pull Request resolved: https://github.com/facebook/react-native/pull/27395

Test Plan: Example can be found in https://github.com/facebook/react-native/issues/27327. No memory spikes any more.

Reviewed By: PeteTheHeat

Differential Revision: D19132504

Pulled By: fkgozali

fbshipit-source-id: d1747f27d36e9a7934966b34aa46d344e06193b3
2019-12-16 23:31:38 -08:00
Valentin Shergin f798e2bc8d RCTAssertJSThread was removed
Summary:
RCTAssertJSThread is a specific to RCTCxxBridge assert that ensured that the code is executed on JavaScript thread. It was here from the very beginning. Now we need to remove it.
Reasons:
- The overall concept of limiting the execution of JavaScript code to a single thread is gone. Now we think about this as some queue, not thread. Fabric heavily relies on that and that asserts fires in Fabric.
- The assert is already far from being trivial: it checks for a custom executor, and if it's not nil, it does not fire. We can introduce another special flag for Fabric that will also disable that... but that's pointless. Such kinda asserts should not be complex to be useful.
- This asserts was used only in two places, and both of them are not exposed as public API.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D18946388

fbshipit-source-id: 1e5fc732abdcb4bff3cfadcba24f7a433f1a480e
2019-12-12 12:53:09 -08:00
Mehdi Mulani 3ceb95954a Enable dev loading view in build-on-device
Summary: Changelog: [iOS] [Changed] - Added another build flag for DevLoadingView

Reviewed By: JoshuaGross

Differential Revision: D18579773

fbshipit-source-id: e53733ac96ddcdb45e3d4ef23612f87ecb6dccd3
2019-11-18 15:24:32 -08:00
Peter Argany 2a13f12106 Re-implement reload reason [7/n]
Summary:
This diff adds back RN reload reason, which was removed earlier in the stack. cc/Rick

For callsites which already had a reason, I kept the string exactly the same. For callsites which didn't have a reason, I made up something reasonable.

Changelog: [Internal][Fixed] Re-implemented bridge reload reason text.

Reviewed By: RSNara

Differential Revision: D18074478

fbshipit-source-id: 64a3cd7718674a7ba7228a80e34791ce9f153f9f
2019-10-30 12:23:25 -07:00
Peter Argany d98cd7d3a1 Migrate bridge reload to RCTReloadCommand [2/n]
Summary:
Motivation described in diff 1/N.

This diff replaces calls to `[bridge reload]` with calls to `RCTReloadCommand`. This shouldn't have any change in behaviour since RCTBridge listens to RCTReloadCommand and calls `[bridge reload]` [here](https://fburl.com/diffusion/kemzkrei).

It will allow us to customize who listens and reacts to RN lifecycle.

Changelog: [Internal][Changed] - Migrated [bridge reload] calls to RCTReloadCommand

Reviewed By: shergin

Differential Revision: D17880909

fbshipit-source-id: 80b26c6badd4b216656fed6dd04554e9877f4bb7
2019-10-30 12:23:24 -07:00
Joe Loser ba18ee9b87 Replace folly::make_unique with std::make_unique (#26730)
Summary:
There is a mixed usage of `folly::make_unique` and `std::make_unique`. Soon, `folly::make_unique` may be removed (see [this PR](https://github.com/facebook/folly/pull/1150)). Since `react-native` only supports C++14-compilers and later, switch to always using `std::make_unique`.

## Changelog

[Internal] [Removed] - Replace folly::make_unique with std::make_unique
Pull Request resolved: https://github.com/facebook/react-native/pull/26730

Test Plan:
Running the existing test suite. No change in behavior is expected.

Joshua Gross: buck install -r fb4a, make sure MP Home and forced teardown works okay on android

Reviewed By: shergin

Differential Revision: D18062400

Pulled By: JoshuaGross

fbshipit-source-id: 978ca794c7e972db872a8dcc57c31bdec7451481
2019-10-22 12:21:41 -07:00