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
This commit is contained in:
Ramanpreet Nara 2020-05-20 20:14:31 -07:00 коммит произвёл Facebook GitHub Bot
Родитель c75e8ae4ff
Коммит 4830085f40
16 изменённых файлов: 956 добавлений и 304 удалений

Просмотреть файл

@ -11,7 +11,7 @@
#import <atomic>
#import <mutex>
#import <reactperflogger/NativeModulePerfLogger.h>
#import <reactperflogger/BridgeNativeModulePerfLogger.h>
#import "RCTBridge+Private.h"
#import "RCTBridge.h"
@ -142,9 +142,9 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init);
}
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"[RCTModuleData setUpInstanceAndBridge] Create module", nil);
NativeModulePerfLogger::getInstance().moduleCreateConstructStart([moduleName UTF8String], requestId);
BridgeNativeModulePerfLogger::moduleCreateConstructStart([moduleName UTF8String], requestId);
_instance = _moduleProvider ? _moduleProvider() : nil;
NativeModulePerfLogger::getInstance().moduleCreateConstructEnd([moduleName UTF8String], requestId);
BridgeNativeModulePerfLogger::moduleCreateConstructEnd([moduleName UTF8String], requestId);
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
if (!_instance) {
@ -166,7 +166,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init);
}
if (_instance) {
NativeModulePerfLogger::getInstance().moduleCreateSetUpStart([moduleName UTF8String], requestId);
BridgeNativeModulePerfLogger::moduleCreateSetUpStart([moduleName UTF8String], requestId);
}
if (shouldSetup) {
@ -199,7 +199,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init);
}
if (_instance) {
NativeModulePerfLogger::getInstance().moduleCreateSetUpEnd([moduleName UTF8String], requestId);
BridgeNativeModulePerfLogger::moduleCreateSetUpEnd([moduleName UTF8String], requestId);
}
}
@ -318,7 +318,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init);
{
NSString *moduleName = [self name];
int32_t requestId = getUniqueId();
NativeModulePerfLogger::getInstance().moduleCreateStart([moduleName UTF8String], requestId);
BridgeNativeModulePerfLogger::moduleCreateStart([moduleName UTF8String], requestId);
if (!_setupComplete) {
RCT_PROFILE_BEGIN_EVENT(
@ -343,13 +343,13 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init);
}
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
} else {
NativeModulePerfLogger::getInstance().moduleCreateCacheHit([moduleName UTF8String], requestId);
BridgeNativeModulePerfLogger::moduleCreateCacheHit([moduleName UTF8String], requestId);
}
if (_instance) {
NativeModulePerfLogger::getInstance().moduleCreateEnd([moduleName UTF8String], requestId);
BridgeNativeModulePerfLogger::moduleCreateEnd([moduleName UTF8String], requestId);
} else {
NativeModulePerfLogger::getInstance().moduleCreateFail([moduleName UTF8String], requestId);
BridgeNativeModulePerfLogger::moduleCreateFail([moduleName UTF8String], requestId);
}
return _instance;
}
@ -388,7 +388,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init);
* - Therefore, this is the first statement that executes after the NativeModule is created/initialized in a JS
* require.
*/
NativeModulePerfLogger::getInstance().moduleJSRequireEndingStart([moduleName UTF8String]);
BridgeNativeModulePerfLogger::moduleJSRequireEndingStart([moduleName UTF8String]);
if (_requiresMainQueueSetup) {
if (!RCTIsMainQueue()) {
RCTLogWarn(@"Required dispatch_sync to load constants for %@. This may lead to deadlocks", _moduleClass);
@ -406,7 +406,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init);
* If a NativeModule doesn't have constants, it isn't eagerly loaded until its methods are first invoked.
* Therefore, we should immediately start JSRequireEnding
*/
NativeModulePerfLogger::getInstance().moduleJSRequireEndingStart([moduleName UTF8String]);
BridgeNativeModulePerfLogger::moduleJSRequireEndingStart([moduleName UTF8String]);
}
}

Просмотреть файл

