Commit Graph
2188 Commits
Author SHA1 Message Date
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
Ramanpreet Nara de56649430 Add CallInvoker::invokeSync
Summary:
We'll be using a native CallInvoker to dispatch sync and async method calls to ObjC NativeModules. This native CallInvoker will hold a reference to the ObjC NativeModule's method queue.

**Why is the native CallInvoker required for ObjC NativeModules?**
In the case where the ObjC NativeModule neither provides nor requests a method queue, we must create a method queue for it. When we go to invoke a method from JS, for these NativeModules specifically, there is no way to access this method queue. A native CallInvoker is a convenient abstraction that holds on to that method queue. For async calls, we'll just call `CallInvoker::invokeAsync`, and for sync calls, we'll just call `CallInvoker::invokeSync`.

**Why do we need sync call support for native `CallInvoker`?**
In ObjC, sync NativeModule method calls block the JS thread, then execute synchronously on the NativeModule's method queue, and then unblock the JS thread. This is what'll be implemented by `CallInvoker::invokeSync`.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D20829955

fbshipit-source-id: efb9d5408a1ade81069a943c865f232d4d10acfe
2020-04-03 09:47:42 -07:00
Ramanpreet Nara eb4e2baaa9 Rename Instance::getNativeCallinvoker to Instance::getDecoratedNativeCallInvoker
Summary:
Now, instead of accepting a `std::function` that schedules work, and returning a `CallInvoker`, `Instance::getDecoratedNativeCallInvoker`  will accept a `CallInvoker` that schedules work, and return a decorated `CallInvoker`.

I think this change will help with readability. It also clarifies that the bridge is adding additional behaviour to the native `CallInvoker`.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D20826885

fbshipit-source-id: a2c5681d10a4544ee3d2a0d1f1cbd386ef06d0e6
2020-04-03 09:47:41 -07:00
Ramanpreet Nara 3a11f0536e Make RCTTurboModuleManagerDelegate getTurboModule accept native CallInvoker and PerfLogger
Summary:
Might be worthwhile to just kill this method instead, since we're having all NativeModules provide their TurboModule jsi::HostObjects. But I'll leave that decision to a later time.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D20809201

fbshipit-source-id: ee73d4b5454a76460832a54f9b864841e5b2b9c0
2020-04-03 02:27:10 -07:00
Ramanpreet Nara 69698b25fc Codemod all getTurboModuleWithJsInvoker methods to accept a native CallInvoker
Summary:
To make iOS TurboModules integrate with the bridge's onBatchComplete event, they need to use a native CallInvoker. This call invoker is created by the `NativeToJsBridge`, and ObjCTurboModule will use this native CallInvoker to dispatch TurboModule method calls. This diff makes sure that ObjCTurboModules are created with that native CallInvoker.

## Script
```
var withSpaces = (...args) => args.join('\s*')

var regexString = withSpaces(
  '-',
  '\(',
  'std::shared_ptr',
  '<',
  '(?<turboModuleClass>(facebook::react::|react::|::|)TurboModule)',
  '>',
  '\)',
  'getTurboModuleWithJsInvoker',
  ':',
  '\(',
  'std::shared_ptr',
  '<',
  '(?<callInvokerClass>(facebook::react::|react::|::|)CallInvoker)',
  '>',
  '\)',
  '(?<jsInvokerInstance>[A-Za-z0-9]+)',
  'perfLogger',
  ':',
  '\(',
  'id',
  '<',
  'RCTTurboModulePerformanceLogger',
  '>',
  '\)',
  '(?<perfLoggerInstance>[A-Za-z0-9]+)',
  '{',
  'return',
  'std::make_shared',
  '<',
  '(?<specName>(facebook::react::|react::|::|)Native[%A-Za-z0-9]+SpecJSI)',
  '>',
  '\(',
  'self',
  ',',
  '\k<jsInvokerInstance>',
  ',',
  '\k<perfLoggerInstance>',
  '\)',
  ';',
  '}',
)

var replaceString = `- (std::shared_ptr<$<turboModuleClass>>)
    getTurboModuleWithJsInvoker:(std::shared_ptr<$<callInvokerClass>>)$<jsInvokerInstance>
                  nativeInvoker:(std::shared_ptr<$<callInvokerClass>>)nativeInvoker
                     perfLogger:(id<RCTTurboModulePerformanceLogger>)$<perfLoggerInstance>
{
  return std::make_shared<$<specName>>(self, $<jsInvokerInstance>, nativeInvoker, $<perfLoggerInstance>);
}`

const exec = require('../lib/exec');
const abspath = require('../lib/abspath');
const relpath = require('../lib/relpath');
const readFile = (filename) => require('fs').readFileSync(filename, 'utf8');
const writeFile = (filename, content) => require('fs').writeFileSync(filename, content);

function main() {
  const tmFiles = exec('cd ~/fbsource && xbgs -n 10000 -l getTurboModuleWithJsInvoker:').split('\n').filter(Boolean);

  tmFiles
    .filter((filename) => !filename.includes('microsoft-fork-of-react-native'))
    .map(abspath)
    .forEach((filename) => {
      const source = readFile(filename);
      const newSource = source.replace(new RegExp(regexString, 'g'), replaceString);

      if (source == newSource) {
        console.log(relpath(filename));
      }

      writeFile(filename, newSource);
    });
}

if (!module.parent) {
  main();
}
```

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D20809202

