[ReactNative] Add JSC profiler to Dev Menu
Summary: Add JSC profiler to the dev menu and rename the pre-existent one to systrace. For now it just outputs to the console, but a better workflow is on the way.
This commit is contained in:
parent
e15f584a3d
commit
aee74efde7
|
@ -6,20 +6,7 @@
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
JSValueRef nativeProfilerStart(
|
void nativeProfilerStart(JSContextRef ctx, const char *title);
|
||||||
JSContextRef ctx,
|
const char *nativeProfilerEnd(JSContextRef ctx, const char *title);
|
||||||
JSObjectRef function,
|
|
||||||
JSObjectRef thisObject,
|
|
||||||
size_t argumentCount,
|
|
||||||
const JSValueRef arguments[],
|
|
||||||
JSValueRef *exception);
|
|
||||||
|
|
||||||
JSValueRef nativeProfilerEnd(
|
|
||||||
JSContextRef ctx,
|
|
||||||
JSObjectRef function,
|
|
||||||
JSObjectRef thisObject,
|
|
||||||
size_t argumentCount,
|
|
||||||
const JSValueRef arguments[],
|
|
||||||
JSValueRef *exception);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "OpaqueJSString.h"
|
#include "OpaqueJSString.h"
|
||||||
#include "JSProfilerPrivate.h"
|
#include "JSProfilerPrivate.h"
|
||||||
#include "JSStringRef.h"
|
#include "JSStringRef.h"
|
||||||
|
#include "String.h"
|
||||||
|
|
||||||
#include <YAJL/yajl_gen.h>
|
#include <YAJL/yajl_gen.h>
|
||||||
|
|
||||||
|
@ -114,48 +115,18 @@ static char *convert_to_json(const JSC::Profile *profile) {
|
||||||
return json_copy;
|
return json_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *JSEndProfilingAndRender(JSContextRef ctx, JSStringRef title)
|
static const char *JSEndProfilingAndRender(JSContextRef ctx, const char *title)
|
||||||
{
|
{
|
||||||
JSC::ExecState *exec = toJS(ctx);
|
JSC::ExecState *exec = toJS(ctx);
|
||||||
JSC::LegacyProfiler *profiler = JSC::LegacyProfiler::profiler();
|
JSC::LegacyProfiler *profiler = JSC::LegacyProfiler::profiler();
|
||||||
RefPtr<JSC::Profile> rawProfile = profiler->stopProfiling(exec, title->string());
|
RefPtr<JSC::Profile> rawProfile = profiler->stopProfiling(exec, WTF::String(title));
|
||||||
return convert_to_json(rawProfile.get());
|
return convert_to_json(rawProfile.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValueRef nativeProfilerStart(
|
void nativeProfilerStart(JSContextRef ctx, const char *title) {
|
||||||
JSContextRef ctx,
|
JSStartProfiling(ctx, JSStringCreateWithUTF8CString(title));
|
||||||
JSObjectRef function,
|
|
||||||
JSObjectRef thisObject,
|
|
||||||
size_t argumentCount,
|
|
||||||
const JSValueRef arguments[],
|
|
||||||
JSValueRef *exception) {
|
|
||||||
if (argumentCount < 1) {
|
|
||||||
// Could raise an exception here.
|
|
||||||
return JSValueMakeUndefined(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSStringRef title = JSValueToStringCopy(ctx, arguments[0], NULL);
|
|
||||||
JSStartProfiling(ctx, title);
|
|
||||||
JSStringRelease(title);
|
|
||||||
return JSValueMakeUndefined(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValueRef nativeProfilerEnd(
|
const char *nativeProfilerEnd( JSContextRef ctx, const char *title) {
|
||||||
JSContextRef ctx,
|
return JSEndProfilingAndRender(ctx, title);
|
||||||
JSObjectRef function,
|
|
||||||
JSObjectRef thisObject,
|
|
||||||
size_t argumentCount,
|
|
||||||
const JSValueRef arguments[],
|
|
||||||
JSValueRef *exception) {
|
|
||||||
if (argumentCount < 1) {
|
|
||||||
// Could raise an exception here.
|
|
||||||
return JSValueMakeUndefined(ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSStringRef title = JSValueToStringCopy(ctx, arguments[0], NULL);
|
|
||||||
char *rendered = JSEndProfilingAndRender(ctx, title);
|
|
||||||
JSStringRelease(title);
|
|
||||||
JSStringRef profile = JSStringCreateWithUTF8CString(rendered);
|
|
||||||
free(rendered);
|
|
||||||
return JSValueMakeString(ctx, profile);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,5 +110,3 @@ armv7:
|
||||||
${HEADER_PATHS} \
|
${HEADER_PATHS} \
|
||||||
-undefined dynamic_lookup \
|
-undefined dynamic_lookup \
|
||||||
./JSCLegacyProfiler.mm ./tmp/yajl.a
|
./JSCLegacyProfiler.mm ./tmp/yajl.a
|
||||||
|
|
||||||
.PHONY: ios8
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#import "RCTAssert.h"
|
#import "RCTAssert.h"
|
||||||
#import "RCTDefines.h"
|
#import "RCTDefines.h"
|
||||||
|
#import "RCTDevMenu.h"
|
||||||
#import "RCTLog.h"
|
#import "RCTLog.h"
|
||||||
#import "RCTProfile.h"
|
#import "RCTProfile.h"
|
||||||
#import "RCTPerformanceLogger.h"
|
#import "RCTPerformanceLogger.h"
|
||||||
|
@ -89,6 +90,7 @@ RCT_NOT_IMPLEMENTED(-(instancetype)init)
|
||||||
}
|
}
|
||||||
|
|
||||||
@synthesize valid = _valid;
|
@synthesize valid = _valid;
|
||||||
|
@synthesize bridge = _bridge;
|
||||||
|
|
||||||
RCT_EXPORT_MODULE()
|
RCT_EXPORT_MODULE()
|
||||||
|
|
||||||
|
@ -285,11 +287,18 @@ static JSValueRef RCTNativeTraceEndSection(JSContextRef context, __unused JSObje
|
||||||
#if RCT_JSC_PROFILER
|
#if RCT_JSC_PROFILER
|
||||||
void *JSCProfiler = dlopen(RCT_JSC_PROFILER_DYLIB, RTLD_NOW);
|
void *JSCProfiler = dlopen(RCT_JSC_PROFILER_DYLIB, RTLD_NOW);
|
||||||
if (JSCProfiler != NULL) {
|
if (JSCProfiler != NULL) {
|
||||||
JSObjectCallAsFunctionCallback nativeProfilerStart = dlsym(JSCProfiler, "nativeProfilerStart");
|
void (*nativeProfilerStart)(JSContextRef, const char *) = (void (*)(JSContextRef, const char *))dlsym(JSCProfiler, "nativeProfilerStart");
|
||||||
JSObjectCallAsFunctionCallback nativeProfilerEnd = dlsym(JSCProfiler, "nativeProfilerEnd");
|
const char *(*nativeProfilerEnd)(JSContextRef, const char *) = (const char *(*)(JSContextRef, const char *))dlsym(JSCProfiler, "nativeProfilerEnd");
|
||||||
if (nativeProfilerStart != NULL && nativeProfilerEnd != NULL) {
|
if (nativeProfilerStart != NULL && nativeProfilerEnd != NULL) {
|
||||||
[strongSelf _addNativeHook:nativeProfilerStart withName:"nativeProfilerStart"];
|
__block BOOL isProfiling = NO;
|
||||||
[strongSelf _addNativeHook:nativeProfilerEnd withName:"nativeProfilerStop"];
|
[_bridge.devMenu addItem:@"Profile" handler:^{
|
||||||
|
if (isProfiling) {
|
||||||
|
RCTLogInfo(@"%s", nativeProfilerEnd(strongSelf->_context.ctx, "profile"));
|
||||||
|
} else {
|
||||||
|
nativeProfilerStart(strongSelf->_context.ctx, "profile");
|
||||||
|
}
|
||||||
|
isProfiling = !isProfiling;
|
||||||
|
}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -314,7 +314,7 @@ RCT_EXPORT_MODULE()
|
||||||
self.liveReloadEnabled = !_liveReloadEnabled;
|
self.liveReloadEnabled = !_liveReloadEnabled;
|
||||||
}]];
|
}]];
|
||||||
|
|
||||||
NSString *profilingTitle = RCTProfileIsProfiling() ? @"Stop Profiling" : @"Start Profiling";
|
NSString *profilingTitle = RCTProfileIsProfiling() ? @"Stop Systrace" : @"Start Systrace";
|
||||||
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:profilingTitle handler:^{
|
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:profilingTitle handler:^{
|
||||||
self.profilingEnabled = !_profilingEnabled;
|
self.profilingEnabled = !_profilingEnabled;
|
||||||
}]];
|
}]];
|
||||||
|
|
Loading…
Reference in New Issue