@ -35,7 +35,7 @@
#import <cxxreact/RAMBundleRegistry.h>
#import <cxxreact/ReactMarker.h>
#import <jsireact/JSIExecutor.h>
#import <reactperflogger/NativeModulePerfLogger.h>
#import <reactperflogger/BridgeNativeModulePerfLogger.h>
#import "JSCExecutorFactory.h"
#import "NSDataBigString.h"
@ -661,9 +661,9 @@ struct RCTInstanceCallback : public InstanceCallback {
// Instantiate moduleData
// TODO #13258411: can we defer this until config generation?
int32_t moduleDataId = getUniqueId();
NativeModulePerfLogger::getInstance().moduleDataCreateStart([moduleName UTF8String], moduleDataId);
BridgeNativeModulePerfLogger::moduleDataCreateStart([moduleName UTF8String], moduleDataId);
moduleData = [[RCTModuleData alloc] initWithModuleClass:moduleClass bridge:self];
NativeModulePerfLogger::getInstance().moduleDataCreateEnd([moduleName UTF8String], moduleDataId);
BridgeNativeModulePerfLogger::moduleDataCreateEnd([moduleName UTF8String], moduleDataId);
_moduleDataByName[moduleName] = moduleData;
[_moduleClassesByID addObject:moduleClass];
@ -724,9 +724,9 @@ struct RCTInstanceCallback : public InstanceCallback {
// Instantiate moduleData container
int32_t moduleDataId = getUniqueId();
NativeModulePerfLogger::getInstance().moduleDataCreateStart([moduleName UTF8String], moduleDataId);
BridgeNativeModulePerfLogger::moduleDataCreateStart([moduleName UTF8String], moduleDataId);
RCTModuleData *moduleData = [[RCTModuleData alloc] initWithModuleInstance:module bridge:self];
NativeModulePerfLogger::getInstance().moduleDataCreateEnd([moduleName UTF8String], moduleDataId);
BridgeNativeModulePerfLogger::moduleDataCreateEnd([moduleName UTF8String], moduleDataId);
_moduleDataByName[moduleName] = moduleData;
[_moduleClassesByID addObject:moduleClass];
@ -775,9 +775,9 @@ struct RCTInstanceCallback : public InstanceCallback {
}
int32_t moduleDataId = getUniqueId();
NativeModulePerfLogger::getInstance().moduleDataCreateStart([moduleName UTF8String], moduleDataId);
BridgeNativeModulePerfLogger::moduleDataCreateStart([moduleName UTF8String], moduleDataId);
moduleData = [[RCTModuleData alloc] initWithModuleClass:moduleClass bridge:self];
NativeModulePerfLogger::getInstance().moduleDataCreateEnd([moduleName UTF8String], moduleDataId);
BridgeNativeModulePerfLogger::moduleDataCreateEnd([moduleName UTF8String], moduleDataId);
_moduleDataByName[moduleName] = moduleData;
[_moduleClassesByID addObject:moduleClass];

Просмотреть файл

@ -15,7 +15,7 @@
#import <React/RCTLog.h>
#import <React/RCTProfile.h>
#import <React/RCTUtils.h>
#import <reactperflogger/NativeModulePerfLogger.h>
#import <reactperflogger/BridgeNativeModulePerfLogger.h>
#ifdef WITH_FBSYSTRACE
#include <fbsystrace.h>
@ -80,10 +80,10 @@ void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &&params, int
const bool isSyncModule = queue == RCTJSThread;
if (isSyncModule) {
NativeModulePerfLogger::getInstance().syncMethodCallStart(moduleName, methodName);
NativeModulePerfLogger::getInstance().syncMethodCallArgConversionStart(moduleName, methodName);
BridgeNativeModulePerfLogger::syncMethodCallStart(moduleName, methodName);
BridgeNativeModulePerfLogger::syncMethodCallArgConversionStart(moduleName, methodName);
} else {
NativeModulePerfLogger::getInstance().asyncMethodCallStart(moduleName, methodName);
BridgeNativeModulePerfLogger::asyncMethodCallStart(moduleName, methodName);
}
// capture by weak pointer so that we can safely use these variables in a callback
@ -105,9 +105,9 @@ void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &&params, int
if (isSyncModule) {
block();
NativeModulePerfLogger::getInstance().syncMethodCallReturnConversionEnd(moduleName, methodName);
BridgeNativeModulePerfLogger::syncMethodCallReturnConversionEnd(moduleName, methodName);
} else if (queue) {
NativeModulePerfLogger::getInstance().asyncMethodCallDispatch(moduleName, methodName);
BridgeNativeModulePerfLogger::asyncMethodCallDispatch(moduleName, methodName);
dispatch_async(queue, block);
}
@ -121,9 +121,9 @@ void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &&params, int
#endif
if (isSyncModule) {
NativeModulePerfLogger::getInstance().syncMethodCallEnd(moduleName, methodName);
BridgeNativeModulePerfLogger::syncMethodCallEnd(moduleName, methodName);
} else {
NativeModulePerfLogger::getInstance().asyncMethodCallEnd(moduleName, methodName);
BridgeNativeModulePerfLogger::asyncMethodCallEnd(moduleName, methodName);
}
}
@ -147,7 +147,7 @@ static MethodCallResult invokeInner(
* call at a time, and when we call syncMethodCallFail, that one call should terminate. This is also an
* exceptional scenario, so it shouldn't occur often.
*/
NativeModulePerfLogger::getInstance().syncMethodCallFail("N/A", "N/A");
BridgeNativeModulePerfLogger::syncMethodCallFail("N/A", "N/A");
}
return folly::none;
}
@ -161,40 +161,38 @@ static MethodCallResult invokeInner(
const char *methodName = moduleData.methods[methodId].JSMethodName;
if (context == Async) {
NativeModulePerfLogger::getInstance().asyncMethodCallExecutionStart(moduleName, methodName, (int32_t)callId);
NativeModulePerfLogger::getInstance().asyncMethodCallExecutionArgConversionStart(
moduleName, methodName, (int32_t)callId);
BridgeNativeModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodName, (int32_t)callId);
BridgeNativeModulePerfLogger::asyncMethodCallExecutionArgConversionStart(moduleName, methodName, (int32_t)callId);
}
NSArray *objcParams = convertFollyDynamicToId(params);
if (context == Sync) {
NativeModulePerfLogger::getInstance().syncMethodCallArgConversionEnd(moduleName, methodName);
BridgeNativeModulePerfLogger::syncMethodCallArgConversionEnd(moduleName, methodName);
}
@try {
if (context == Sync) {
NativeModulePerfLogger::getInstance().syncMethodCallExecutionStart(moduleName, methodName);
BridgeNativeModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
} else {
NativeModulePerfLogger::getInstance().asyncMethodCallExecutionArgConversionEnd(
moduleName, methodName, (int32_t)callId);
BridgeNativeModulePerfLogger::asyncMethodCallExecutionArgConversionEnd(moduleName, methodName, (int32_t)callId);
}
id result = [method invokeWithBridge:bridge module:moduleData.instance arguments:objcParams];
if (context == Sync) {
NativeModulePerfLogger::getInstance().syncMethodCallExecutionEnd(moduleName, methodName);
NativeModulePerfLogger::getInstance().syncMethodCallReturnConversionStart(moduleName, methodName);
BridgeNativeModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodName);
BridgeNativeModulePerfLogger::syncMethodCallReturnConversionStart(moduleName, methodName);
} else {
NativeModulePerfLogger::getInstance().asyncMethodCallExecutionEnd(moduleName, methodName, (int32_t)callId);
BridgeNativeModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodName, (int32_t)callId);
}
return convertIdToFollyDynamic(result);
} @catch (NSException *exception) {
if (context == Sync) {
NativeModulePerfLogger::getInstance().syncMethodCallFail(moduleName, methodName);
BridgeNativeModulePerfLogger::syncMethodCallFail(moduleName, methodName);
} else {
NativeModulePerfLogger::getInstance().asyncMethodCallExecutionFail(moduleName, methodName, (int32_t)callId);
BridgeNativeModulePerfLogger::asyncMethodCallExecutionFail(moduleName, methodName, (int32_t)callId);
}
// Pass on JS exceptions

Просмотреть файл

@ -8,7 +8,7 @@
#include "ModuleRegistry.h"
#include <glog/logging.h>
#include <reactperflogger/NativeModulePerfLogger.h>
#include <reactperflogger/BridgeNativeModulePerfLogger.h>
#include "NativeModule.h"
#include "SystraceSection.h"
@ -100,24 +100,19 @@ folly::Optional<ModuleConfig> ModuleRegistry::getConfig(
if (it == modulesByName_.end()) {
if (unknownModules_.find(name) != unknownModules_.end()) {
NativeModulePerfLogger::getInstance().moduleJSRequireBeginningFail(
name.c_str());
NativeModulePerfLogger::getInstance().moduleJSRequireEndingStart(
name.c_str());
BridgeNativeModulePerfLogger::moduleJSRequireBeginningFail(name.c_str());
BridgeNativeModulePerfLogger::moduleJSRequireEndingStart(name.c_str());
return folly::none;
}
if (!moduleNotFoundCallback_) {
unknownModules_.insert(name);
NativeModulePerfLogger::getInstance().moduleJSRequireBeginningFail(
name.c_str());
NativeModulePerfLogger::getInstance().moduleJSRequireEndingStart(
name.c_str());
BridgeNativeModulePerfLogger::moduleJSRequireBeginningFail(name.c_str());
BridgeNativeModulePerfLogger::moduleJSRequireEndingStart(name.c_str());
return folly::none;
}
NativeModulePerfLogger::getInstance().moduleJSRequireBeginningEnd(
name.c_str());
BridgeNativeModulePerfLogger::moduleJSRequireBeginningEnd(name.c_str());
bool wasModuleLazilyLoaded = moduleNotFoundCallback_(name);
it = modulesByName_.find(name);
@ -126,14 +121,12 @@ folly::Optional<ModuleConfig> ModuleRegistry::getConfig(
wasModuleLazilyLoaded && it != modulesByName_.end();
if (!wasModuleRegisteredWithRegistry) {
NativeModulePerfLogger::getInstance().moduleJSRequireEndingStart(
name.c_str());
BridgeNativeModulePerfLogger::moduleJSRequireEndingStart(name.c_str());
unknownModules_.insert(name);
return folly::none;
}
} else {
NativeModulePerfLogger::getInstance().moduleJSRequireBeginningEnd(
name.c_str());
BridgeNativeModulePerfLogger::moduleJSRequireBeginningEnd(name.c_str());
}
// If we've gotten this far, then we've signaled moduleJSRequireBeginningEnd

Просмотреть файл

@ -11,7 +11,7 @@
#include <folly/MoveWrapper.h>
#include <folly/json.h>
#include <glog/logging.h>
#include <reactperflogger/NativeModulePerfLogger.h>
#include <reactperflogger/BridgeNativeModulePerfLogger.h>
#include "Instance.h"
#include "JSBigString.h"
@ -57,7 +57,7 @@ class JsToNativeBridge : public react::ExecutorDelegate {
m_batchHadNativeModuleOrTurboModuleCalls || !calls.empty();
std::vector<MethodCall> methodCalls = parseMethodCalls(std::move(calls));
NativeModulePerfLogger::getInstance().asyncMethodCallBatchPreprocessEnd(
BridgeNativeModulePerfLogger::asyncMethodCallBatchPreprocessEnd(
(int)methodCalls.size());
// An exception anywhere in here stops processing of the batch. This

Просмотреть файл

@ -16,7 +16,7 @@
#include <glog/logging.h>
#include <jsi/JSIDynamic.h>
#include <jsi/instrumentation.h>
#include <reactperflogger/NativeModulePerfLogger.h>
#include <reactperflogger/BridgeNativeModulePerfLogger.h>
#include <sstream>
#include <stdexcept>
@ -385,7 +385,7 @@ void JSIExecutor::callNativeModules(const Value &queue, bool isEndOfBatch) {
.getPropertyAsFunction(*runtime_, "stringify").call(*runtime_, queue)
.getString(*runtime_).utf8(*runtime_);
#endif
NativeModulePerfLogger::getInstance().asyncMethodCallBatchPreprocessStart();
BridgeNativeModulePerfLogger::asyncMethodCallBatchPreprocessStart();
delegate_->callNativeModules(
*this, dynamicFromValue(*runtime_, queue), isEndOfBatch);
@ -453,10 +453,10 @@ Value JSIExecutor::nativeCallSyncHook(const Value *args, size_t count) {
moduleName = moduleRegistry_->getModuleName(moduleId);
methodName = moduleRegistry_->getModuleSyncMethodName(moduleId, methodId);
NativeModulePerfLogger::getInstance().syncMethodCallStart(
BridgeNativeModulePerfLogger::syncMethodCallStart(
moduleName.c_str(), methodName.c_str());
NativeModulePerfLogger::getInstance().syncMethodCallArgConversionStart(
BridgeNativeModulePerfLogger::syncMethodCallArgConversionStart(
moduleName.c_str(), methodName.c_str());
}
@ -485,9 +485,9 @@ Value JSIExecutor::nativeCallSyncHook(const Value *args, size_t count) {
Value returnValue = valueFromDynamic(*runtime_, result.value());
if (moduleRegistry_) {
NativeModulePerfLogger::getInstance().syncMethodCallReturnConversionEnd(
BridgeNativeModulePerfLogger::syncMethodCallReturnConversionEnd(
moduleName.c_str(), methodName.c_str());
NativeModulePerfLogger::getInstance().syncMethodCallEnd(
BridgeNativeModulePerfLogger::syncMethodCallEnd(
moduleName.c_str(), methodName.c_str());
}

Просмотреть файл

@ -6,7 +6,7 @@
*/
#include "jsireact/JSINativeModules.h"
#include <reactperflogger/NativeModulePerfLogger.h>
#include <reactperflogger/BridgeNativeModulePerfLogger.h>
#include <glog/logging.h>
@ -32,22 +32,21 @@ Value JSINativeModules::getModule(Runtime &rt, const PropNameID &name) {
std::string moduleName = name.utf8(rt);
NativeModulePerfLogger::getInstance().moduleJSRequireBeginningStart(
BridgeNativeModulePerfLogger::moduleJSRequireBeginningStart(
moduleName.c_str());
const auto it = m_objects.find(moduleName);
if (it != m_objects.end()) {
NativeModulePerfLogger::getInstance().moduleJSRequireBeginningCacheHit(
BridgeNativeModulePerfLogger::moduleJSRequireBeginningCacheHit(
moduleName.c_str());
NativeModulePerfLogger::getInstance().moduleJSRequireBeginningEnd(
BridgeNativeModulePerfLogger::moduleJSRequireBeginningEnd(
moduleName.c_str());
return Value(rt, it->second);
}
auto module = createModule(rt, moduleName);
if (!module.hasValue()) {
NativeModulePerfLogger::getInstance().moduleJSRequireEndingFail(
moduleName.c_str());
BridgeNativeModulePerfLogger::moduleJSRequireEndingFail(moduleName.c_str());
// Allow lookup to continue in the objects own properties, which allows for
// overrides of NativeModules
return nullptr;
@ -57,8 +56,7 @@ Value JSINativeModules::getModule(Runtime &rt, const PropNameID &name) {
m_objects.emplace(std::move(moduleName), std::move(*module)).first;
Value ret = Value(rt, result->second);
NativeModulePerfLogger::getInstance().moduleJSRequireEndingEnd(
moduleName.c_str());
BridgeNativeModulePerfLogger::moduleJSRequireEndingEnd(moduleName.c_str());
return ret;
}

Просмотреть файл

@ -5,6 +5,7 @@ rn_xplat_cxx_library(
srcs = glob(["**/*.cpp"]),
header_namespace = "",
exported_headers = {
"reactperflogger/BridgeNativeModulePerfLogger.h": "reactperflogger/BridgeNativeModulePerfLogger.h",
"reactperflogger/NativeModulePerfLogger.h": "reactperflogger/NativeModulePerfLogger.h",
},
compiler_flags = [

Просмотреть файл

@ -0,0 +1,320 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "BridgeNativeModulePerfLogger.h"
namespace facebook {
namespace react {
namespace BridgeNativeModulePerfLogger {
std::unique_ptr<NativeModulePerfLogger> g_perfLogger = nullptr;
void enableLogging(std::unique_ptr<NativeModulePerfLogger> &&newPerfLogger) {
g_perfLogger = std::move(newPerfLogger);
}
void moduleDataCreateStart(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleDataCreateStart(moduleName, id);
}
}
void moduleDataCreateEnd(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleDataCreateEnd(moduleName, id);
}
}
void moduleCreateStart(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateStart(moduleName, id);
}
}
void moduleCreateCacheHit(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateCacheHit(moduleName, id);
}
}
void moduleCreateConstructStart(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateConstructStart(moduleName, id);
}
}
void moduleCreateConstructEnd(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateConstructEnd(moduleName, id);
}
}
void moduleCreateSetUpStart(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateSetUpStart(moduleName, id);
}
}
void moduleCreateSetUpEnd(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateSetUpEnd(moduleName, id);
}
}
void moduleCreateEnd(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateEnd(moduleName, id);
}
}
void moduleCreateFail(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateFail(moduleName, id);
}
}
void moduleJSRequireBeginningStart(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireBeginningStart(moduleName);
}
}
void moduleJSRequireBeginningCacheHit(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireBeginningCacheHit(moduleName);
}
}
void moduleJSRequireBeginningEnd(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireBeginningEnd(moduleName);
}
}
void moduleJSRequireBeginningFail(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireBeginningFail(moduleName);
}
}
void moduleJSRequireEndingStart(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireEndingStart(moduleName);
}
}
void moduleJSRequireEndingEnd(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireEndingEnd(moduleName);
}
}
void moduleJSRequireEndingFail(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireEndingFail(moduleName);
}
}
void syncMethodCallStart(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallStart(moduleName, methodName);
}
}
void syncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallArgConversionStart(moduleName, methodName);
}
}
void syncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallArgConversionEnd(moduleName, methodName);
}
}
void syncMethodCallExecutionStart(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallExecutionStart(moduleName, methodName);
}
}
void syncMethodCallExecutionEnd(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallExecutionEnd(moduleName, methodName);
}
}
void syncMethodCallReturnConversionStart(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallReturnConversionStart(moduleName, methodName);
}
}
void syncMethodCallReturnConversionEnd(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallReturnConversionEnd(moduleName, methodName);
}
}
void syncMethodCallEnd(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallEnd(moduleName, methodName);
}
}
void syncMethodCallFail(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallFail(moduleName, methodName);
}
}
void asyncMethodCallStart(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallStart(moduleName, methodName);
}
}
void asyncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallArgConversionStart(moduleName, methodName);
}
}
void asyncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallArgConversionEnd(moduleName, methodName);
}
}
void asyncMethodCallDispatch(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallDispatch(moduleName, methodName);
}
}
void asyncMethodCallEnd(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallEnd(moduleName, methodName);
}
}
void asyncMethodCallBatchPreprocessStart() {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallBatchPreprocessStart();
}
}
void asyncMethodCallBatchPreprocessEnd(int batchSize) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallBatchPreprocessEnd(batchSize);
}
}
void asyncMethodCallExecutionStart(
const char *moduleName,
const char *methodName,
int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallExecutionStart(moduleName, methodName, id);
}
}
void asyncMethodCallExecutionArgConversionStart(
const char *moduleName,
const char *methodName,
int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallExecutionArgConversionStart(
moduleName, methodName, id);
}
}
void asyncMethodCallExecutionArgConversionEnd(
const char *moduleName,
const char *methodName,
int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallExecutionArgConversionEnd(
moduleName, methodName, id);
}
}
void asyncMethodCallExecutionEnd(
const char *moduleName,
const char *methodName,
int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallExecutionEnd(moduleName, methodName, id);
}
}
void asyncMethodCallExecutionFail(
const char *moduleName,
const char *methodName,
int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallExecutionFail(moduleName, methodName, id);
}
}
} // namespace BridgeNativeModulePerfLogger
} // namespace react
} // namespace facebook