fbshipit-source-id: 5d39b3cacdaa5681b70ce1803351d0432dd74550
2020-04-03 02:27:10 -07:00
Ramanpreet Nara 7e16a9d5e2 Manual changes required to make ObjCTurboModule accept native CallInvoker
Summary: Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D20809200

fbshipit-source-id: d540eec9a3360a031f75d76a6ab9fb15303f8af5
2020-04-03 02:27:10 -07:00
Ramanpreet Nara b1b2f3016e Pass native CallInvoker to ObjCTurboModule constructor
Summary:
This is necessary to integrate TurboModule async method dispatch with the bridge's `onBatchComplete` event. See D20717931 for more details.

This diff is similar to D20480971.

**Note:** This stack doesn't really make any functional changes, since the native CallInvoker is `nullptr` right now.

Changelog:
[Internal]

Reviewed By: fkgozali

Differential Revision: D20809199

fbshipit-source-id: bf465a3a51bdddb8b56d1e696ca510fdf071f9ec
2020-04-03 02:27:09 -07:00
Valentin Shergin b145a82964 Fixed crash in JSIExecutor::NativeModuleProxy
Summary:
JSIExecutor::NativeModuleProxy is an object created by JSIExecutor and essentially representing that in JavaScript world. Before this change, JSIExecutor::NativeModuleProxy had a raw reference to JSIExecutor which (I believe) caused a crash because JSIExecutor can be deallocated before JSIExecutor::NativeModuleProxy. Now, instead of storing a pointer to JSIExecutor, we store a weak pointer to JSINativeModules which we can safely validate before calling on it.

Changelog: [Internal] Fixed crash in JSIExecutor

Now the configuration looks like this:

