mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add additional Systrace support
Summary: Adding support for application to hook into further tracing methods ## Changelog [General][Added] - Add additional Systrace support Reviewed By: NickGerleman Differential Revision: D38673212 fbshipit-source-id: 55a90a0cd57809bca5f01da7acddcf253e5852ba
This commit is contained in:
committed by
Facebook GitHub Bot
parent
447be62909
commit
9cb716ff76
@@ -73,6 +73,15 @@ folly::dynamic RCTNativeModule::getConstants()
|
||||
|
||||
void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &¶ms, int callId)
|
||||
{
|
||||
id<RCTBridgeMethod> method = m_moduleData.methods[methodId];
|
||||
if (method) {
|
||||
RCT_PROFILE_BEGIN_EVENT(
|
||||
RCTProfileTagAlways,
|
||||
@"[RCTNativeModule invoke]",
|
||||
@{@"method" : [NSString stringWithUTF8String:method.JSMethodName]});
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
}
|
||||
|
||||
const char *moduleName = [m_moduleData.name UTF8String];
|
||||
const char *methodName = m_moduleData.methods[methodId].JSMethodName;
|
||||
|
||||
@@ -173,6 +182,10 @@ static MethodCallResult invokeInner(
|
||||
BridgeNativeModulePerfLogger::syncMethodCallArgConversionEnd(moduleName, methodName);
|
||||
}
|
||||
|
||||
RCT_PROFILE_BEGIN_EVENT(
|
||||
RCTProfileTagAlways,
|
||||
@"[RCTNativeModule invokeInner]",
|
||||
@{@"method" : [NSString stringWithUTF8String:method.JSMethodName]});
|
||||
@try {
|
||||
if (context == Sync) {
|
||||
BridgeNativeModulePerfLogger::syncMethodCallExecutionStart(moduleName, methodName);
|
||||
@@ -214,6 +227,8 @@ static MethodCallResult invokeInner(
|
||||
#else
|
||||
RCTFatalException(exception);
|
||||
#endif
|
||||
} @finally {
|
||||
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||
}
|
||||
|
||||
return folly::none;
|
||||
|
||||
@@ -57,6 +57,20 @@ RCT_EXTERN void RCTProfileInit(RCTBridge *);
|
||||
*/
|
||||
RCT_EXTERN void RCTProfileEnd(RCTBridge *, void (^)(NSString *));
|
||||
|
||||
/**
|
||||
* Route the RCT_PROFILE_BEGIN_EVENT hooks to our loom tracing.
|
||||
*/
|
||||
#ifdef WITH_LOOM_TRACE
|
||||
RCT_EXTERN BOOL _RCTLoomIsProfiling(void);
|
||||
RCT_EXTERN void
|
||||
_RCTLoomBeginEvent(NSString *name, const char *file, size_t line, NSDictionary<NSString *, NSString *> *args);
|
||||
RCT_EXTERN void _RCTLoomEndEvent();
|
||||
#else
|
||||
#define _RCTLoomIsProfiling(...) NO
|
||||
#define _RCTLoomBeginEvent(...)
|
||||
#define _RCTLoomEndEvent(...)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Collects the initial event information for the event and returns a reference ID
|
||||
*/
|
||||
@@ -68,6 +82,9 @@ RCT_EXTERN void _RCTProfileBeginEvent(
|
||||
NSDictionary<NSString *, NSString *> *args);
|
||||
#define RCT_PROFILE_BEGIN_EVENT(tag, name, args) \
|
||||
do { \
|
||||
if (_RCTLoomIsProfiling()) { \
|
||||
_RCTLoomBeginEvent(name, __FILE__, __LINE__, args); \
|
||||
} \
|
||||
if (RCTProfileIsProfiling()) { \
|
||||
NSThread *__calleeThread = [NSThread currentThread]; \
|
||||
NSTimeInterval __time = CACurrentMediaTime(); \
|
||||
@@ -89,6 +106,9 @@ RCT_EXTERN void _RCTProfileEndEvent(
|
||||
|
||||
#define RCT_PROFILE_END_EVENT(tag, category) \
|
||||
do { \
|
||||
if (_RCTLoomIsProfiling()) { \
|
||||
_RCTLoomEndEvent(); \
|
||||
} \
|
||||
if (RCTProfileIsProfiling()) { \
|
||||
NSThread *__calleeThread = [NSThread currentThread]; \
|
||||
NSString *__threadName = RCTCurrentThreadName(); \
|
||||
|
||||
@@ -185,34 +185,42 @@ void CxxNativeModule::invoke(
|
||||
// stack. I'm told that will be possible in the future. TODO
|
||||
// mhorowitz #7128529: convert C++ exceptions to Java
|
||||
|
||||
messageQueueThread_->runOnQueue(
|
||||
[method, params = std::move(params), first, second, callId]() {
|
||||
const auto &moduleName = name_;
|
||||
SystraceSection s(
|
||||
"CxxMethodCallQueue", "module", moduleName, "method", method.name);
|
||||
messageQueueThread_->runOnQueue([method,
|
||||
moduleName,
|
||||
params = std::move(params),
|
||||
first,
|
||||
second,
|
||||
callId]() {
|
||||
#ifdef WITH_FBSYSTRACE
|
||||
if (callId != -1) {
|
||||
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
||||
}
|
||||
if (callId != -1) {
|
||||
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
||||
}
|
||||
#else
|
||||
(void)(callId);
|
||||
(void)(callId);
|
||||
#endif
|
||||
SystraceSection s(method.name.c_str());
|
||||
try {
|
||||
method.func(std::move(params), first, second);
|
||||
} catch (const facebook::xplat::JsArgumentException &ex) {
|
||||
throw;
|
||||
} catch (std::exception &e) {
|
||||
LOG(ERROR) << "std::exception. Method call " << method.name.c_str()
|
||||
<< " failed: " << e.what();
|
||||
std::terminate();
|
||||
} catch (std::string &error) {
|
||||
LOG(ERROR) << "std::string. Method call " << method.name.c_str()
|
||||
<< " failed: " << error.c_str();
|
||||
std::terminate();
|
||||
} catch (...) {
|
||||
LOG(ERROR) << "Method call " << method.name.c_str()
|
||||
<< " failed. unknown error";
|
||||
std::terminate();
|
||||
}
|
||||
});
|
||||
SystraceSection s(
|
||||
"CxxMethodCallDispatch", "module", moduleName, "method", method.name);
|
||||
try {
|
||||
method.func(std::move(params), first, second);
|
||||
} catch (const facebook::xplat::JsArgumentException &ex) {
|
||||
throw;
|
||||
} catch (std::exception &e) {
|
||||
LOG(ERROR) << "std::exception. Method call " << method.name.c_str()
|
||||
<< " failed: " << e.what();
|
||||
std::terminate();
|
||||
} catch (std::string &error) {
|
||||
LOG(ERROR) << "std::string. Method call " << method.name.c_str()
|
||||
<< " failed: " << error.c_str();
|
||||
std::terminate();
|
||||
} catch (...) {
|
||||
LOG(ERROR) << "Method call " << method.name.c_str()
|
||||
<< " failed. unknown error";
|
||||
std::terminate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
MethodCallResult CxxNativeModule::callSerializableNativeHook(
|
||||
|
||||
@@ -14,6 +14,16 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/**
|
||||
* Allow providing an fbsystrace implementation that can short-circuit out
|
||||
* quickly and can throttle too frequent events so we can get useful traces even
|
||||
* if rendering etc. is spinning. For throttling we'll need file/line info so we
|
||||
* use a macro.
|
||||
*/
|
||||
#if defined(WITH_LOOM_TRACE)
|
||||
#define SystraceSection \
|
||||
static constexpr const char systraceSectionFile[] = __FILE__; \
|
||||
fbsystrace::FbSystraceSection<systraceSectionFile, __LINE__>
|
||||
/**
|
||||
* This is a convenience class to avoid lots of verbose profiling
|
||||
* #ifdefs. If WITH_FBSYSTRACE is not defined, the optimizer will
|
||||
@@ -23,7 +33,7 @@ namespace react {
|
||||
* different values in different files, there is no inconsistency in the sizes
|
||||
* of defined symbols.
|
||||
*/
|
||||
#ifdef WITH_FBSYSTRACE
|
||||
#elif defined(WITH_FBSYSTRACE)
|
||||
struct ConcreteSystraceSection {
|
||||
public:
|
||||
template <typename... ConvertsToStringPiece>
|
||||
|
||||
Reference in New Issue
Block a user