Просмотреть файл

@ -0,0 +1,111 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <memory>
#include "NativeModulePerfLogger.h"
namespace facebook {
namespace react {
namespace BridgeNativeModulePerfLogger {
void enableLogging(std::unique_ptr<NativeModulePerfLogger> &&logger);
void moduleDataCreateStart(const char *moduleName, int32_t id);
void moduleDataCreateEnd(const char *moduleName, int32_t id);
/**
* Create NativeModule platform object
*/
void moduleCreateStart(const char *moduleName, int32_t id);
void moduleCreateCacheHit(const char *moduleName, int32_t id);
void moduleCreateConstructStart(const char *moduleName, int32_t id);
void moduleCreateConstructEnd(const char *moduleName, int32_t id);
void moduleCreateSetUpStart(const char *moduleName, int32_t id);
void moduleCreateSetUpEnd(const char *moduleName, int32_t id);
void moduleCreateEnd(const char *moduleName, int32_t id);
void moduleCreateFail(const char *moduleName, int32_t id);
/**
* JS require beginning
*/
void moduleJSRequireBeginningStart(const char *moduleName);
void moduleJSRequireBeginningCacheHit(const char *moduleName);
void moduleJSRequireBeginningEnd(const char *moduleName);
void moduleJSRequireBeginningFail(const char *moduleName);
/**
* JS require ending
*/
void moduleJSRequireEndingStart(const char *moduleName);
void moduleJSRequireEndingEnd(const char *moduleName);
void moduleJSRequireEndingFail(const char *moduleName);
// Sync method calls
void syncMethodCallStart(const char *moduleName, const char *methodName);
void syncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName);
void syncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName);
void syncMethodCallExecutionStart(
const char *moduleName,
const char *methodName);
void syncMethodCallExecutionEnd(const char *moduleName, const char *methodName);
void syncMethodCallReturnConversionStart(
const char *moduleName,
const char *methodName);
void syncMethodCallReturnConversionEnd(
const char *moduleName,
const char *methodName);
void syncMethodCallEnd(const char *moduleName, const char *methodName);
void syncMethodCallFail(const char *moduleName, const char *methodName);
// Async method calls
void asyncMethodCallStart(const char *moduleName, const char *methodName);
void asyncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName);
void asyncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName);
void asyncMethodCallDispatch(const char *moduleName, const char *methodName);
void asyncMethodCallEnd(const char *moduleName, const char *methodName);
/**
* Pre-processing async method call batch
*/
void asyncMethodCallBatchPreprocessStart();
void asyncMethodCallBatchPreprocessEnd(int batchSize);
// Async method call execution
void asyncMethodCallExecutionStart(
const char *moduleName,
const char *methodName,
int32_t id);
void asyncMethodCallExecutionArgConversionStart(
const char *moduleName,
const char *methodName,
int32_t id);
void asyncMethodCallExecutionArgConversionEnd(
const char *moduleName,
const char *methodName,
int32_t id);
void asyncMethodCallExecutionEnd(
const char *moduleName,
const char *methodName,
int32_t id);
void asyncMethodCallExecutionFail(
const char *moduleName,
const char *methodName,
int32_t id);
} // namespace BridgeNativeModulePerfLogger
} // namespace react
} // namespace facebook