```
                                                         + - - - - - - - - - - - - - - - - - - - - -
                                                                        Something else              |
                                                         |     shared_ptr<jsi::Runtime> runtime      --+
                                                                                                    |  |
                                                         + - - - - - - - - - - - - - - - - - - - - -   |
                                                                                                       |
                                                                                                       |
 +------------------------------------------+                                                          |
 |                                          |                                                          |
 |            JSExecutorFactory             |                                                          |        +--------------------------------+-------------------------------+
 |                                          |                                  +-----------------------+        |                                |                               |
 +------------------------------------------+                                  |                                |                                v                               |
                                                                               |                                |          +------------------------------------------+          |
                                                                               +--------------------------+     |          |                                          |          |
                                                                               |                          |     |          |              ModuleRegistry              |          |
                                                                               v                          |     |          |                                          |          |
                                                         +------------------------------------------+     |     |          +------------------------------------------+          |
                                                         |            HermesRuntimeImpl             |     |     |          |                                                     |
                                                         |              (jsi::Runtime)              |--+  |     |          +->+------------------------------------------+       |
                                                         |                                          |  |  |     |          |  |std::unordered_map<std::string, size_t>   |       |
                                                         +------------------------------------------+  |  |     |          |  |modulesByName_                            |       |
                                                                                                       |  |     |          |  |                                          |       |
                                                                                                       |  |     |          |  +------------------------------------------+       |
                                                                                                       |  |     |          +->+------------------------------------------+       |
                                                                               +-----------------------+  |     |             |std::vector<std::unique_ptr<NativeModule>>|       |
                                                                               |                          |     |             |modules_                                  |       |
                                                                               |                          |     |             |                                          |       |
                                                                               v                          |     |             +------------------------------------------+       |
                                                         +------------------------------------------+     |     |                                                                |
                                                         |                                          |     |     |                                                                |
                                                         |      JSIExecutor::NativeModuleProxy      |     |     |                                                                |
                                                         |                                          |     |     |                                                                |
                                                         +------------------------------------------+     |     |                                                                |
+------------------------------------------+             |                                                |     |                                                                |
|                                          |             +->+------------------------------------------+  |     |                                                                |
|             NativeToJsBridge             |                |shared_ptr<JSINativeModules>              |  |     |                                                                |
|                                          |                |nativeModules_                            |  |     |                                                                |
+------------------------------------------+                +------------------------------------------+--+-----+------------------------------------+                           |
|                                                                                                         |     |                                    |                           |
+->+------------------------------------------+                                                           |     |                                    |                           |
|  |unique_ptr<JSExecutor>                    |                                                           |     |                                    |                           |
|  |m_executor                                |                                                           |     |                                    |                           |
|  |(`::destroy()` resets it.)                |                                                           |     |                                    |                           |
|  +------------------------------------------+--------------------------------+                          |     |                                    |                           |
+->+------------------------------------------+                                |                          |     |                                    |                           |
|  |shared_ptr<JsToNativeBridge>              |                                |                          |     |                                    |                           |
|  |m_delegate                                |                                |                          |     |                                    |                           |
|  +------------------------------------------+--+                             v                          |     |                                    |                           |
+->+------------------------------------------+  |       +------------------------------------------+     |     |                                    |                           |
   |shared_ptr<MessageQueueThread>            |  |       |                                          |     |     |                                    |                           |
   |m_executorMessageQueueThread              |  |       | HermesExecutor: JSIExecutor: JSExecutor  |     |     |                                    |                           |
   +------------------------------------------+  |       |                                          |     |     |                                    |                           |
                                                 |       +------------------------------------------+     |     |                                    |                           |
                                                 |       |                                                |     |                                    |                           |
                                                 |       +->+------------------------------------------+  |     |                                    |                           |
                                                 |       |  |shared_ptr<jsi::Runtime>                  |  |     |                                    |                           |
                                                 |       |  |runtime_                                  |  |     |                                    |                           |
                                                 |       |  +------------------------------------------+--+     |                                    |                           |
                                                 |       +->+------------------------------------------+        |                                    |                           |
                                                 |       |  |shared_ptr<JSINativeModules>              |        |                                    |                           |
                                                 |       |  |nativeModules_                            |        |                                    |                           |
                                                 |       |  +------------------------------------------+--------+------------------------------------+                           |
                      +--------------------------+       +->+------------------------------------------+        |                                    |                           |
                      |                                     |std::shared_ptr<ExecutorDelegate>         |        |                                    v                           |
                      |                                     |delegate_                                 |        |              +------------------------------------------+      |
                      |                                     +------------------------------------------+--+     |              |                                          |      |
                      |                                                                                   |     |              |             JSINativeModules             |      |
                      |                                                                                   |     |              |                                          |      |
                      |                                                                                   |     |              +------------------------------------------+      |
                      |                                                                                   |     |              |                                                 |
                      |                                                                                   |     |              +-->+------------------------------------------+  |
                      +-----------------------------------------------------------------------------------+     |                  |m_moduleRegistry                          |  |
                      |                                                                                         |                  |(shared_ptr)                              |  |
                      |                                                                                         |                  +------------------------------------------+--+
                      |                                                                                         |
                      |                                                                                         |
                      v                                                                                         |
+------------------------------------------+                                                                    |
|                                          |                                                                    |
|    JsToNativeBridge: ExecutorDelegate    |                                                                    |
|                                          |                                                                    |
+------------------------------------------+                                                                    |
|                                                                                                               |
+->+------------------------------------------+                                                                 |
   |shared_ptr<ModuleRegistry>                |                                                                 |
   |m_registry                                |                                                                 |
   +------------------------------------------+-----------------------------------------------------------------+

```

Reviewed By: RSNara

Differential Revision: D20817257

fbshipit-source-id: 9ae378dbe880aaabfef7ae783dae2f94ee4b0af5
2020-04-02 11:16:13 -07:00
Samuel Susla 3d61dc9f36 Back out "Fix controlled TextInput with child nodes"
Summary:
Changelog: [Internal]

Original commit changeset: 1b8a2efabbfa

Original diff D20587681 breaks non-controlled text input.

Reviewed By: motiz88

Differential Revision: D20815935

fbshipit-source-id: 70577ed1e5701850ff0e30a6592945a31c2a8bec
2020-04-02 08:26:04 -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
Sidharth Guglani 2e085a388b Fix Yoga flexshrink with min-width sizing issue
Summary:
While resolving the flexible items we calculate totalFlexShrinkScaledFactors which uses the flexBasis or initial width of node (Not min-width).

At a later stage during distribution of space we are subtracting value from this which also takes care of min-width.

For example
If node has flexShrink 1 and width 100 and min-width 301  then totalFlexShrinkScaledFactors will become -1*100 = -100
but later we are subtracting -1 * 301 (min-width) = -301 which is ambiguous and causing layout inconsistencies with how web behaves.

Fixed this by only using the flexBasis or width for these calculations.

