Skip to content

Commit

Permalink
[ReactNative] Add JSC profiler to Dev Menu
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tadeuzagallo committed Aug 28, 2015
1 parent e15f584 commit aee74ef
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 58 deletions.
17 changes: 2 additions & 15 deletions JSCLegacyProfiler/JSCLegacyProfiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,7 @@

extern "C" {

JSValueRef nativeProfilerStart(
JSContextRef ctx,
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);
void nativeProfilerStart(JSContextRef ctx, const char *title);
const char *nativeProfilerEnd(JSContextRef ctx, const char *title);

}
43 changes: 7 additions & 36 deletions JSCLegacyProfiler/JSCLegacyProfiler.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "OpaqueJSString.h"
#include "JSProfilerPrivate.h"
#include "JSStringRef.h"
#include "String.h"

#include <YAJL/yajl_gen.h>

Expand Down Expand Up @@ -114,48 +115,18 @@ static yajl_gen_status append_node_json(yajl_gen gen, const JSC::ProfileNode *no
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::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());
}

JSValueRef nativeProfilerStart(
JSContextRef ctx,
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);
void nativeProfilerStart(JSContextRef ctx, const char *title) {
JSStartProfiling(ctx, JSStringCreateWithUTF8CString(title));
}

JSValueRef nativeProfilerEnd(
JSContextRef ctx,
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);
const char *nativeProfilerEnd( JSContextRef ctx, const char *title) {
return JSEndProfilingAndRender(ctx, title);
}
2 changes: 0 additions & 2 deletions JSCLegacyProfiler/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,3 @@ armv7:
${HEADER_PATHS} \
-undefined dynamic_lookup \
./JSCLegacyProfiler.mm ./tmp/yajl.a

.PHONY: ios8
17 changes: 13 additions & 4 deletions React/Executors/RCTContextExecutor.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#import "RCTAssert.h"
#import "RCTDefines.h"
#import "RCTDevMenu.h"
#import "RCTLog.h"
#import "RCTProfile.h"
#import "RCTPerformanceLogger.h"
Expand Down Expand Up @@ -89,6 +90,7 @@ @implementation RCTContextExecutor
}

@synthesize valid = _valid;
@synthesize bridge = _bridge;

RCT_EXPORT_MODULE()

Expand Down Expand Up @@ -285,11 +287,18 @@ - (void)setUp
#if RCT_JSC_PROFILER
void *JSCProfiler = dlopen(RCT_JSC_PROFILER_DYLIB, RTLD_NOW);
if (JSCProfiler != NULL) {
JSObjectCallAsFunctionCallback nativeProfilerStart = dlsym(JSCProfiler, "nativeProfilerStart");
JSObjectCallAsFunctionCallback nativeProfilerEnd = dlsym(JSCProfiler, "nativeProfilerEnd");
void (*nativeProfilerStart)(JSContextRef, const char *) = (void (*)(JSContextRef, const char *))dlsym(JSCProfiler, "nativeProfilerStart");
const char *(*nativeProfilerEnd)(JSContextRef, const char *) = (const char *(*)(JSContextRef, const char *))dlsym(JSCProfiler, "nativeProfilerEnd");
if (nativeProfilerStart != NULL && nativeProfilerEnd != NULL) {
[strongSelf _addNativeHook:nativeProfilerStart withName:"nativeProfilerStart"];
[strongSelf _addNativeHook:nativeProfilerEnd withName:"nativeProfilerStop"];
__block BOOL isProfiling = NO;
[_bridge.devMenu addItem:@"Profile" handler:^{
if (isProfiling) {
RCTLogInfo(@"%s", nativeProfilerEnd(strongSelf->_context.ctx, "profile"));
} else {
nativeProfilerStart(strongSelf->_context.ctx, "profile");
}
isProfiling = !isProfiling;
}];
}
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion React/Modules/RCTDevMenu.m
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ - (NSArray *)menuItems
self.liveReloadEnabled = !_liveReloadEnabled;
}]];

NSString *profilingTitle = RCTProfileIsProfiling() ? @"Stop Profiling" : @"Start Profiling";
NSString *profilingTitle = RCTProfileIsProfiling() ? @"Stop Systrace" : @"Start Systrace";
[items addObject:[[RCTDevMenuItem alloc] initWithTitle:profilingTitle handler:^{
self.profilingEnabled = !_profilingEnabled;
}]];
Expand Down

0 comments on commit aee74ef

Please sign in to comment.