Просмотреть файл

@ -1,144 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "NativeModulePerfLogger.h"
namespace facebook {
namespace react {
std::shared_ptr<NativeModulePerfLogger> NativeModulePerfLogger::s_perfLogger =
nullptr;
NativeModulePerfLogger &NativeModulePerfLogger::getInstance() {
static std::shared_ptr<NativeModulePerfLogger> defaultPerfLogger =
std::make_shared<NativeModulePerfLogger>();
return s_perfLogger ? *s_perfLogger : *defaultPerfLogger;
}
void NativeModulePerfLogger::setInstance(
std::shared_ptr<NativeModulePerfLogger> newPerfLogger) {
s_perfLogger = newPerfLogger;
}
NativeModulePerfLogger::~NativeModulePerfLogger() {}
void NativeModulePerfLogger::moduleDataCreateStart(
const char *moduleName,
int32_t id) {}
void NativeModulePerfLogger::moduleDataCreateEnd(
const char *moduleName,
int32_t id) {}
void NativeModulePerfLogger::moduleCreateStart(
const char *moduleName,
int32_t id) {}
void NativeModulePerfLogger::moduleCreateCacheHit(
const char *moduleName,
int32_t id) {}
void NativeModulePerfLogger::moduleCreateConstructStart(
const char *moduleName,
int32_t id) {}
void NativeModulePerfLogger::moduleCreateConstructEnd(
const char *moduleName,
int32_t id) {}
void NativeModulePerfLogger::moduleCreateSetUpStart(
const char *moduleName,
int32_t id) {}
void NativeModulePerfLogger::moduleCreateSetUpEnd(
const char *moduleName,
int32_t id) {}
void NativeModulePerfLogger::moduleCreateEnd(
const char *moduleName,
int32_t id) {}
void NativeModulePerfLogger::moduleCreateFail(
const char *moduleName,
int32_t id) {}
void NativeModulePerfLogger::moduleJSRequireBeginningStart(
const char *moduleName) {}
void NativeModulePerfLogger::moduleJSRequireBeginningCacheHit(
const char *moduleName) {}
void NativeModulePerfLogger::moduleJSRequireBeginningEnd(
const char *moduleName) {}
void NativeModulePerfLogger::moduleJSRequireBeginningFail(
const char *moduleName) {}
void NativeModulePerfLogger::moduleJSRequireEndingStart(
const char *moduleName) {}
void NativeModulePerfLogger::moduleJSRequireEndingEnd(const char *moduleName) {}
void NativeModulePerfLogger::moduleJSRequireEndingFail(const char *moduleName) {
}
void NativeModulePerfLogger::syncMethodCallStart(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::syncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::syncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::syncMethodCallExecutionStart(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::syncMethodCallExecutionEnd(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::syncMethodCallReturnConversionStart(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::syncMethodCallReturnConversionEnd(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::syncMethodCallEnd(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::syncMethodCallFail(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::asyncMethodCallStart(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::asyncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::asyncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::asyncMethodCallDispatch(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::asyncMethodCallEnd(
const char *moduleName,
const char *methodName) {}
void NativeModulePerfLogger::asyncMethodCallBatchPreprocessStart() {}
void NativeModulePerfLogger::asyncMethodCallBatchPreprocessEnd(int batchSize) {}
void NativeModulePerfLogger::asyncMethodCallExecutionStart(
const char *moduleName,
const char *methodName,
int32_t id) {}
void NativeModulePerfLogger::asyncMethodCallExecutionArgConversionStart(
const char *moduleName,
const char *methodName,
int32_t id) {}
void NativeModulePerfLogger::asyncMethodCallExecutionArgConversionEnd(
const char *moduleName,
const char *methodName,
int32_t id) {}
void NativeModulePerfLogger::asyncMethodCallExecutionEnd(
const char *moduleName,
const char *methodName,
int32_t id) {}
void NativeModulePerfLogger::asyncMethodCallExecutionFail(
const char *moduleName,
const char *methodName,
int32_t id) {}
} // namespace react
} // namespace facebook

Просмотреть файл

@ -6,7 +6,7 @@
*/
#pragma once
#include <memory>
#include <cstdint>
namespace facebook {
namespace react {
@ -16,14 +16,8 @@ namespace react {
* TuboModules.
*/
class NativeModulePerfLogger {
private:
static std::shared_ptr<NativeModulePerfLogger> s_perfLogger;
public:
static NativeModulePerfLogger &getInstance();
static void setInstance(std::shared_ptr<NativeModulePerfLogger> perfLogger);
virtual ~NativeModulePerfLogger();
virtual ~NativeModulePerfLogger() {}
/**
* NativeModule Initialization.
@ -45,22 +39,24 @@ class NativeModulePerfLogger {
* - moduleDataCreateStart: very beginning of first phase.
* - moduleDataCreateEnd: after RCTModuleData has been created.
*/
virtual void moduleDataCreateStart(const char *moduleName, int32_t id);
virtual void moduleDataCreateEnd(const char *moduleName, int32_t id);
virtual void moduleDataCreateStart(const char *moduleName, int32_t id) = 0;
virtual void moduleDataCreateEnd(const char *moduleName, int32_t id) = 0;
/**
* How long does it take to create the platform NativeModule object?
* - moduleCreateStart: start creating platform NativeModule
* - moduleCreateEnd: stop creating platform NativeModule
*/
virtual void moduleCreateStart(const char *moduleName, int32_t id);
virtual void moduleCreateCacheHit(const char *moduleName, int32_t id);
virtual void moduleCreateConstructStart(const char *moduleName, int32_t id);
virtual void moduleCreateConstructEnd(const char *moduleName, int32_t id);
virtual void moduleCreateSetUpStart(const char *moduleName, int32_t id);
virtual void moduleCreateSetUpEnd(const char *moduleName, int32_t id);
virtual void moduleCreateEnd(const char *moduleName, int32_t id);
virtual void moduleCreateFail(const char *moduleName, int32_t id);
virtual void moduleCreateStart(const char *moduleName, int32_t id) = 0;
virtual void moduleCreateCacheHit(const char *moduleName, int32_t id) = 0;
virtual void moduleCreateConstructStart(
const char *moduleName,
int32_t id) = 0;
virtual void moduleCreateConstructEnd(const char *moduleName, int32_t id) = 0;
virtual void moduleCreateSetUpStart(const char *moduleName, int32_t id) = 0;
virtual void moduleCreateSetUpEnd(const char *moduleName, int32_t id) = 0;
virtual void moduleCreateEnd(const char *moduleName, int32_t id) = 0;
virtual void moduleCreateFail(const char *moduleName, int32_t id) = 0;
/**
* How long, after starting JS require, does it take to start creating the
@ -68,10 +64,10 @@ class NativeModulePerfLogger {
* - moduleJSRequireBeginningStart: start of JS require
* - moduleJSRequireBeginningEnd: start creating platform NativeModule
*/
virtual void moduleJSRequireBeginningStart(const char *moduleName);
virtual void moduleJSRequireBeginningCacheHit(const char *moduleName);
virtual void moduleJSRequireBeginningEnd(const char *moduleName);
virtual void moduleJSRequireBeginningFail(const char *moduleName);
virtual void moduleJSRequireBeginningStart(const char *moduleName) = 0;
virtual void moduleJSRequireBeginningCacheHit(const char *moduleName) = 0;
virtual void moduleJSRequireBeginningEnd(const char *moduleName) = 0;
virtual void moduleJSRequireBeginningFail(const char *moduleName) = 0;
/**
* How long does it take to return from the JS require after the platform
@ -79,55 +75,55 @@ class NativeModulePerfLogger {
* - moduleJSRequireEndingStart: end creating platform NativeModule
* - moduleJSRequireEndingEnd: end of JS require
*/
virtual void moduleJSRequireEndingStart(const char *moduleName);
virtual void moduleJSRequireEndingEnd(const char *moduleName);
virtual void moduleJSRequireEndingFail(const char *moduleName);
virtual void moduleJSRequireEndingStart(const char *moduleName) = 0;
virtual void moduleJSRequireEndingEnd(const char *moduleName) = 0;
virtual void moduleJSRequireEndingFail(const char *moduleName) = 0;
// Sync method calls
virtual void syncMethodCallStart(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void syncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void syncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void syncMethodCallExecutionStart(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void syncMethodCallExecutionEnd(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void syncMethodCallReturnConversionStart(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void syncMethodCallReturnConversionEnd(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void syncMethodCallEnd(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void syncMethodCallFail(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
// Async method calls
virtual void asyncMethodCallStart(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void asyncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void asyncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void asyncMethodCallDispatch(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
virtual void asyncMethodCallEnd(
const char *moduleName,
const char *methodName);
const char *methodName) = 0;
/**
* In the NativeModule system, we batch async NativeModule method calls.
@ -135,30 +131,30 @@ class NativeModulePerfLogger {
* from a jsi::Value to folly::dynamic to std::vector<MethodCall>. This marker
* documents that work.
*/
virtual void asyncMethodCallBatchPreprocessStart();
virtual void asyncMethodCallBatchPreprocessEnd(int batchSize);
virtual void asyncMethodCallBatchPreprocessStart() = 0;
virtual void asyncMethodCallBatchPreprocessEnd(int batchSize) = 0;
// Async method call execution
virtual void asyncMethodCallExecutionStart(
const char *moduleName,
const char *methodName,
int32_t id);
int32_t id) = 0;
virtual void asyncMethodCallExecutionArgConversionStart(
const char *moduleName,
const char *methodName,
int32_t id);
int32_t id) = 0;
virtual void asyncMethodCallExecutionArgConversionEnd(
const char *moduleName,
const char *methodName,
int32_t id);
int32_t id) = 0;
virtual void asyncMethodCallExecutionEnd(
const char *moduleName,
const char *methodName,
int32_t id);
int32_t id) = 0;
virtual void asyncMethodCallExecutionFail(
const char *moduleName,
const char *methodName,
int32_t id);
int32_t id) = 0;
};
} // namespace react

Просмотреть файл

@ -11,15 +11,308 @@ namespace facebook {
namespace react {
namespace TurboModulePerfLogger {
std::shared_ptr<NativeModulePerfLogger> g_perfLogger = nullptr;
std::unique_ptr<NativeModulePerfLogger> g_perfLogger = nullptr;
NativeModulePerfLogger &getInstance() {
static std::shared_ptr<NativeModulePerfLogger> defaultPerfLogger =
std::make_shared<NativeModulePerfLogger>();
return g_perfLogger ? *g_perfLogger : *defaultPerfLogger;
void enableLogging(std::unique_ptr<NativeModulePerfLogger> &&newPerfLogger) {
g_perfLogger = std::move(newPerfLogger);
}
void setInstance(std::shared_ptr<NativeModulePerfLogger> perfLogger) {
g_perfLogger = perfLogger;
void moduleDataCreateStart(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleDataCreateStart(moduleName, id);
}
}
void moduleDataCreateEnd(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleDataCreateEnd(moduleName, id);
}
}
void moduleCreateStart(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateStart(moduleName, id);
}
}
void moduleCreateCacheHit(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateCacheHit(moduleName, id);
}
}
void moduleCreateConstructStart(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateConstructStart(moduleName, id);
}
}
void moduleCreateConstructEnd(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateConstructEnd(moduleName, id);
}
}
void moduleCreateSetUpStart(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateSetUpStart(moduleName, id);
}
}
void moduleCreateSetUpEnd(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateSetUpEnd(moduleName, id);
}
}
void moduleCreateEnd(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateEnd(moduleName, id);
}
}
void moduleCreateFail(const char *moduleName, int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleCreateFail(moduleName, id);
}
}
void moduleJSRequireBeginningStart(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireBeginningStart(moduleName);
}
}
void moduleJSRequireBeginningCacheHit(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireBeginningCacheHit(moduleName);
}
}
void moduleJSRequireBeginningEnd(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireBeginningEnd(moduleName);
}
}
void moduleJSRequireBeginningFail(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireBeginningFail(moduleName);
}
}
void moduleJSRequireEndingStart(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireEndingStart(moduleName);
}
}
void moduleJSRequireEndingEnd(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireEndingEnd(moduleName);
}
}
void moduleJSRequireEndingFail(const char *moduleName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->moduleJSRequireEndingFail(moduleName);
}
}
void syncMethodCallStart(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallStart(moduleName, methodName);
}
}
void syncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallArgConversionStart(moduleName, methodName);
}
}
void syncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallArgConversionEnd(moduleName, methodName);
}
}
void syncMethodCallExecutionStart(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallExecutionStart(moduleName, methodName);
}
}
void syncMethodCallExecutionEnd(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallExecutionEnd(moduleName, methodName);
}
}
void syncMethodCallReturnConversionStart(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallReturnConversionStart(moduleName, methodName);
}
}
void syncMethodCallReturnConversionEnd(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallReturnConversionEnd(moduleName, methodName);
}
}
void syncMethodCallEnd(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallEnd(moduleName, methodName);
}
}
void syncMethodCallFail(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->syncMethodCallFail(moduleName, methodName);
}
}
void asyncMethodCallStart(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallStart(moduleName, methodName);
}
}
void asyncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallArgConversionStart(moduleName, methodName);
}
}
void asyncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallArgConversionEnd(moduleName, methodName);
}
}
void asyncMethodCallDispatch(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallDispatch(moduleName, methodName);
}
}
void asyncMethodCallEnd(const char *moduleName, const char *methodName) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallEnd(moduleName, methodName);
}
}
void asyncMethodCallBatchPreprocessStart() {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallBatchPreprocessStart();
}
}
void asyncMethodCallBatchPreprocessEnd(int batchSize) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallBatchPreprocessEnd(batchSize);
}
}
void asyncMethodCallExecutionStart(
const char *moduleName,
const char *methodName,
int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallExecutionStart(moduleName, methodName, id);
}
}
void asyncMethodCallExecutionArgConversionStart(
const char *moduleName,
const char *methodName,
int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallExecutionArgConversionStart(
moduleName, methodName, id);
}
}
void asyncMethodCallExecutionArgConversionEnd(
const char *moduleName,
const char *methodName,
int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallExecutionArgConversionEnd(
moduleName, methodName, id);
}
}
void asyncMethodCallExecutionEnd(
const char *moduleName,
const char *methodName,
int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallExecutionEnd(moduleName, methodName, id);
}
}
void asyncMethodCallExecutionFail(
const char *moduleName,
const char *methodName,
int32_t id) {
NativeModulePerfLogger *logger = g_perfLogger.get();
if (logger != nullptr) {
logger->asyncMethodCallExecutionFail(moduleName, methodName, id);
}
}
} // namespace TurboModulePerfLogger