Changelog:
[Internal][Yoga] Fix layout issue when flexShrink and min-width are used together

Reviewed By: pasqualeanatriello

Differential Revision: D20219419

fbshipit-source-id: 948fbc06ca541d4ad307c88c8a2df65d157778b1
2020-04-01 14:41:38 -07:00
Marc Horowitz 8970ee9f32 Make HermesRuntime::description() always include "HermesRuntime"
Summary:
If name is passed in as part of RuntimeConfig, that is included
in the description, too.
Changelog: [Internal]

Reviewed By: dulinriley

Differential Revision: D20716320

fbshipit-source-id: f2fba6df32f496090dee787d8b7f55a6a4dd8ed8
2020-04-01 13:42:56 -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
Samuel Susla 3591b7a956 Promote shadowColor to formsStackingContext property
Summary:
Changelog: [Internal]

View with `ShadowColor` was getting flattened and therefore views didn't have shadow property set.
This is fixed by promoting ShadowColor so in case it is set, it forms stacking context.

Reviewed By: shergin

Differential Revision: D20792201

fbshipit-source-id: 1033ac00e32047ffbb14e61b7c26348c578d132d
2020-04-01 10:42:51 -07:00
Samuel Susla 46722dcfc2 Swap left and right yoga position with start and end in RTL context
Summary:
Changelog: [Internal]

