Add gluecode for systrace
Summary: @public Add gluecode to allow use to systrace as the backend of RCTProfile Reviewed By: @jspahrsummers Differential Revision: D2439181
This commit is contained in:
parent
dcf245a9a2
commit
98378cab18
|
@ -125,6 +125,34 @@ RCT_EXTERN void RCTProfileUnhookModules(RCTBridge *);
|
||||||
*/
|
*/
|
||||||
RCT_EXTERN void RCTProfileSendResult(RCTBridge *bridge, NSString *route, NSData *profielData);
|
RCT_EXTERN void RCTProfileSendResult(RCTBridge *bridge, NSString *route, NSData *profielData);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Systrace gluecode
|
||||||
|
*
|
||||||
|
* allow to use systrace to back RCTProfile
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *key;
|
||||||
|
int key_len;
|
||||||
|
const char *value;
|
||||||
|
int value_len;
|
||||||
|
} systrace_arg_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void (*start)(uint64_t enabledTags, char *buffer, size_t bufferSize);
|
||||||
|
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);
|
||||||
|
} RCTProfileCallbacks;
|
||||||
|
|
||||||
|
RCT_EXTERN void RCTProfileRegisterCallbacks(RCTProfileCallbacks *);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define RCTProfileBeginFlowEvent()
|
#define RCTProfileBeginFlowEvent()
|
||||||
|
|
|
@ -35,11 +35,11 @@ NSString *const RCTProfilePrefix = @"rct_profile_";
|
||||||
|
|
||||||
#pragma mark - Variables
|
#pragma mark - Variables
|
||||||
|
|
||||||
NSDictionary *RCTProfileInfo;
|
static BOOL RCTProfileProfiling;
|
||||||
NSUInteger RCTProfileEventID = 0;
|
static NSDictionary *RCTProfileInfo;
|
||||||
NSMutableDictionary *RCTProfileOngoingEvents;
|
static NSMutableDictionary *RCTProfileOngoingEvents;
|
||||||
NSTimeInterval RCTProfileStartTime;
|
static NSTimeInterval RCTProfileStartTime;
|
||||||
NSRecursiveLock *_RCTProfileLock;
|
static NSUInteger RCTProfileEventID = 0;
|
||||||
|
|
||||||
#pragma mark - Macros
|
#pragma mark - Macros
|
||||||
|
|
||||||
|
@ -56,12 +56,55 @@ if (!RCTProfileIsProfiling()) { \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RCTProfileLock(...) \
|
#define RCTProfileLock(...) \
|
||||||
[_RCTProfileLock lock]; \
|
[_RCTProfileLock() lock]; \
|
||||||
__VA_ARGS__ \
|
__VA_ARGS__ \
|
||||||
[_RCTProfileLock unlock]
|
[_RCTProfileLock() unlock]
|
||||||
|
|
||||||
|
#pragma mark - systrace glue code
|
||||||
|
|
||||||
|
static RCTProfileCallbacks *callbacks;
|
||||||
|
static char *systrace_buffer;
|
||||||
|
|
||||||
|
static systrace_arg_t *RCTProfileSystraceArgsFromNSDictionary(NSDictionary *args)
|
||||||
|
{
|
||||||
|
if (args.count == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
systrace_arg_t *systrace_args = malloc(sizeof(systrace_arg_t) * args.count);
|
||||||
|
__block size_t i = 0;
|
||||||
|
[args enumerateKeysAndObjectsUsingBlock:^(id key, id value, __unused BOOL *stop) {
|
||||||
|
const char *keyc = [key description].UTF8String;
|
||||||
|
systrace_args[i].key = keyc;
|
||||||
|
systrace_args[i].key_len = (int)strlen(keyc);
|
||||||
|
|
||||||
|
const char *valuec = RCTJSONStringify(value, nil).UTF8String;
|
||||||
|
systrace_args[i].value = valuec;
|
||||||
|
systrace_args[i].value_len = (int)strlen(valuec);
|
||||||
|
i++;
|
||||||
|
}];
|
||||||
|
return systrace_args;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RCTProfileRegisterCallbacks(RCTProfileCallbacks *cb)
|
||||||
|
{
|
||||||
|
callbacks = cb;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Private Helpers
|
#pragma mark - Private Helpers
|
||||||
|
|
||||||
|
static NSLock *_RCTProfileLock()
|
||||||
|
{
|
||||||
|
static dispatch_once_t token;
|
||||||
|
static NSLock *lock;
|
||||||
|
dispatch_once(&token, ^{
|
||||||
|
lock = [NSLock new];
|
||||||
|
lock.name = @"RCTProfileLock";
|
||||||
|
});
|
||||||
|
|
||||||
|
return lock;
|
||||||
|
}
|
||||||
|
|
||||||
static NSNumber *RCTProfileTimestamp(NSTimeInterval timestamp)
|
static NSNumber *RCTProfileTimestamp(NSTimeInterval timestamp)
|
||||||
{
|
{
|
||||||
return @((timestamp - RCTProfileStartTime) * 1e6);
|
return @((timestamp - RCTProfileStartTime) * 1e6);
|
||||||
|
@ -215,20 +258,19 @@ void RCTProfileUnhookModules(RCTBridge *bridge)
|
||||||
|
|
||||||
BOOL RCTProfileIsProfiling(void)
|
BOOL RCTProfileIsProfiling(void)
|
||||||
{
|
{
|
||||||
RCTProfileLock(
|
return RCTProfileProfiling;
|
||||||
BOOL profiling = RCTProfileInfo != nil;
|
|
||||||
);
|
|
||||||
return profiling;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RCTProfileInit(RCTBridge *bridge)
|
void RCTProfileInit(RCTBridge *bridge)
|
||||||
{
|
{
|
||||||
RCTProfileHookModules(bridge);
|
RCTProfileHookModules(bridge);
|
||||||
|
RCTProfileProfiling = YES;
|
||||||
|
|
||||||
static dispatch_once_t onceToken;
|
if (callbacks != NULL) {
|
||||||
dispatch_once(&onceToken, ^{
|
size_t buffer_size = 1 << 22;
|
||||||
_RCTProfileLock = [NSRecursiveLock new];
|
systrace_buffer = calloc(1, buffer_size);
|
||||||
});
|
callbacks->start(~((uint64_t)0), systrace_buffer, buffer_size);
|
||||||
|
} else {
|
||||||
RCTProfileLock(
|
RCTProfileLock(
|
||||||
RCTProfileStartTime = CACurrentMediaTime();
|
RCTProfileStartTime = CACurrentMediaTime();
|
||||||
RCTProfileOngoingEvents = [NSMutableDictionary new];
|
RCTProfileOngoingEvents = [NSMutableDictionary new];
|
||||||
|
@ -237,6 +279,7 @@ void RCTProfileInit(RCTBridge *bridge)
|
||||||
RCTProfileSamples: [NSMutableArray new],
|
RCTProfileSamples: [NSMutableArray new],
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTProfileDidStartProfiling
|
[[NSNotificationCenter defaultCenter] postNotificationName:RCTProfileDidStartProfiling
|
||||||
object:nil];
|
object:nil];
|
||||||
|
@ -247,6 +290,17 @@ NSString *RCTProfileEnd(RCTBridge *bridge)
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationName:RCTProfileDidEndProfiling
|
[[NSNotificationCenter defaultCenter] postNotificationName:RCTProfileDidEndProfiling
|
||||||
object:nil];
|
object:nil];
|
||||||
|
|
||||||
|
RCTProfileProfiling = NO;
|
||||||
|
|
||||||
|
RCTProfileLock(
|
||||||
|
RCTProfileUnhookModules(bridge);
|
||||||
|
);
|
||||||
|
|
||||||
|
if (callbacks != NULL) {
|
||||||
|
callbacks->stop();
|
||||||
|
|
||||||
|
return @(systrace_buffer);
|
||||||
|
} else {
|
||||||
RCTProfileLock(
|
RCTProfileLock(
|
||||||
NSString *log = RCTJSONStringify(RCTProfileInfo, NULL);
|
NSString *log = RCTJSONStringify(RCTProfileInfo, NULL);
|
||||||
RCTProfileEventID = 0;
|
RCTProfileEventID = 0;
|
||||||
|
@ -254,9 +308,8 @@ NSString *RCTProfileEnd(RCTBridge *bridge)
|
||||||
RCTProfileOngoingEvents = nil;
|
RCTProfileOngoingEvents = nil;
|
||||||
);
|
);
|
||||||
|
|
||||||
RCTProfileUnhookModules(bridge);
|
|
||||||
|
|
||||||
return log;
|
return log;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static NSMutableArray *RCTProfileGetThreadEvents(void)
|
static NSMutableArray *RCTProfileGetThreadEvents(void)
|
||||||
|
@ -273,6 +326,12 @@ static NSMutableArray *RCTProfileGetThreadEvents(void)
|
||||||
void RCTProfileBeginEvent(uint64_t tag, NSString *name, NSDictionary *args)
|
void RCTProfileBeginEvent(uint64_t tag, NSString *name, NSDictionary *args)
|
||||||
{
|
{
|
||||||
CHECK();
|
CHECK();
|
||||||
|
|
||||||
|
if (callbacks != NULL) {
|
||||||
|
callbacks->begin_section(tag, name.UTF8String, args.count, RCTProfileSystraceArgsFromNSDictionary(args));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NSMutableArray *events = RCTProfileGetThreadEvents();
|
NSMutableArray *events = RCTProfileGetThreadEvents();
|
||||||
[events addObject:@[
|
[events addObject:@[
|
||||||
RCTProfileTimestamp(CACurrentMediaTime()),
|
RCTProfileTimestamp(CACurrentMediaTime()),
|
||||||
|
@ -283,12 +342,17 @@ void RCTProfileBeginEvent(uint64_t tag, NSString *name, NSDictionary *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
void RCTProfileEndEvent(
|
void RCTProfileEndEvent(
|
||||||
__unused uint64_t tag,
|
uint64_t tag,
|
||||||
NSString *category,
|
NSString *category,
|
||||||
NSDictionary *args
|
NSDictionary *args
|
||||||
) {
|
) {
|
||||||
CHECK();
|
CHECK();
|
||||||
|
|
||||||
|
if (callbacks != NULL) {
|
||||||
|
callbacks->end_section(tag, args.count, RCTProfileSystraceArgsFromNSDictionary(args));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
NSMutableArray *events = RCTProfileGetThreadEvents();
|
NSMutableArray *events = RCTProfileGetThreadEvents();
|
||||||
NSArray *event = events.lastObject;
|
NSArray *event = events.lastObject;
|
||||||
[events removeLastObject];
|
[events removeLastObject];
|
||||||
|
@ -312,7 +376,7 @@ void RCTProfileEndEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
int RCTProfileBeginAsyncEvent(
|
int RCTProfileBeginAsyncEvent(
|
||||||
__unused uint64_t tag,
|
uint64_t tag,
|
||||||
NSString *name,
|
NSString *name,
|
||||||
NSDictionary *args
|
NSDictionary *args
|
||||||
) {
|
) {
|
||||||
|
@ -320,6 +384,9 @@ int RCTProfileBeginAsyncEvent(
|
||||||
|
|
||||||
static int eventID = 0;
|
static int eventID = 0;
|
||||||
|
|
||||||
|
if (callbacks != NULL) {
|
||||||
|
callbacks->begin_async_section(tag, name.UTF8String, eventID, args.count, RCTProfileSystraceArgsFromNSDictionary(args));
|
||||||
|
} else {
|
||||||
RCTProfileLock(
|
RCTProfileLock(
|
||||||
RCTProfileOngoingEvents[@(eventID)] = @[
|
RCTProfileOngoingEvents[@(eventID)] = @[
|
||||||
RCTProfileTimestamp(CACurrentMediaTime()),
|
RCTProfileTimestamp(CACurrentMediaTime()),
|
||||||
|
@ -327,18 +394,25 @@ int RCTProfileBeginAsyncEvent(
|
||||||
RCTNullIfNil(args),
|
RCTNullIfNil(args),
|
||||||
];
|
];
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return eventID++;
|
return eventID++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RCTProfileEndAsyncEvent(
|
void RCTProfileEndAsyncEvent(
|
||||||
__unused uint64_t tag,
|
uint64_t tag,
|
||||||
NSString *category,
|
NSString *category,
|
||||||
int cookie,
|
int cookie,
|
||||||
__unused NSString *name,
|
NSString *name,
|
||||||
NSDictionary *args
|
NSDictionary *args
|
||||||
) {
|
) {
|
||||||
CHECK();
|
CHECK();
|
||||||
|
|
||||||
|
if (callbacks != NULL) {
|
||||||
|
callbacks->end_async_section(tag, name.UTF8String, cookie, args.count, RCTProfileSystraceArgsFromNSDictionary(args));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RCTProfileLock(
|
RCTProfileLock(
|
||||||
NSArray *event = RCTProfileOngoingEvents[@(cookie)];
|
NSArray *event = RCTProfileOngoingEvents[@(cookie)];
|
||||||
if (event) {
|
if (event) {
|
||||||
|
@ -358,12 +432,17 @@ void RCTProfileEndAsyncEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
void RCTProfileImmediateEvent(
|
void RCTProfileImmediateEvent(
|
||||||
__unused uint64_t tag,
|
uint64_t tag,
|
||||||
NSString *name,
|
NSString *name,
|
||||||
char scope
|
char scope
|
||||||
) {
|
) {
|
||||||
CHECK();
|
CHECK();
|
||||||
|
|
||||||
|
if (callbacks != NULL) {
|
||||||
|
callbacks->instant_section(tag, name.UTF8String, scope);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RCTProfileLock(
|
RCTProfileLock(
|
||||||
RCTProfileAddEvent(RCTProfileTraceEvents,
|
RCTProfileAddEvent(RCTProfileTraceEvents,
|
||||||
@"name": name,
|
@"name": name,
|
||||||
|
@ -380,6 +459,12 @@ NSNumber *_RCTProfileBeginFlowEvent(void)
|
||||||
static NSUInteger flowID = 0;
|
static NSUInteger flowID = 0;
|
||||||
|
|
||||||
CHECK(@0);
|
CHECK(@0);
|
||||||
|
|
||||||
|
if (callbacks != NULL) {
|
||||||
|
// flow events not supported yet
|
||||||
|
return @0;
|
||||||
|
}
|
||||||
|
|
||||||
RCTProfileAddEvent(RCTProfileTraceEvents,
|
RCTProfileAddEvent(RCTProfileTraceEvents,
|
||||||
@"name": @"flow",
|
@"name": @"flow",
|
||||||
@"id": @(++flowID),
|
@"id": @(++flowID),
|
||||||
|
@ -394,6 +479,11 @@ NSNumber *_RCTProfileBeginFlowEvent(void)
|
||||||
void _RCTProfileEndFlowEvent(NSNumber *flowID)
|
void _RCTProfileEndFlowEvent(NSNumber *flowID)
|
||||||
{
|
{
|
||||||
CHECK();
|
CHECK();
|
||||||
|
|
||||||
|
if (callbacks != NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RCTProfileAddEvent(RCTProfileTraceEvents,
|
RCTProfileAddEvent(RCTProfileTraceEvents,
|
||||||
@"name": @"flow",
|
@"name": @"flow",
|
||||||
@"id": flowID,
|
@"id": flowID,
|
||||||
|
|
Loading…
Reference in New Issue