Просмотреть файл

@ -13,9 +13,97 @@
namespace facebook {
namespace react {
namespace TurboModulePerfLogger {
void enableLogging(std::unique_ptr<NativeModulePerfLogger> &&logger);
NativeModulePerfLogger &getInstance();
void setInstance(std::shared_ptr<NativeModulePerfLogger> perfLogger);
void moduleDataCreateStart(const char *moduleName, int32_t id);
void moduleDataCreateEnd(const char *moduleName, int32_t id);
/**
* Create NativeModule platform object
*/
void moduleCreateStart(const char *moduleName, int32_t id);
void moduleCreateCacheHit(const char *moduleName, int32_t id);
void moduleCreateConstructStart(const char *moduleName, int32_t id);
void moduleCreateConstructEnd(const char *moduleName, int32_t id);
void moduleCreateSetUpStart(const char *moduleName, int32_t id);
void moduleCreateSetUpEnd(const char *moduleName, int32_t id);
void moduleCreateEnd(const char *moduleName, int32_t id);
void moduleCreateFail(const char *moduleName, int32_t id);
/**
* JS require beginning
*/
void moduleJSRequireBeginningStart(const char *moduleName);
void moduleJSRequireBeginningCacheHit(const char *moduleName);
void moduleJSRequireBeginningEnd(const char *moduleName);
void moduleJSRequireBeginningFail(const char *moduleName);
/**
* JS require ending
*/
void moduleJSRequireEndingStart(const char *moduleName);
void moduleJSRequireEndingEnd(const char *moduleName);
void moduleJSRequireEndingFail(const char *moduleName);
// Sync method calls
void syncMethodCallStart(const char *moduleName, const char *methodName);
void syncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName);
void syncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName);
void syncMethodCallExecutionStart(
const char *moduleName,
const char *methodName);
void syncMethodCallExecutionEnd(const char *moduleName, const char *methodName);
void syncMethodCallReturnConversionStart(
const char *moduleName,
const char *methodName);
void syncMethodCallReturnConversionEnd(
const char *moduleName,
const char *methodName);
void syncMethodCallEnd(const char *moduleName, const char *methodName);
void syncMethodCallFail(const char *moduleName, const char *methodName);
// Async method calls
void asyncMethodCallStart(const char *moduleName, const char *methodName);
void asyncMethodCallArgConversionStart(
const char *moduleName,
const char *methodName);
void asyncMethodCallArgConversionEnd(
const char *moduleName,
const char *methodName);
void asyncMethodCallDispatch(const char *moduleName, const char *methodName);
void asyncMethodCallEnd(const char *moduleName, const char *methodName);
/**
* Pre-processing async method call batch
*/
void asyncMethodCallBatchPreprocessStart();
void asyncMethodCallBatchPreprocessEnd(int batchSize);
// Async method call execution
void asyncMethodCallExecutionStart(
const char *moduleName,
const char *methodName,
int32_t id);
void asyncMethodCallExecutionArgConversionStart(
const char *moduleName,
const char *methodName,
int32_t id);
void asyncMethodCallExecutionArgConversionEnd(
const char *moduleName,
const char *methodName,
int32_t id);
void asyncMethodCallExecutionEnd(
const char *moduleName,
const char *methodName,
int32_t id);
void asyncMethodCallExecutionFail(
const char *moduleName,
const char *methodName,
int32_t id);
} // namespace TurboModulePerfLogger
} // namespace react