Paper swaps right and left in RTL setting, this logic is in [RCTShadowView.m](https://our.intern.facebook.com/intern/diffusion/FBS/browse/master/xplat/js/react-native-github/React/Views/RCTShadowView.m?commit=cdd504cfbee66ae0659495604c4ff7b5764a1d9e&lines=529-549).

For Fabric instead of doing it during yoga props assignment, I swap the left/right with start/end just before we pass yoga nodes to layout calculation.

Reviewed By: shergin

Differential Revision: D20420040

fbshipit-source-id: b777f2658f56c173743b2034b8b5059e3e0c9840
2020-04-01 05:42:20 -07:00
Joshua Gross 2b062eadc8 Fix bug in optimized differ
Summary:
The differ was still producing correct, but not minimal, instruction sets in some cases due to an optimization that was buggy.

This affected cases where 2+ nodes were inserted at the beginning of a list. It would trigger the old behavior where all nodes after the first would be removed, deleted, then reinserted.

See the test case (which was failing and now passed) and P128190998 (the 3->4 transition) for samples.

Changelog: [Internal] Fabric differ

Reviewed By: mdvacca

Differential Revision: D20785729

fbshipit-source-id: 2fea6a816753066abb358ed7bb51003140cd5fc4
2020-03-31 19:36:45 -07:00
Jacob Bower ed3054927c Plumb through memory allocation profiler feature to Chrome Inspector
Summary: Changelog: Make allocation profiler feature of Chome Inspector work

Reviewed By: dulinriley

Differential Revision: D20383003

fbshipit-source-id: 8a10c310d5a639a6644763adb53f2f0017057587
2020-03-31 11:02:41 -07:00
Jacob Bower 8454975d2c Save/restore IP when leaving the interpreter
Summary:
This diff implements the instruction pointer save/restore trick Tzvetan came up with; allowing us to observe and modify the IP from outside the interpreter loop with negligible overhead.

From Tzvetan's internal post on the subject:

> [Today] the interpreter IP is just a local variable in the interpreter function, so there is no way to get to its value from outside the function. It lives in a register and we don't want to make it a Runtime field since the overhead [of accessing it via memory in the interpeter loop] would kill us.

> However, if you really think about it, it only lives in a register while the interpreter function is running. For the rest of the time, it is spilled by the C++ compiler onto the stack.
So, precisely when we need it, it is actually stored in memory. The only problem is, we don't know where! Admittedly, that is an annoying problem, but it feels like it should be solvable.

> What if, instead of relying on the compiler to spill the IP register, we manually spill it ourselves, to a known location? It works. Example: https://godbolt.org/z/ftSDnp

This diff implements this approach across the whole interpreter loop: whenever we call out of the loop we capture/publish the IP and restore it again immediately after the external call returns. This means we can now see the IP outside the interpret loop and even change it. This is effectively "for free" as the compiler now skips spilling/restoring the IP behind the scenes.

The immediate benefit of this is knowing the current IP allows us to have more accurate stack-traces during execution. In future this may enabled tricks like changing the IP before returning to the interpreter loop, allowing things outside the interpreter to affect program flow without adding logic to the interpreter loop.

Reviewed By: tmikov

Differential Revision: D20151091

fbshipit-source-id: 3814382639800208d8985a32ede31ba8f7ff7c80
2020-03-31 11:02:41 -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
Samuel Susla 367a573ccc Assign orderIndex_ in ConcreteViewShadowNode constructor instead of ViewShadowNode's constructor
Summary:
Changelog: [Internal]

`orderIndex_` was only being assigned for `ViewShadowNode`, not for other `ShadowNodes` that are later represented on the screen.

Reviewed By: shergin

Differential Revision: D20746477

fbshipit-source-id: c04c2cfea14b9141d22bc3d9e9bb4c0c59925754
2020-03-31 09:50:17 -07:00
Samuel Susla c381518a68 Set RootNodeKind trait in ModalHostViewShadowNode
Summary:
Changelog: [internal]

`ModalHostViewShadowNode` didn't have `RootNodeKit` trait, therefore `getRelativeLayoutMetrics`  was including nodes in ancestors that it shouldn't have.

Reviewed By: shergin

Differential Revision: D20735801

fbshipit-source-id: 6b81e3b174c2f82e530abc2bca2da8bebc2270b0
2020-03-31 02:59:59 -07:00
Valentin Shergin 15ea60e3a8 RuntimeExecutor helpers that modify the way of the callback is being executed.
Summary:
Here we implement a bunch of helper methods that allow customizing the behavior of a RuntimeExecutor "on-demand" on the caller side. We will use it in the next diff(s).

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: PeteTheHeat

Differential Revision: D20551411

fbshipit-source-id: 51d3cd02b69753110c0e1155347c6e52eb882c7d
2020-03-30 19:35:08 -07:00
Samuel Susla bbd91446dd Include transform property when calling getRelativeLayoutMetrics
Summary:
Changelog: [Internal]

Current implementation of `measure` doesn't take transform into account..

So if you had a view which has width and height 100 and had `Scale(0.5, 0.5, 1)` (this will shrink view by half). Calling `getRelativeLayoutMetrics` would report its size being `{100, 100}`.
This applies if view's parent has transformation as well, because transformation is applied to all subviews of the view as well.

Reviewed By: mdvacca

Differential Revision: D20621590

fbshipit-source-id: 2cf902a0494291c821ecada56f810c5e6620db5a
2020-03-30 04:03:57 -07:00
Samuel Susla 26b209431b Add support for translation and rotation to operator * between Rect and Transform
Summary:
Changelog: [Internal]

Until now `Rect operator*(Rect const &rect, Transform const &transform)` supported only scaling. Now it supports translation and rotation as well.

Reviewed By: shergin

Differential Revision: D20622876

fbshipit-source-id: 1b65393bd3fd6fd9a8941903e0f2681a10097e4a
2020-03-30 04:03:57 -07:00
Samuel Susla 7a01afe03b Remove LayoutInspectingPolicy.includeScrollViewContentOffset
Summary:
`LayoutInspectingPolicy` has two flags, `includeTransform` and `includeScrollViewContentOffset`.

`includeScrollViewContentOffset` seems to be redundant for two reasons.

# 1st
From looking at callers, they have always the same value.
I looked at all call sites, and they are either always both set to true or both set to false.

# 2nd
The way we include scroll view content offset, is through transformation, so setting `includeTransform` to true and `includeScrollViewContentOffset` to false will include content offset anyway. In order to make both flags work, we would need to introduce further changes to `getRelativeLayoutMetrics`. But since the flag isn't used anyway, I think it is better to get rid of it for now. If we need it in the future, we could re-introduce it.

Reviewed By: shergin

Differential Revision: D20622256

fbshipit-source-id: fb6156c66b752319ea928239fa723ff90688b0a0
2020-03-30 04:03:57 -07:00
Joshua Gross d770d78032 Reimplement D19965405: Small improvements in Differentiator/TinyMap
Summary:
Two things:
1) I reimplement Valentin's idea in D19965405, so that TinyMaps can be iterated over, with a couple of bugfixes (calling front() or back() on an empty vector will crash).
2) I now use TinyMap instead of better::map in the "optimized" diffing algorithm.
3) `erase` now actually removes elements from the vector, but only when more than half of elements have been erased.
4) If you repeatedly erase elements at the beginning of the vector, they will no longer be iterated over. This is a specific optimization for our heaviest TinyMap use-cases.

These amount to some small but hopefully somewhat meaningful perf improvements.

Changelog: [Internal] Fabric perf

Reviewed By: shergin

Differential Revision: D20718719

fbshipit-source-id: 91f4b2e2e0f6387ae484e43d5b0095103087baa6
2020-03-28 14:49:54 -07:00
Joshua Gross 1281be69f2 Unit test for V2 "minimal instruction" diffing algorithm
Summary:
This unit test is to verify that the new diffing algorithm generates a "minimal" instruction set, with regards to removes and inserts ("moves").

