amis-rpc-design/node_modules/react-native/React/Profiler/RCTProfile.h
2023-10-07 19:42:30 +08:00

247 lines
8.0 KiB
Objective-C

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#import <Foundation/Foundation.h>
#import <React/RCTAssert.h>
#import <React/RCTDefines.h>
/**
* RCTProfile
*
* This file provides a set of functions and macros for performance profiling
*
* NOTE: This API is a work in progress, please consider carefully before
* using it.
*/
RCT_EXTERN NSString *const RCTProfileDidStartProfiling;
RCT_EXTERN NSString *const RCTProfileDidEndProfiling;
RCT_EXTERN const uint64_t RCTProfileTagAlways;
#if RCT_PROFILE
@class RCTBridge;
#define RCTProfileBeginFlowEvent() \
_Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\"") NSUInteger __rct_profile_flow_id = \
_RCTProfileBeginFlowEvent(); \
_Pragma("clang diagnostic pop")
#define RCTProfileEndFlowEvent() _RCTProfileEndFlowEvent(__rct_profile_flow_id)
RCT_EXTERN dispatch_queue_t RCTProfileGetQueue(void);
RCT_EXTERN NSUInteger _RCTProfileBeginFlowEvent(void);
RCT_EXTERN void _RCTProfileEndFlowEvent(NSUInteger);
/**
* Returns YES if the profiling information is currently being collected
*/
RCT_EXTERN BOOL RCTProfileIsProfiling(void);
/**
* Start collecting profiling information
*/
RCT_EXTERN void RCTProfileInit(RCTBridge *);
/**
* Stop profiling and return a JSON string of the collected data - The data
* returned is compliant with google's trace event format - the format used
* as input to trace-viewer
*/
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
*/
RCT_EXTERN void _RCTProfileBeginEvent(
NSThread *calleeThread,
NSTimeInterval time,
uint64_t tag,
NSString *name,
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(); \
_RCTProfileBeginEvent(__calleeThread, __time, tag, name, args); \
} \
} while (0)
/**
* The ID returned by BeginEvent should then be passed into EndEvent, with the
* rest of the event information. Just at this point the event will actually be
* registered
*/
RCT_EXTERN void _RCTProfileEndEvent(
NSThread *calleeThread,
NSString *threadName,
NSTimeInterval time,
uint64_t tag,
NSString *category);
#define RCT_PROFILE_END_EVENT(tag, category) \
do { \
if (_RCTLoomIsProfiling()) { \
_RCTLoomEndEvent(); \
} \
if (RCTProfileIsProfiling()) { \
NSThread *__calleeThread = [NSThread currentThread]; \
NSString *__threadName = RCTCurrentThreadName(); \
NSTimeInterval __time = CACurrentMediaTime(); \
_RCTProfileEndEvent(__calleeThread, __threadName, __time, tag, category); \
} \
} while (0)
/**
* Collects the initial event information for the event and returns a reference ID
*/
RCT_EXTERN NSUInteger
RCTProfileBeginAsyncEvent(uint64_t tag, NSString *name, NSDictionary<NSString *, NSString *> *args);
/**
* The ID returned by BeginEvent should then be passed into EndEvent, with the
* rest of the event information. Just at this point the event will actually be
* registered
*/
RCT_EXTERN void
RCTProfileEndAsyncEvent(uint64_t tag, NSString *category, NSUInteger cookie, NSString *name, NSString *threadName);
/**
* An event that doesn't have a duration (i.e. Notification, VSync, etc)
*/
RCT_EXTERN void RCTProfileImmediateEvent(uint64_t tag, NSString *name, NSTimeInterval time, char scope);
/**
* Helper to profile the duration of the execution of a block. This method uses
* self and _cmd to name this event for simplicity sake.
*
* NOTE: The block can't expect any argument
*
* DEPRECATED: this approach breaks debugging and stepping through instrumented block functions
*/
#define RCTProfileBlock(block, tag, category, arguments) \
^{ \
RCT_PROFILE_BEGIN_EVENT(tag, @(__PRETTY_FUNCTION__), nil); \
block(); \
RCT_PROFILE_END_EVENT(tag, category, arguments); \
}
/**
* Hook into a bridge instance to log all bridge module's method calls
*/
RCT_EXTERN void RCTProfileHookModules(RCTBridge *);
/**
* Unhook from a given bridge instance's modules
*/
RCT_EXTERN void RCTProfileUnhookModules(RCTBridge *);
/**
* Hook into all of a module's methods
*/
RCT_EXTERN void RCTProfileHookInstance(id instance);
/**
* Send systrace or cpu profiling information to the packager
* to present to the user
*/
RCT_EXTERN void RCTProfileSendResult(RCTBridge *bridge, NSString *route, NSData *profileData);
/**
* Systrace gluecode
*
* allow to use systrace to back RCTProfile
*/
typedef struct {
const char *key;
unsigned long key_len;
const char *value;
unsigned long value_len;
} systrace_arg_t;
typedef struct {
char *(*start)(void);
void (*stop)(void);
void (*begin_section)(uint64_t tag, const char *name, size_t numArgs, systrace_arg_t *args);
void (*end_section)(uint64_t tag, size_t numArgs, systrace_arg_t *args);
void (*begin_async_section)(uint64_t tag, const char *name, int cookie, size_t numArgs, systrace_arg_t *args);
void (*end_async_section)(uint64_t tag, const char *name, int cookie, size_t numArgs, systrace_arg_t *args);
void (*instant_section)(uint64_t tag, const char *name, char scope);
void (*begin_async_flow)(uint64_t tag, const char *name, int cookie);
void (*end_async_flow)(uint64_t tag, const char *name, int cookie);
} RCTProfileCallbacks;
RCT_EXTERN void RCTProfileRegisterCallbacks(RCTProfileCallbacks *);
/**
* Systrace control window
*/
RCT_EXTERN void RCTProfileShowControls(void);
RCT_EXTERN void RCTProfileHideControls(void);
#else
#define RCTProfileBeginFlowEvent()
#define _RCTProfileBeginFlowEvent() @0
#define RCTProfileEndFlowEvent()
#define _RCTProfileEndFlowEvent(...)
#define RCTProfileIsProfiling(...) NO
#define RCTProfileInit(...)
#define RCTProfileEnd(...) @""
#define _RCTProfileBeginEvent(...)
#define _RCTProfileEndEvent(...)
#define RCT_PROFILE_BEGIN_EVENT(...)
#define RCT_PROFILE_END_EVENT(...)
#define RCTProfileBeginAsyncEvent(...) 0
#define RCTProfileEndAsyncEvent(...)
#define RCTProfileImmediateEvent(...)
#define RCTProfileBlock(block, ...) block
#define RCTProfileHookModules(...)
#define RCTProfileHookInstance(...)
#define RCTProfileUnhookModules(...)
#define RCTProfileSendResult(...)
#define RCTProfileShowControls(...)
#define RCTProfileHideControls(...)
#endif