Просмотреть файл

@ -338,10 +338,9 @@ jsi::Value ObjCTurboModule::performMethodInvocation(
id<RCTTurboModule> strongModule = weakModule;
if (wasMethodSync) {
TurboModulePerfLogger::getInstance().syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
TurboModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodNameStr.c_str());
} else {
TurboModulePerfLogger::getInstance().asyncMethodCallExecutionStart(
moduleName, methodNameStr.c_str(), asyncCallCounter);
TurboModulePerfLogger::asyncMethodCallExecutionStart(moduleName, methodNameStr.c_str(), asyncCallCounter);
}
// TODO(T66699874) Should we guard this with a try/catch?
@ -349,13 +348,12 @@ jsi::Value ObjCTurboModule::performMethodInvocation(
[retainedObjectsForInvocation removeAllObjects];
if (!wasMethodSync) {
TurboModulePerfLogger::getInstance().asyncMethodCallExecutionEnd(
moduleName, methodNameStr.c_str(), asyncCallCounter);
TurboModulePerfLogger::asyncMethodCallExecutionEnd(moduleName, methodNameStr.c_str(), asyncCallCounter);
return;
}
TurboModulePerfLogger::getInstance().syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
TurboModulePerfLogger::getInstance().syncMethodCallReturnConversionStart(moduleName, methodNameStr.c_str());
TurboModulePerfLogger::syncMethodCallExecutionEnd(moduleName, methodNameStr.c_str());
TurboModulePerfLogger::syncMethodCallReturnConversionStart(moduleName, methodNameStr.c_str());
void *rawResult;
[inv getReturnValue:&rawResult];
@ -366,7 +364,7 @@ jsi::Value ObjCTurboModule::performMethodInvocation(
nativeInvoker_->invokeSync([block]() -> void { block(); });
} else {
asyncCallCounter = getUniqueId();
TurboModulePerfLogger::getInstance().asyncMethodCallDispatch(moduleName, methodName);
TurboModulePerfLogger::asyncMethodCallDispatch(moduleName, methodName);
nativeInvoker_->invokeAsync([block]() -> void { block(); });
return jsi::Value::undefined();
}
@ -408,7 +406,7 @@ jsi::Value ObjCTurboModule::performMethodInvocation(
throw std::runtime_error("convertInvocationResultToJSIValue: PromiseKind wasn't handled properly.");
}
TurboModulePerfLogger::getInstance().syncMethodCallReturnConversionEnd(moduleName, methodName);
TurboModulePerfLogger::syncMethodCallReturnConversionEnd(moduleName, methodName);
return returnValue;
}
@ -483,9 +481,9 @@ NSInvocation *ObjCTurboModule::getMethodInvocation(
const id<RCTTurboModule> module = instance_;
if (isMethodSync(returnType)) {
TurboModulePerfLogger::getInstance().syncMethodCallArgConversionStart(moduleName, methodName);
TurboModulePerfLogger::syncMethodCallArgConversionStart(moduleName, methodName);
} else {
TurboModulePerfLogger::getInstance().asyncMethodCallArgConversionStart(moduleName, methodName);
TurboModulePerfLogger::asyncMethodCallArgConversionStart(moduleName, methodName);
}
NSInvocation *inv =
@ -590,9 +588,9 @@ NSInvocation *ObjCTurboModule::getMethodInvocation(
}
if (isMethodSync(returnType)) {
TurboModulePerfLogger::getInstance().syncMethodCallArgConversionEnd(moduleName, methodName);
TurboModulePerfLogger::syncMethodCallArgConversionEnd(moduleName, methodName);
} else {
TurboModulePerfLogger::getInstance().asyncMethodCallArgConversionEnd(moduleName, methodName);
TurboModulePerfLogger::asyncMethodCallArgConversionEnd(moduleName, methodName);
}
return inv;
@ -623,9 +621,9 @@ jsi::Value ObjCTurboModule::invokeObjCMethod(
const char *methodName = methodNameStr.c_str();
if (isMethodSync(returnType)) {
TurboModulePerfLogger::getInstance().syncMethodCallStart(moduleName, methodName);
TurboModulePerfLogger::syncMethodCallStart(moduleName, methodName);
} else {
TurboModulePerfLogger::getInstance().asyncMethodCallStart(moduleName, methodName);
TurboModulePerfLogger::asyncMethodCallStart(moduleName, methodName);
}
NSMutableArray *retainedObjectsForInvocation = [NSMutableArray arrayWithCapacity:count + 2];
@ -647,9 +645,9 @@ jsi::Value ObjCTurboModule::invokeObjCMethod(
: performMethodInvocation(runtime, returnType, methodName, inv, retainedObjectsForInvocation);
if (isMethodSync(returnType)) {
TurboModulePerfLogger::getInstance().syncMethodCallEnd(moduleName, methodName);
TurboModulePerfLogger::syncMethodCallEnd(moduleName, methodName);
} else {
TurboModulePerfLogger::getInstance().asyncMethodCallEnd(moduleName, methodName);
TurboModulePerfLogger::asyncMethodCallEnd(moduleName, methodName);
}
return returnValue;

Просмотреть файл

@ -224,12 +224,12 @@ static Class getFallbackClassFromName(const char *name)
{
auto turboModuleLookup = _turboModuleCache.find(moduleName);
if (turboModuleLookup != _turboModuleCache.end()) {
TurboModulePerfLogger::getInstance().moduleJSRequireBeginningCacheHit(moduleName);
TurboModulePerfLogger::getInstance().moduleJSRequireBeginningEnd(moduleName);
TurboModulePerfLogger::moduleJSRequireBeginningCacheHit(moduleName);
TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName);
return turboModuleLookup->second;
}
TurboModulePerfLogger::getInstance().moduleJSRequireBeginningEnd(moduleName);
TurboModulePerfLogger::moduleJSRequireBeginningEnd(moduleName);
/**
* Step 1: Look for pure C++ modules.
@ -237,15 +237,15 @@ static Class getFallbackClassFromName(const char *name)
*/
if ([_delegate respondsToSelector:@selector(getTurboModule:jsInvoker:)]) {
int32_t moduleId = getUniqueId();
TurboModulePerfLogger::getInstance().moduleCreateStart(moduleName, moduleId);
TurboModulePerfLogger::moduleCreateStart(moduleName, moduleId);
auto turboModule = [_delegate getTurboModule:moduleName jsInvoker:_jsInvoker];
if (turboModule != nullptr) {
_turboModuleCache.insert({moduleName, turboModule});
TurboModulePerfLogger::getInstance().moduleCreateEnd(moduleName, moduleId);
TurboModulePerfLogger::moduleCreateEnd(moduleName, moduleId);
return turboModule;
}
TurboModulePerfLogger::getInstance().moduleCreateFail(moduleName, moduleId);
TurboModulePerfLogger::moduleCreateFail(moduleName, moduleId);
}
/**
@ -253,7 +253,7 @@ static Class getFallbackClassFromName(const char *name)
*/
id<RCTTurboModule> module = [self provideRCTTurboModule:moduleName];
TurboModulePerfLogger::getInstance().moduleJSRequireEndingStart(moduleName);
TurboModulePerfLogger::moduleJSRequireEndingStart(moduleName);
// If we request that a TurboModule be created, its respective ObjC class must exist
// If the class doesn't exist, then provideRCTTurboModule returns nil
@ -338,13 +338,13 @@ static Class getFallbackClassFromName(const char *name)
moduleHolder = &_turboModuleHolders[moduleName];
}
TurboModulePerfLogger::getInstance().moduleCreateStart(moduleName, moduleHolder->getModuleId());
TurboModulePerfLogger::moduleCreateStart(moduleName, moduleHolder->getModuleId());
id<RCTTurboModule> module = [self _provideRCTTurboModule:moduleName moduleHolder:moduleHolder shouldPerfLog:YES];
if (module) {
TurboModulePerfLogger::getInstance().moduleCreateEnd(moduleName, moduleHolder->getModuleId());
TurboModulePerfLogger::moduleCreateEnd(moduleName, moduleHolder->getModuleId());
} else {
TurboModulePerfLogger::getInstance().moduleCreateFail(moduleName, moduleHolder->getModuleId());
TurboModulePerfLogger::moduleCreateFail(moduleName, moduleHolder->getModuleId());
}
return module;
@ -361,7 +361,7 @@ static Class getFallbackClassFromName(const char *name)
if (moduleHolder->isDoneCreatingModule()) {
if (shouldPerfLog) {
TurboModulePerfLogger::getInstance().moduleCreateCacheHit(moduleName, moduleHolder->getModuleId());
TurboModulePerfLogger::moduleCreateCacheHit(moduleName, moduleHolder->getModuleId());
}
return moduleHolder->getModule();
}
@ -451,7 +451,7 @@ static Class getFallbackClassFromName(const char *name)
* Step 2b: Ask hosting application/delegate to instantiate this class
*/
TurboModulePerfLogger::getInstance().moduleCreateConstructStart(moduleName, moduleId);
TurboModulePerfLogger::moduleCreateConstructStart(moduleName, moduleId);
if ([_delegate respondsToSelector:@selector(getModuleInstanceFromClass:)]) {
std::lock_guard<std::mutex> delegateGuard(_turboModuleManagerDelegateMutex);
@ -459,9 +459,9 @@ static Class getFallbackClassFromName(const char *name)
} else {
module = [moduleClass new];
}
TurboModulePerfLogger::getInstance().moduleCreateConstructEnd(moduleName, moduleId);
TurboModulePerfLogger::moduleCreateConstructEnd(moduleName, moduleId);
TurboModulePerfLogger::getInstance().moduleCreateSetUpStart(moduleName, moduleId);
TurboModulePerfLogger::moduleCreateSetUpStart(moduleName, moduleId);
if ([module respondsToSelector:@selector(setTurboModuleLookupDelegate:)]) {
[module setTurboModuleLookupDelegate:self];
@ -578,7 +578,7 @@ static Class getFallbackClassFromName(const char *name)
object:_bridge
userInfo:@{@"module" : module, @"bridge" : RCTNullIfNil([_bridge parentBridge])}];
TurboModulePerfLogger::getInstance().moduleCreateSetUpEnd(moduleName, moduleId);
TurboModulePerfLogger::moduleCreateSetUpEnd(moduleName, moduleId);
return module;
}
@ -658,7 +658,7 @@ static Class getFallbackClassFromName(const char *name)
auto moduleName = name.c_str();
TurboModulePerfLogger::getInstance().moduleJSRequireBeginningStart(moduleName);
TurboModulePerfLogger::moduleJSRequireBeginningStart(moduleName);
__strong __typeof(self) strongSelf = weakSelf;
@ -680,9 +680,9 @@ static Class getFallbackClassFromName(const char *name)
}
if (turboModule) {
TurboModulePerfLogger::getInstance().moduleJSRequireEndingEnd(moduleName);
TurboModulePerfLogger::moduleJSRequireEndingEnd(moduleName);
} else {
TurboModulePerfLogger::getInstance().moduleJSRequireEndingFail(moduleName);
TurboModulePerfLogger::moduleJSRequireEndingFail(moduleName);
}
return turboModule;