These unit tests are here to verify the expected behavior in this new algorithm, but these tests may be modified or deleted in the future if we decide we want to change this behavior.

Changelog: [Internal] fabric unit test

Reviewed By: mdvacca

Differential Revision: D20706592

fbshipit-source-id: 5f9991498e0d788ecbf88d938bfe6d3f0f27af40
2020-03-27 19:07:54 -07:00
Joshua Gross 50a34bcd7f Optimize diff algorithm to produce fewer remove+insert ("move") paired instructions
Summary:
An evolution of D20633188 but more performant.

There are three optimized paths before the slow path.

The first optimized path tries to pair identical nodes from old/new tree, and generate Update mutations, until we hit nodes that are different (indicating either a remove or an insert). This already existed.

The next two optimizations, introduced by Tim in his JS pseudocode, were inspired by ReactJS's diffing algorithm. They work in cases where the rest of the nodes are (1) all removals/deletes or (2) all creates+inserts.

Finally, if those final two optimized paths can't run, it's because there is a mix of delete+remove, create+insert, and "move" operations, mixed at the beginning, middle, and/or end of the list.

This has slightly better average/best-case complexity as the previous implementation.
In particularly pathological cases where all nodes are arbitrarily reordered, or reversed, for instance (ABCDE->EDCBA) the algorithm has the same complexity as the previous algorithm (quadratic).

For now iOS is pinned to the older differ

Changelog: [Internal] Experiment to optimize diffing algorithm in Fabric

Reviewed By: shergin

Differential Revision: D20684094

fbshipit-source-id: d29fba95a0328156c023e1c87804f23770ee1d91
2020-03-27 19:07:53 -07:00
Joshua Gross 24b79c1182 Core telemetry tests: update so they pass on my machine
Summary:
`std::this_thread::sleep_for` is not really precise and will attempt to sleep for "at least" that much time, but may sleep much longer depending on what CPUs are doing and scheduling policies.

To get this to pass on my machine, I had to substantially increase the thresholds.

Changelog: [Internal]

Reviewed By: shergin

Differential Revision: D20689571

fbshipit-source-id: f159420d24a95da2b5d95d49ed7882e783291e98
2020-03-27 19:07:53 -07:00
Joshua Gross c3d0f3b2de Ship State Reconciliation 100% on all platforms
Summary:
State Reconciliation has been running 50/50 for a while and all metrics look stable. This is necessary for providing a good experience so we should ship to everyone unconditionally.

Changelog: [Internal] Fabric diffing reconciliation process improvement

Reviewed By: mdvacca

Differential Revision: D20715694

fbshipit-source-id: 25b2635ecc29b67e2911679c9db66bc84d37dec1
2020-03-27 18:44:02 -07:00
Kevin Gozali 21785eea67 Replace fbsource// with // in xplat/js/ files [4]
Summary:
`fbsource//xplat` and `//xplat` are equivalent for FB BUCK targets. Removing extra prefix for consistency.

Changelog: [Internal]

Reviewed By: JoshuaGross, shergin

Differential Revision: D20656696

fbshipit-source-id: 10f02decb1dc969fd3491ac90d97f09e2bda59e7
2020-03-26 01:12:50 -07:00
Kevin Gozali 25f7aea86c Replace fbsource// with // in xplat/js/ files [1]
Summary:
`fbsource//xplat` and `//xplat` are equivalent for FB BUCK targets. Removing extra prefix for consistency.

Changelog: [Internal]

Reviewed By: scottrice

Differential Revision: D20495655

fbshipit-source-id: a57b72f694c533e2e16dffe74eccb8fdec1f55f5
2020-03-25 21:55:47 -07:00
Valentin Shergin fb0232883b Fabric: Additional temporary checks in prop parsing infra
Summary:
While ViewConfig infra isn't perfect we need to check some value for correctness during prop-parsing.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: JoshuaGross

Differential Revision: D20639055

fbshipit-source-id: 193dcd0769bc7777bc8d60c964ede72ebdaa83e4
2020-03-24 21:55:54 -07:00
Michael Bolin 0b9ea60b4f Back out "Upgrade Prettier from 1.17 to 2.0.2."
Differential Revision: D20639755

fbshipit-source-id: 5028563f9cf0527a30b4259daac50cdc03934bfd
2020-03-24 21:47:35 -07:00
Michael Bolin cf44650b3f Upgrade Prettier from 1.17 to 2.0.2.
Summary:
This gets us on the latest Prettier 2.x:
https://prettier.io/blog/2020/03/21/2.0.0.html

Notably, this adds support for TypeScript 3.8,
which introduces new syntax, such as `import type`.

Reviewed By: zertosh

