react-native-windows 0.82.1 → 0.82.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Microsoft.ReactNative/Base/CxxReactIncludes.h +11 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +52 -2
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +70 -49
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +4 -1
- package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/WindowsTextLayoutManager.cpp +7 -2
- package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -1
- package/Microsoft.ReactNative/Pch/pch.h +2 -0
- package/Microsoft.ReactNative/ReactHost/CrashManager.cpp +5 -0
- package/Microsoft.ReactNative/ReactHost/ReactNativeHeaders.h +1 -0
- package/PropertySheets/External/Microsoft.ReactNative.Composition.CppLib.props +10 -0
- package/PropertySheets/External/Microsoft.ReactNative.Uwp.CppLib.props +10 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/ReactCommon/ReactCommon.vcxproj +10 -10
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/Instance.cpp +379 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSExecutor.cpp +47 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/JSIndexedRAMBundle.cpp +143 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/MethodCall.cpp +98 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/ModuleRegistry.cpp +254 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/NativeToJsBridge.cpp +9 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/RAMBundleRegistry.cpp +91 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/cxxreact/ReactMarker.cpp +147 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsiexecutor/jsireact/JSIExecutor.cpp +622 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/jsiexecutor/jsireact/JSINativeModules.cpp +121 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/webperformance/NativePerformance.cpp +409 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/BaseViewProps.cpp +628 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/core/EventDispatcher.cpp +79 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/core/EventQueueProcessor.cpp +138 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/uimanager/UIManager.cpp +732 -0
- package/ReactCommon/TEMP_UntilReactCommonUpdate/react/runtime/ReactInstance.cpp +687 -0
- package/Shared/Shared.vcxitems +9 -9
- package/package.json +1 -1
- package/templates/cpp-app/windows/MyApp/MyApp.vcxproj +2 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#if _MSC_VER
|
|
9
|
+
#pragma warning(push)
|
|
10
|
+
#pragma warning(disable : 4996) // deprecated APIs
|
|
11
|
+
#endif
|
|
12
|
+
#include "jsireact/JSINativeModules.h"
|
|
13
|
+
|
|
14
|
+
#ifndef RCT_FIT_RM_OLD_RUNTIME
|
|
15
|
+
|
|
16
|
+
#include <reactperflogger/BridgeNativeModulePerfLogger.h>
|
|
17
|
+
|
|
18
|
+
#include <glog/logging.h>
|
|
19
|
+
|
|
20
|
+
#include <cxxreact/ReactMarker.h>
|
|
21
|
+
|
|
22
|
+
#include <jsi/JSIDynamic.h>
|
|
23
|
+
|
|
24
|
+
#include <string>
|
|
25
|
+
|
|
26
|
+
using namespace facebook::jsi;
|
|
27
|
+
|
|
28
|
+
namespace facebook::react {
|
|
29
|
+
|
|
30
|
+
JSINativeModules::JSINativeModules(
|
|
31
|
+
std::shared_ptr<ModuleRegistry> moduleRegistry)
|
|
32
|
+
: m_moduleRegistry(std::move(moduleRegistry)) {}
|
|
33
|
+
|
|
34
|
+
Value JSINativeModules::getModule(Runtime& rt, const PropNameID& name) {
|
|
35
|
+
if (!m_moduleRegistry) {
|
|
36
|
+
return nullptr;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
std::string moduleName = name.utf8(rt);
|
|
40
|
+
|
|
41
|
+
BridgeNativeModulePerfLogger::moduleJSRequireBeginningStart(
|
|
42
|
+
moduleName.c_str());
|
|
43
|
+
|
|
44
|
+
const auto it = m_objects.find(moduleName);
|
|
45
|
+
if (it != m_objects.end()) {
|
|
46
|
+
BridgeNativeModulePerfLogger::moduleJSRequireBeginningCacheHit(
|
|
47
|
+
moduleName.c_str());
|
|
48
|
+
BridgeNativeModulePerfLogger::moduleJSRequireBeginningEnd(
|
|
49
|
+
moduleName.c_str());
|
|
50
|
+
return Value(rt, it->second);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
auto module = createModule(rt, moduleName);
|
|
54
|
+
if (!module.has_value()) {
|
|
55
|
+
BridgeNativeModulePerfLogger::moduleJSRequireEndingFail(moduleName.c_str());
|
|
56
|
+
// Allow lookup to continue in the objects own properties, which allows for
|
|
57
|
+
// overrides of NativeModules
|
|
58
|
+
return nullptr;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
auto result =
|
|
62
|
+
m_objects.emplace(std::move(moduleName), std::move(*module)).first;
|
|
63
|
+
|
|
64
|
+
Value ret = Value(rt, result->second);
|
|
65
|
+
BridgeNativeModulePerfLogger::moduleJSRequireEndingEnd(moduleName.c_str());
|
|
66
|
+
return ret;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
void JSINativeModules::reset() {
|
|
70
|
+
m_genNativeModuleJS = std::nullopt;
|
|
71
|
+
m_objects.clear();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
std::optional<Object> JSINativeModules::createModule(
|
|
75
|
+
Runtime& rt,
|
|
76
|
+
const std::string& name) {
|
|
77
|
+
bool hasLogger = false;
|
|
78
|
+
{
|
|
79
|
+
std::shared_lock lock(ReactMarker::logTaggedMarkerImplMutex);
|
|
80
|
+
hasLogger = ReactMarker::logTaggedMarkerImpl != nullptr;
|
|
81
|
+
}
|
|
82
|
+
if (hasLogger) {
|
|
83
|
+
ReactMarker::logTaggedMarker(
|
|
84
|
+
ReactMarker::NATIVE_MODULE_SETUP_START, name.c_str());
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
auto result = m_moduleRegistry->getConfig(name);
|
|
88
|
+
if (!result.has_value()) {
|
|
89
|
+
return std::nullopt;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (!m_genNativeModuleJS) {
|
|
93
|
+
m_genNativeModuleJS =
|
|
94
|
+
rt.global().getPropertyAsFunction(rt, "__fbGenNativeModule");
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
Value moduleInfo = m_genNativeModuleJS->call(
|
|
98
|
+
rt,
|
|
99
|
+
valueFromDynamic(rt, result->config),
|
|
100
|
+
static_cast<double>(result->index));
|
|
101
|
+
CHECK(!moduleInfo.isNull()) << "Module returned from genNativeModule is null";
|
|
102
|
+
CHECK(moduleInfo.isObject())
|
|
103
|
+
<< "Module returned from genNativeModule isn't an Object";
|
|
104
|
+
|
|
105
|
+
std::optional<Object> module(
|
|
106
|
+
moduleInfo.asObject(rt).getPropertyAsObject(rt, "module"));
|
|
107
|
+
|
|
108
|
+
if (hasLogger) {
|
|
109
|
+
ReactMarker::logTaggedMarker(
|
|
110
|
+
ReactMarker::NATIVE_MODULE_SETUP_STOP, name.c_str());
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return module;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
} // namespace facebook::react
|
|
117
|
+
|
|
118
|
+
#endif // RCT_FIT_RM_OLD_RUNTIME
|
|
119
|
+
#if _MSC_VER
|
|
120
|
+
#pragma warning(pop)
|
|
121
|
+
#endif
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#if _MSC_VER
|
|
9
|
+
#pragma warning(push)
|
|
10
|
+
#pragma warning(disable : 4996) // deprecated APIs
|
|
11
|
+
#endif
|
|
12
|
+
#include "NativePerformance.h"
|
|
13
|
+
|
|
14
|
+
#include <memory>
|
|
15
|
+
#include <unordered_map>
|
|
16
|
+
#include <variant>
|
|
17
|
+
|
|
18
|
+
#include <cxxreact/JSExecutor.h>
|
|
19
|
+
#include <cxxreact/ReactMarker.h>
|
|
20
|
+
#include <jsi/JSIDynamic.h>
|
|
21
|
+
#include <jsi/instrumentation.h>
|
|
22
|
+
#include <react/performance/timeline/PerformanceEntryReporter.h>
|
|
23
|
+
#include <react/performance/timeline/PerformanceObserver.h>
|
|
24
|
+
|
|
25
|
+
#include "NativePerformance.h"
|
|
26
|
+
|
|
27
|
+
#ifdef RN_DISABLE_OSS_PLUGIN_HEADER
|
|
28
|
+
#include "Plugins.h"
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
std::shared_ptr<facebook::react::TurboModule> NativePerformanceModuleProvider(
|
|
32
|
+
std::shared_ptr<facebook::react::CallInvoker> jsInvoker) {
|
|
33
|
+
return std::make_shared<facebook::react::NativePerformance>(
|
|
34
|
+
std::move(jsInvoker));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
namespace facebook::react {
|
|
38
|
+
|
|
39
|
+
namespace {
|
|
40
|
+
|
|
41
|
+
class PerformanceObserverWrapper : public jsi::NativeState {
|
|
42
|
+
public:
|
|
43
|
+
explicit PerformanceObserverWrapper(
|
|
44
|
+
const std::shared_ptr<PerformanceObserver> observer)
|
|
45
|
+
: observer(observer) {}
|
|
46
|
+
|
|
47
|
+
const std::shared_ptr<PerformanceObserver> observer;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
void sortEntries(std::vector<PerformanceEntry>& entries) {
|
|
51
|
+
return std::stable_sort(
|
|
52
|
+
entries.begin(), entries.end(), PerformanceEntrySorter{});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
NativePerformanceEntry toNativePerformanceEntry(const PerformanceEntry& entry) {
|
|
56
|
+
auto nativeEntry = std::visit(
|
|
57
|
+
[](const auto& entryData) -> NativePerformanceEntry {
|
|
58
|
+
return {
|
|
59
|
+
.name = entryData.name,
|
|
60
|
+
.entryType = entryData.entryType,
|
|
61
|
+
.startTime = entryData.startTime,
|
|
62
|
+
.duration = entryData.duration,
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
entry);
|
|
66
|
+
|
|
67
|
+
if (std::holds_alternative<PerformanceEventTiming>(entry)) {
|
|
68
|
+
auto eventEntry = std::get<PerformanceEventTiming>(entry);
|
|
69
|
+
nativeEntry.processingStart = eventEntry.processingStart;
|
|
70
|
+
nativeEntry.processingEnd = eventEntry.processingEnd;
|
|
71
|
+
nativeEntry.interactionId = eventEntry.interactionId;
|
|
72
|
+
}
|
|
73
|
+
if (std::holds_alternative<PerformanceResourceTiming>(entry)) {
|
|
74
|
+
auto resourceEntry = std::get<PerformanceResourceTiming>(entry);
|
|
75
|
+
nativeEntry.fetchStart = resourceEntry.fetchStart;
|
|
76
|
+
nativeEntry.requestStart = resourceEntry.requestStart;
|
|
77
|
+
nativeEntry.connectStart = resourceEntry.connectStart;
|
|
78
|
+
nativeEntry.connectEnd = resourceEntry.connectEnd;
|
|
79
|
+
nativeEntry.responseStart = resourceEntry.responseStart;
|
|
80
|
+
nativeEntry.responseEnd = resourceEntry.responseEnd;
|
|
81
|
+
nativeEntry.responseStatus = resourceEntry.responseStatus;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return nativeEntry;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
std::vector<NativePerformanceEntry> toNativePerformanceEntries(
|
|
88
|
+
std::vector<PerformanceEntry>& entries) {
|
|
89
|
+
std::vector<NativePerformanceEntry> result;
|
|
90
|
+
result.reserve(entries.size());
|
|
91
|
+
|
|
92
|
+
for (auto& entry : entries) {
|
|
93
|
+
result.emplace_back(toNativePerformanceEntry(entry));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const std::array<PerformanceEntryType, 2> ENTRY_TYPES_AVAILABLE_FROM_TIMELINE{
|
|
100
|
+
{PerformanceEntryType::MARK, PerformanceEntryType::MEASURE}};
|
|
101
|
+
|
|
102
|
+
bool isAvailableFromTimeline(PerformanceEntryType entryType) {
|
|
103
|
+
return entryType == PerformanceEntryType::MARK ||
|
|
104
|
+
entryType == PerformanceEntryType::MEASURE;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
std::shared_ptr<PerformanceObserver> tryGetObserver(
|
|
108
|
+
jsi::Runtime& rt,
|
|
109
|
+
jsi::Object& observerObj) {
|
|
110
|
+
if (!observerObj.hasNativeState(rt)) {
|
|
111
|
+
return nullptr;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
auto observerWrapper = std::dynamic_pointer_cast<PerformanceObserverWrapper>(
|
|
115
|
+
observerObj.getNativeState(rt));
|
|
116
|
+
return observerWrapper ? observerWrapper->observer : nullptr;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
PerformanceEntryReporter::UserTimingDetailProvider getDetailProviderFromEntry(
|
|
120
|
+
jsi::Runtime& rt,
|
|
121
|
+
jsi::Value& entry) {
|
|
122
|
+
return [&rt, &entry]() -> folly::dynamic {
|
|
123
|
+
try {
|
|
124
|
+
auto detail = entry.asObject(rt).getProperty(rt, "detail");
|
|
125
|
+
return jsi::dynamicFromValue(rt, detail);
|
|
126
|
+
} catch (jsi::JSIException&) {
|
|
127
|
+
return nullptr;
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
} // namespace
|
|
133
|
+
|
|
134
|
+
NativePerformance::NativePerformance(std::shared_ptr<CallInvoker> jsInvoker)
|
|
135
|
+
: NativePerformanceCxxSpec(std::move(jsInvoker)) {}
|
|
136
|
+
|
|
137
|
+
HighResTimeStamp NativePerformance::now(jsi::Runtime& /*rt*/) {
|
|
138
|
+
// This is not spec-compliant, as this is the duration from system boot to
|
|
139
|
+
// now, instead of from app startup to now.
|
|
140
|
+
// This should be carefully changed eventually.
|
|
141
|
+
return HighResTimeStamp::now();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
HighResDuration NativePerformance::timeOrigin(jsi::Runtime& /*rt*/) {
|
|
145
|
+
// This is not spec-compliant, as this is an approximation from Unix epoch to
|
|
146
|
+
// system boot, instead of a precise duration from Unix epoch to app startup.
|
|
147
|
+
return HighResTimeStamp::unsafeOriginFromUnixTimeStamp();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
void NativePerformance::reportMark(
|
|
151
|
+
jsi::Runtime& rt,
|
|
152
|
+
const std::string& name,
|
|
153
|
+
HighResTimeStamp startTime,
|
|
154
|
+
jsi::Value entry) {
|
|
155
|
+
PerformanceEntryReporter::getInstance()->reportMark(
|
|
156
|
+
name, startTime, getDetailProviderFromEntry(rt, entry));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
void NativePerformance::reportMeasure(
|
|
160
|
+
jsi::Runtime& rt,
|
|
161
|
+
const std::string& name,
|
|
162
|
+
HighResTimeStamp startTime,
|
|
163
|
+
HighResDuration duration,
|
|
164
|
+
jsi::Value entry) {
|
|
165
|
+
PerformanceEntryReporter::getInstance()->reportMeasure(
|
|
166
|
+
name, startTime, duration, getDetailProviderFromEntry(rt, entry));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
std::optional<double> NativePerformance::getMarkTime(
|
|
170
|
+
jsi::Runtime& /*rt*/,
|
|
171
|
+
const std::string& name) {
|
|
172
|
+
auto markTime = PerformanceEntryReporter::getInstance()->getMarkTime(name);
|
|
173
|
+
return markTime ? std::optional{(*markTime).toDOMHighResTimeStamp()}
|
|
174
|
+
: std::nullopt;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
void NativePerformance::clearMarks(
|
|
178
|
+
jsi::Runtime& /*rt*/,
|
|
179
|
+
std::optional<std::string> entryName) {
|
|
180
|
+
if (entryName) {
|
|
181
|
+
PerformanceEntryReporter::getInstance()->clearEntries(
|
|
182
|
+
PerformanceEntryType::MARK, *entryName);
|
|
183
|
+
} else {
|
|
184
|
+
PerformanceEntryReporter::getInstance()->clearEntries(
|
|
185
|
+
PerformanceEntryType::MARK);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
void NativePerformance::clearMeasures(
|
|
190
|
+
jsi::Runtime& /*rt*/,
|
|
191
|
+
std::optional<std::string> entryName) {
|
|
192
|
+
if (entryName) {
|
|
193
|
+
PerformanceEntryReporter::getInstance()->clearEntries(
|
|
194
|
+
PerformanceEntryType::MEASURE, *entryName);
|
|
195
|
+
} else {
|
|
196
|
+
PerformanceEntryReporter::getInstance()->clearEntries(
|
|
197
|
+
PerformanceEntryType::MEASURE);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
std::vector<NativePerformanceEntry> NativePerformance::getEntries(
|
|
202
|
+
jsi::Runtime& /*rt*/) {
|
|
203
|
+
std::vector<PerformanceEntry> entries;
|
|
204
|
+
|
|
205
|
+
for (auto entryType : ENTRY_TYPES_AVAILABLE_FROM_TIMELINE) {
|
|
206
|
+
PerformanceEntryReporter::getInstance()->getEntries(entries, entryType);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
sortEntries(entries);
|
|
210
|
+
|
|
211
|
+
return toNativePerformanceEntries(entries);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
std::vector<NativePerformanceEntry> NativePerformance::getEntriesByName(
|
|
215
|
+
jsi::Runtime& /*rt*/,
|
|
216
|
+
const std::string& entryName,
|
|
217
|
+
std::optional<PerformanceEntryType> entryType) {
|
|
218
|
+
std::vector<PerformanceEntry> entries;
|
|
219
|
+
|
|
220
|
+
if (entryType) {
|
|
221
|
+
if (isAvailableFromTimeline(*entryType)) {
|
|
222
|
+
PerformanceEntryReporter::getInstance()->getEntries(
|
|
223
|
+
entries, *entryType, entryName);
|
|
224
|
+
}
|
|
225
|
+
} else {
|
|
226
|
+
for (auto type : ENTRY_TYPES_AVAILABLE_FROM_TIMELINE) {
|
|
227
|
+
PerformanceEntryReporter::getInstance()->getEntries(
|
|
228
|
+
entries, type, entryName);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
sortEntries(entries);
|
|
233
|
+
|
|
234
|
+
return toNativePerformanceEntries(entries);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
std::vector<NativePerformanceEntry> NativePerformance::getEntriesByType(
|
|
238
|
+
jsi::Runtime& /*rt*/,
|
|
239
|
+
PerformanceEntryType entryType) {
|
|
240
|
+
std::vector<PerformanceEntry> entries;
|
|
241
|
+
|
|
242
|
+
if (isAvailableFromTimeline(entryType)) {
|
|
243
|
+
PerformanceEntryReporter::getInstance()->getEntries(entries, entryType);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
sortEntries(entries);
|
|
247
|
+
|
|
248
|
+
return toNativePerformanceEntries(entries);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
std::vector<std::pair<std::string, uint32_t>> NativePerformance::getEventCounts(
|
|
252
|
+
jsi::Runtime& /*rt*/) {
|
|
253
|
+
const auto& eventCounts =
|
|
254
|
+
PerformanceEntryReporter::getInstance()->getEventCounts();
|
|
255
|
+
return {eventCounts.begin(), eventCounts.end()};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
std::unordered_map<std::string, double> NativePerformance::getSimpleMemoryInfo(
|
|
259
|
+
jsi::Runtime& rt) {
|
|
260
|
+
auto heapInfo = rt.instrumentation().getHeapInfo(false);
|
|
261
|
+
std::unordered_map<std::string, double> heapInfoToJs;
|
|
262
|
+
for (auto& entry : heapInfo) {
|
|
263
|
+
heapInfoToJs[entry.first] = static_cast<double>(entry.second);
|
|
264
|
+
}
|
|
265
|
+
return heapInfoToJs;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
std::unordered_map<std::string, double>
|
|
269
|
+
NativePerformance::getReactNativeStartupTiming(jsi::Runtime& /*rt*/) {
|
|
270
|
+
std::unordered_map<std::string, double> result;
|
|
271
|
+
|
|
272
|
+
ReactMarker::StartupLogger& startupLogger =
|
|
273
|
+
ReactMarker::StartupLogger::getInstance();
|
|
274
|
+
if (!std::isnan(startupLogger.getAppStartupStartTime())) {
|
|
275
|
+
result["startTime"] = startupLogger.getAppStartupStartTime();
|
|
276
|
+
} else if (!std::isnan(startupLogger.getInitReactRuntimeStartTime())) {
|
|
277
|
+
result["startTime"] = startupLogger.getInitReactRuntimeStartTime();
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (!std::isnan(startupLogger.getInitReactRuntimeStartTime())) {
|
|
281
|
+
result["initializeRuntimeStart"] =
|
|
282
|
+
startupLogger.getInitReactRuntimeStartTime();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (!std::isnan(startupLogger.getRunJSBundleStartTime())) {
|
|
286
|
+
result["executeJavaScriptBundleEntryPointStart"] =
|
|
287
|
+
startupLogger.getRunJSBundleStartTime();
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (!std::isnan(startupLogger.getAppStartupEndTime())) {
|
|
291
|
+
result["endTime"] = startupLogger.getAppStartupEndTime();
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
jsi::Object NativePerformance::createObserver(
|
|
298
|
+
jsi::Runtime& rt,
|
|
299
|
+
NativePerformancePerformanceObserverCallback callback) {
|
|
300
|
+
// The way we dispatch performance observer callbacks is a bit different from
|
|
301
|
+
// the spec. The specification requires us to queue a single task that
|
|
302
|
+
// dispatches observer callbacks. Instead, we are queuing all callbacks as
|
|
303
|
+
// separate tasks in the scheduler.
|
|
304
|
+
PerformanceObserverCallback cb = [callback = std::move(callback)]() {
|
|
305
|
+
callback.callWithPriority(SchedulerPriority::IdlePriority);
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
auto& registry =
|
|
309
|
+
PerformanceEntryReporter::getInstance()->getObserverRegistry();
|
|
310
|
+
|
|
311
|
+
auto observer = PerformanceObserver::create(registry, std::move(cb));
|
|
312
|
+
auto observerWrapper = std::make_shared<PerformanceObserverWrapper>(observer);
|
|
313
|
+
jsi::Object observerObj{rt};
|
|
314
|
+
observerObj.setNativeState(rt, observerWrapper);
|
|
315
|
+
return observerObj;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
double NativePerformance::getDroppedEntriesCount(
|
|
319
|
+
jsi::Runtime& rt,
|
|
320
|
+
jsi::Object observerObj) {
|
|
321
|
+
auto observer = tryGetObserver(rt, observerObj);
|
|
322
|
+
|
|
323
|
+
if (!observer) {
|
|
324
|
+
return 0;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
return observer->getDroppedEntriesCount();
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
void NativePerformance::observe(
|
|
331
|
+
jsi::Runtime& rt,
|
|
332
|
+
jsi::Object observerObj,
|
|
333
|
+
NativePerformancePerformanceObserverObserveOptions options) {
|
|
334
|
+
auto observer = tryGetObserver(rt, observerObj);
|
|
335
|
+
|
|
336
|
+
if (!observer) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
auto durationThreshold =
|
|
341
|
+
options.durationThreshold.value_or(HighResDuration::zero());
|
|
342
|
+
|
|
343
|
+
// observer of type multiple
|
|
344
|
+
if (options.entryTypes.has_value()) {
|
|
345
|
+
std::unordered_set<PerformanceEntryType> entryTypes;
|
|
346
|
+
auto rawTypes = options.entryTypes.value();
|
|
347
|
+
|
|
348
|
+
for (auto rawType : rawTypes) {
|
|
349
|
+
entryTypes.insert(Bridging<PerformanceEntryType>::fromJs(rt, rawType));
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
observer->observe(entryTypes);
|
|
353
|
+
} else { // single
|
|
354
|
+
auto buffered = options.buffered.value_or(false);
|
|
355
|
+
if (options.type.has_value()) {
|
|
356
|
+
observer->observe(
|
|
357
|
+
static_cast<PerformanceEntryType>(options.type.value()),
|
|
358
|
+
{.buffered = buffered, .durationThreshold = durationThreshold});
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
void NativePerformance::disconnect(jsi::Runtime& rt, jsi::Object observerObj) {
|
|
364
|
+
auto observerWrapper = std::dynamic_pointer_cast<PerformanceObserverWrapper>(
|
|
365
|
+
observerObj.getNativeState(rt));
|
|
366
|
+
|
|
367
|
+
if (!observerWrapper) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
auto observer = observerWrapper->observer;
|
|
372
|
+
observer->disconnect();
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
std::vector<NativePerformanceEntry> NativePerformance::takeRecords(
|
|
376
|
+
jsi::Runtime& rt,
|
|
377
|
+
jsi::Object observerObj,
|
|
378
|
+
bool sort) {
|
|
379
|
+
auto observerWrapper = std::dynamic_pointer_cast<PerformanceObserverWrapper>(
|
|
380
|
+
observerObj.getNativeState(rt));
|
|
381
|
+
|
|
382
|
+
if (!observerWrapper) {
|
|
383
|
+
return {};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
auto observer = observerWrapper->observer;
|
|
387
|
+
auto records = observer->takeRecords();
|
|
388
|
+
if (sort) {
|
|
389
|
+
sortEntries(records);
|
|
390
|
+
}
|
|
391
|
+
return toNativePerformanceEntries(records);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
std::vector<PerformanceEntryType>
|
|
395
|
+
NativePerformance::getSupportedPerformanceEntryTypes(jsi::Runtime& /*rt*/) {
|
|
396
|
+
auto supportedEntryTypes = PerformanceEntryReporter::getSupportedEntryTypes();
|
|
397
|
+
return {supportedEntryTypes.begin(), supportedEntryTypes.end()};
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
#pragma mark - Testing
|
|
401
|
+
|
|
402
|
+
void NativePerformance::clearEventCountsForTesting(jsi::Runtime& /*rt*/) {
|
|
403
|
+
PerformanceEntryReporter::getInstance()->clearEventCounts();
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
} // namespace facebook::react
|
|
407
|
+
#if _MSC_VER
|
|
408
|
+
#pragma warning(pop)
|
|
409
|
+
#endif
|