Differential Revision: D20636268

fbshipit-source-id: fca5833d003804333a05ba16325bbbe0e06d6c8a
2020-03-24 20:24:47 -07:00
Oleg Bogdanov 79c69bea02 hermes | inspector | Don't include posix headers on non-posix systems
Summary:
Changelog: [Internal]

Hermes inspector includes pthreads, arpa and sys headers on all OSes that would break vanilla Windows builds. This diff adds a check for posix-compliance before inclusion

(Note: this ignores all push blocking failures!)

Reviewed By: dulinriley

Differential Revision: D20564449

fbshipit-source-id: 8e264bc3104065dc4315bb291e8560609fe65184
2020-03-24 18:53:43 -07:00
generatedunixname89002005287564 9a75d50d46 xplat/js/react-native-github/ReactCommon/fabric/components/textinput/
Summary: Changelog: [Internal]

Reviewed By: scottrice

Differential Revision: D20619227

fbshipit-source-id: 674337e6ce585a4e96d020f9624b874ba86e2d80
2020-03-24 09:33:50 -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
Valentin Shergin 0952e4bb03 Fabric: View Test: Changing state should not dirty Yoga tree (in some most cases)
Summary: Changelog: [Internal] Fabric-specific internal change.

Reviewed By: mdvacca

Differential Revision: D20578789

fbshipit-source-id: 4336165217bd39fc8065cfaeb96ef7753433d48a
2020-03-23 13:33:23 -07:00
Valentin Shergin 100bf9076a Fabric: Changing signature of ComponentDescriptor::createState
Summary:
This is pure syntactic change. Often we don't have a shared pointer to ShadowNodeFamily and only have just a reference. At the same time, `ComponentDescriptor::createState` does not have to accept a shared pointer. So, it's better to accept just a reference.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D20578787

fbshipit-source-id: 905277001e096d41e75007575b59ea2ea15fbf4b
2020-03-23 13:33:21 -07:00
Valentin Shergin 3679929830 Fabric: Modernizing Yoga Dirty flag test.
Summary:
Now we using TEST_F thing that allows consilidating initialization.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: mdvacca

Differential Revision: D20578788

fbshipit-source-id: 103bcb8fdeb3dbf297385cfe56415bd646e16791
2020-03-23 13:33:20 -07:00
Samuel Susla a40cfc05b8 Fix controlled TextInput with child nodes
Summary:
Changelog: [Internal]

# There are three changes in this diff

## _stateRevision is replaced with a BOOL
`_stateRevision` was protecting against setting attributed string that is already visible to the user. Previously this was ok because the change was only coming from native, any changes from JS were ignored.

Imagine following scenario:

1. User taps key.
2. Update state is called on component initiated by native.
3. New state is created with incremented revision by one.
4. `_stateRevision` gets set to new state's revision + 1.
5. Now JS wants to change something because it just learnt that user tapped the key.
6. New state is created again with incremented revision by one.
7. Update state is called on the component, but the change isn't applied to the text view because `_state->getRevision()` will equal `_stateRevision`.

By having a BOOL instead of number, we very explicitly mark the region in which we don't want state changes to be applied to text view.

## Calling [_backedTextInputView setAttributedText] move cursor to the end of text input
This is prevented by storing what the current selection is and applying it after `[_backedTextInputView setAttributedText]` is called.
This was previously invisible because JS wasn't changing contents of `_backedTextInputView`.

## Storing of previously applied JS attributed string in state

This is the mechanism used to detect when value of text input changes come from JavaScript. JavaScript sends text input value changes through props and as children of TextInput.
We compare what previously was set from JavaScript to what is currently being send from JavaScript and if they differ, this change is communicated to the component.
Previously only first attributed string send from JavaScript was send to the component.

# Problem

If children are used to set text input's value, then there is a case in which we can't tell what source of truth should be.

Let's take following example
We have a text field that allows only 4 characters, again this is only a problem if those 4 characters come as children, not as value.
This is a controller text input.

1. User types 1234.
2. User types 5th character.
3. JavaScript updates TextInput, saying that the content should stay 1234.
4. In `TextInputShadowNode` `hasJSUpdatedAttributedString` will be set to false, because previous JS value is the same as current JS value.

Reviewed By: shergin

Differential Revision: D20587681

fbshipit-source-id: 1b8a2efabbfa0fc87cba210570142d162efe61e6
2020-03-23 04:42:09 -07:00
Joshua Gross fb9a7be2bd Fix TextInput left/right padding
Summary:
This fixes two things:

1) Currently it only respects Start and End padding, and if there's a Theme default, it will override Left/Right padding. Whoops.
2) Currently it doesn't respect when a TextInput starts with padding, but then is removed.

This resolves both.

It still does not account for RTL support.

Changelog: [Internal] Fix AndroidTextInput padding

Reviewed By: mdvacca

Differential Revision: D20573151

fbshipit-source-id: e89791641b6699e728cde9dbd661a8c21485fbc8
2020-03-20 18:47:31 -07:00
Ramanpreet Nara 39aae1038b Perflogger codemod manual changes
Summary:
Just includes the manual changes to get the perf logger moved to the ObjCTurboModule constructor.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D20498443

fbshipit-source-id: e607588f47ccc8ae199cd97043b09dfaff7a72dd
2020-03-18 11:01:15 -07:00
Ramanpreet Nara 9c4eb14213 Pass PerfLogger to ObjCTurboModule constructor
Summary:
Previously, I had logic inside `RCTTurboModuleManager` to attach the `id<RCTTurboModulePerformanceLogger>` to the `ObjCTurboModule` object

```
/**
 * By default, all TurboModules are long-lived.
 * Additionally, if a TurboModule with the name `name` isn't found, then we
 * trigger an assertion failure.
 */
auto turboModule = [strongSelf provideTurboModule:moduleName];

/**
 * TODO(T63718299): Move this setter into the ObjCTurboModule constructor
 */
if (performanceLogger) {
  if (auto objCTurboModule = std::dynamic_pointer_cast<facebook::react::ObjCTurboModule>(turboModule)) {
    objCTurboModule->setRCTTurboModulePerformanceLogger(performanceLogger);
  };
}
```

This diff removes that logic in `RCTTurboModuleManager`, and it also removes `ObjCTurboModule::setRCTTurboModulePerformanceLogger`. Henceforth, we'll instead pass the `id<RCTTurboModulePerformanceLogger>` into `ObjCTurboModule`'s constructor. I've made all the necessary changes to the codegen scripts in this diff as well.

This should also resolve T63903079 by simply eliminating the code that's crashing production FB apps.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D20480971

fbshipit-source-id: c3899981f880aa5d1354b5c3f4018c8fd57c3bae
2020-03-18 11:01:15 -07:00
Samuel Susla 48fe460ed9 When resolving borders, respect leading/trailing semantics before left/right
Summary:
Changelog: [Internal]

When resolving borders, leading/trailing semantics should take priority over left/right.

Reviewed By: shergin

Differential Revision: D20422951

fbshipit-source-id: 7a464c88f881a77732929a155aaa9b2e150bba74
2020-03-17 14:09:28 -07:00
Samuel Susla 71c7e80bfd Add RTL support
Summary:
Changelog: [internal]

layoutDirectionPass down layoutDirection from `RCTSurfacePresenter` down to `YogaLayutableShadowNode`.

In `ParagraphShadowNode`, we propagate layoutDirection from yoga node to `TextAttributes.layoutDirection`.

Reviewed By: shergin

Differential Revision: D20420041

fbshipit-source-id: 86e01d31ea9415acb8579c44c470cac870ec1b8f
2020-03-17 14:09:28 -07:00
Samuel Susla 678f1c4490 Fix crash in slider with custom image
Summary:
Changelog: [Internal]

# Why was it crashing?
Crash was caused by `data.getTrackImageRequest()` returning NULL. The crash happened inside `getCoordinator` method. If you look at the implementation of the method below

```
if (request) {
    return &request->getObserverCoordinator();
} else {
    return nullptr;
}
```

you might notice that we check for NULL, why is it crashing then? And why is it only crashing in production?

The reason is compiler's optimiser, which looks at `data.getTrackImageRequest()`, this method returns `ImageRequest const &` and sees that this method will always return a value, never NULL. Compiler then looks at our `getCoordinator` function, sees that we check there for nullity but since it can never be null, removes that branch.

# Solution
Create new SliderState with non null image observer.

Reviewed By: shergin

Differential Revision: D20491367

fbshipit-source-id: 17b7cf31feabbe6f8ece324a3d329902b2ef6a2d
2020-03-17 13:56:46 -07:00
Valentin Shergin 44618c80ed Revert D20464278: Make Lambda function called in NativeModule mutable to improve performance
Differential Revision:
D20464278

Original commit changeset: 846a8bc6c61c

fbshipit-source-id: 71b69687ab3c279ec4e14f633700355af2291705
2020-03-16 16:21:28 -07:00
Valentin Shergin e602b22bfb Fabric: Tests for traitCast<>
Summary:
Subject.

Changelog: [Internal] Fabric-specific internal change.

Reviewed By: sammy-SC

Differential Revision: D20462834

fbshipit-source-id: 13e3c3b45537e22002b948f967a2576bc52145e8
2020-03-16 10:21:41 -07:00