mirror of
https://github.com/status-im/react-native.git
synced 2025-02-25 07:35:25 +00:00
Improve systrace markers
Reviewed By: mhorowitz Differential Revision: D4860135 fbshipit-source-id: ce963010883e6b9cc8e34f7ff01b4018cd195eba
This commit is contained in:
parent
49e6d3965f
commit
6221053179
@ -54,7 +54,7 @@
|
|||||||
RCTAssert(self.executorClass || self->_jsThread == [NSThread currentThread], \
|
RCTAssert(self.executorClass || self->_jsThread == [NSThread currentThread], \
|
||||||
@"This method must be called on JS thread")
|
@"This method must be called on JS thread")
|
||||||
|
|
||||||
NSString *const RCTJSThreadName = @"com.facebook.React.JavaScript";
|
static NSString *const RCTJSThreadName = @"com.facebook.react.JavaScript";
|
||||||
|
|
||||||
using namespace facebook::react;
|
using namespace facebook::react;
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ static bool isRAMBundle(NSData *script) {
|
|||||||
|
|
||||||
static void registerPerformanceLoggerHooks(RCTPerformanceLogger *performanceLogger) {
|
static void registerPerformanceLoggerHooks(RCTPerformanceLogger *performanceLogger) {
|
||||||
__weak RCTPerformanceLogger *weakPerformanceLogger = performanceLogger;
|
__weak RCTPerformanceLogger *weakPerformanceLogger = performanceLogger;
|
||||||
ReactMarker::logTaggedMarker = [weakPerformanceLogger](const ReactMarker::ReactMarkerId markerId, const char* tag) {
|
ReactMarker::logTaggedMarker = [weakPerformanceLogger](const ReactMarker::ReactMarkerId markerId, const char *tag) {
|
||||||
switch (markerId) {
|
switch (markerId) {
|
||||||
case ReactMarker::RUN_JS_BUNDLE_START:
|
case ReactMarker::RUN_JS_BUNDLE_START:
|
||||||
[weakPerformanceLogger markStartForTag:RCTPLScriptExecution];
|
[weakPerformanceLogger markStartForTag:RCTPLScriptExecution];
|
||||||
@ -255,6 +255,8 @@ struct RCTInstanceCallback : public InstanceCallback {
|
|||||||
|
|
||||||
- (void)start
|
- (void)start
|
||||||
{
|
{
|
||||||
|
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTCxxBridge start]", nil);
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter]
|
[[NSNotificationCenter defaultCenter]
|
||||||
postNotificationName:RCTJavaScriptWillStartLoadingNotification
|
postNotificationName:RCTJavaScriptWillStartLoadingNotification
|
||||||
object:_parentBridge userInfo:@{@"bridge": self}];
|
object:_parentBridge userInfo:@{@"bridge": self}];
|
||||||
@ -349,6 +351,7 @@ struct RCTInstanceCallback : public InstanceCallback {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)loadSource:(RCTSourceLoadBlock)_onSourceLoad onProgress:(RCTSourceLoadProgressBlock)onProgress
|
- (void)loadSource:(RCTSourceLoadBlock)_onSourceLoad onProgress:(RCTSourceLoadProgressBlock)onProgress
|
||||||
@ -963,7 +966,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
|
|||||||
|
|
||||||
[_performanceLogger markStopForTag:RCTPLBridgeStartup];
|
[_performanceLogger markStopForTag:RCTPLBridgeStartup];
|
||||||
|
|
||||||
RCT_PROFILE_BEGIN_EVENT(0, @"Processing pendingCalls", @{ @"count": @(_pendingCalls.count) });
|
RCT_PROFILE_BEGIN_EVENT(0, @"Processing pendingCalls", @{ @"count": [@(_pendingCalls.count) stringValue] });
|
||||||
// Phase B: _flushPendingCalls happens. Each block in _pendingCalls is
|
// Phase B: _flushPendingCalls happens. Each block in _pendingCalls is
|
||||||
// executed, adding work to the queue, and _pendingCount is decremented.
|
// executed, adding work to the queue, and _pendingCount is decremented.
|
||||||
// loading is set to NO.
|
// loading is set to NO.
|
||||||
@ -1051,8 +1054,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
|
|||||||
{
|
{
|
||||||
RCTAssert(onComplete != nil, @"onComplete block passed in should be non-nil");
|
RCTAssert(onComplete != nil, @"onComplete block passed in should be non-nil");
|
||||||
|
|
||||||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways,
|
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[RCTCxxBridge enqueueApplicationScript]", nil);
|
||||||
@"-[RCTCxxBridge enqueueApplicationScript]", nil);
|
|
||||||
|
|
||||||
[self _tryAndHandleError:^{
|
[self _tryAndHandleError:^{
|
||||||
if (isRAMBundle(script)) {
|
if (isRAMBundle(script)) {
|
||||||
|
@ -20,7 +20,7 @@ class RCTNativeModule : public NativeModule {
|
|||||||
std::string getName() override;
|
std::string getName() override;
|
||||||
std::vector<MethodDescriptor> getMethods() override;
|
std::vector<MethodDescriptor> getMethods() override;
|
||||||
folly::dynamic getConstants() override;
|
folly::dynamic getConstants() override;
|
||||||
void invoke(unsigned int methodId, folly::dynamic &¶ms) override;
|
void invoke(unsigned int methodId, folly::dynamic &¶ms, int callId) override;
|
||||||
MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic &¶ms) override;
|
MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic &¶ms) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
#import <React/RCTProfile.h>
|
#import <React/RCTProfile.h>
|
||||||
#import <React/RCTUtils.h>
|
#import <React/RCTUtils.h>
|
||||||
|
|
||||||
|
#ifdef WITH_FBSYSTRACE
|
||||||
|
#include <fbsystrace.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
|
|
||||||
@ -50,20 +54,20 @@ folly::dynamic RCTNativeModule::getConstants() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &¶ms) {
|
void RCTNativeModule::invoke(unsigned int methodId, folly::dynamic &¶ms, int callId) {
|
||||||
// The BatchedBridge version of this buckets all the callbacks by thread, and
|
// The BatchedBridge version of this buckets all the callbacks by thread, and
|
||||||
// queues one block on each. This is much simpler; we'll see how it goes and
|
// queues one block on each. This is much simpler; we'll see how it goes and
|
||||||
// iterate.
|
// iterate.
|
||||||
dispatch_block_t block = [this, methodId, params=std::move(params)] {
|
dispatch_block_t block = [this, methodId, params=std::move(params), callId] {
|
||||||
if (!m_bridge.valid) {
|
#ifdef WITH_FBSYSTRACE
|
||||||
return;
|
if (callId != -1) {
|
||||||
|
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
invokeInner(methodId, std::move(params));
|
invokeInner(methodId, std::move(params));
|
||||||
};
|
};
|
||||||
|
|
||||||
dispatch_queue_t queue = m_moduleData.methodQueue;
|
dispatch_queue_t queue = m_moduleData.methodQueue;
|
||||||
|
|
||||||
if (queue == RCTJSThread) {
|
if (queue == RCTJSThread) {
|
||||||
block();
|
block();
|
||||||
} else if (queue) {
|
} else if (queue) {
|
||||||
@ -76,6 +80,10 @@ MethodCallResult RCTNativeModule::callSerializableNativeHook(unsigned int reactM
|
|||||||
}
|
}
|
||||||
|
|
||||||
MethodCallResult RCTNativeModule::invokeInner(unsigned int methodId, const folly::dynamic &¶ms) {
|
MethodCallResult RCTNativeModule::invokeInner(unsigned int methodId, const folly::dynamic &¶ms) {
|
||||||
|
if (!m_bridge.valid) {
|
||||||
|
return folly::none;
|
||||||
|
}
|
||||||
|
|
||||||
id<RCTBridgeMethod> method = m_moduleData.methods[methodId];
|
id<RCTBridgeMethod> method = m_moduleData.methods[methodId];
|
||||||
if (RCT_DEBUG && !method) {
|
if (RCT_DEBUG && !method) {
|
||||||
RCTLogError(@"Unknown methodID: %ud for module: %@",
|
RCTLogError(@"Unknown methodID: %ud for module: %@",
|
||||||
@ -83,7 +91,6 @@ MethodCallResult RCTNativeModule::invokeInner(unsigned int methodId, const folly
|
|||||||
}
|
}
|
||||||
|
|
||||||
NSArray *objcParams = convertFollyDynamicToId(params);
|
NSArray *objcParams = convertFollyDynamicToId(params);
|
||||||
|
|
||||||
@try {
|
@try {
|
||||||
id result = [method invokeWithBridge:m_bridge module:m_moduleData.instance arguments:objcParams];
|
id result = [method invokeWithBridge:m_bridge module:m_moduleData.instance arguments:objcParams];
|
||||||
return convertIdToFollyDynamic(result);
|
return convertIdToFollyDynamic(result);
|
||||||
@ -99,7 +106,6 @@ MethodCallResult RCTNativeModule::invokeInner(unsigned int methodId, const folly
|
|||||||
exception, method.JSMethodName, m_moduleData.name, objcParams];
|
exception, method.JSMethodName, m_moduleData.name, objcParams];
|
||||||
RCTFatal(RCTErrorWithMessage(message));
|
RCTFatal(RCTErrorWithMessage(message));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
#import "RCTRootViewInternal.h"
|
#import "RCTRootViewInternal.h"
|
||||||
#import "RCTScrollableProtocol.h"
|
#import "RCTScrollableProtocol.h"
|
||||||
#import "RCTShadowView.h"
|
#import "RCTShadowView.h"
|
||||||
#import "RCTUtils.h"
|
|
||||||
#import "RCTUIManagerObserverCoordinator.h"
|
#import "RCTUIManagerObserverCoordinator.h"
|
||||||
|
#import "RCTUtils.h"
|
||||||
#import "RCTView.h"
|
#import "RCTView.h"
|
||||||
#import "RCTViewManager.h"
|
#import "RCTViewManager.h"
|
||||||
#import "UIView+React.h"
|
#import "UIView+React.h"
|
||||||
@ -1192,7 +1192,7 @@ RCT_EXPORT_METHOD(dispatchViewManagerCommand:(nonnull NSNumber *)reactTag
|
|||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
RCTProfileEndFlowEvent();
|
RCTProfileEndFlowEvent();
|
||||||
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[UIManager flushUIBlocks]", (@{
|
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"-[UIManager flushUIBlocks]", (@{
|
||||||
@"count": @(previousPendingUIBlocks.count),
|
@"count": [@(previousPendingUIBlocks.count) stringValue],
|
||||||
}));
|
}));
|
||||||
@try {
|
@try {
|
||||||
for (RCTViewManagerUIBlock block in previousPendingUIBlocks) {
|
for (RCTViewManagerUIBlock block in previousPendingUIBlocks) {
|
||||||
@ -1202,6 +1202,7 @@ RCT_EXPORT_METHOD(dispatchViewManagerCommand:(nonnull NSNumber *)reactTag
|
|||||||
@catch (NSException *exception) {
|
@catch (NSException *exception) {
|
||||||
RCTLogError(@"Exception thrown while executing UI block: %@", exception);
|
RCTLogError(@"Exception thrown while executing UI block: %@", exception);
|
||||||
}
|
}
|
||||||
|
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ RCT_EXTERN void _RCTProfileBeginEvent(NSThread *calleeThread,
|
|||||||
NSTimeInterval time,
|
NSTimeInterval time,
|
||||||
uint64_t tag,
|
uint64_t tag,
|
||||||
NSString *name,
|
NSString *name,
|
||||||
NSDictionary *args);
|
NSDictionary<NSString *, NSString *> *args);
|
||||||
#define RCT_PROFILE_BEGIN_EVENT(tag, name, args) \
|
#define RCT_PROFILE_BEGIN_EVENT(tag, name, args) \
|
||||||
do { \
|
do { \
|
||||||
if (RCTProfileIsProfiling()) { \
|
if (RCTProfileIsProfiling()) { \
|
||||||
@ -104,7 +104,7 @@ RCT_EXTERN void _RCTProfileEndEvent(NSThread *calleeThread,
|
|||||||
*/
|
*/
|
||||||
RCT_EXTERN NSUInteger RCTProfileBeginAsyncEvent(uint64_t tag,
|
RCT_EXTERN NSUInteger RCTProfileBeginAsyncEvent(uint64_t tag,
|
||||||
NSString *name,
|
NSString *name,
|
||||||
NSDictionary *args);
|
NSDictionary<NSString *, NSString *> *args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ID returned by BeginEvent should then be passed into EndEvent, with the
|
* The ID returned by BeginEvent should then be passed into EndEvent, with the
|
||||||
|
@ -71,7 +71,7 @@ if (!RCTProfileIsProfiling()) { \
|
|||||||
static RCTProfileCallbacks *callbacks;
|
static RCTProfileCallbacks *callbacks;
|
||||||
static char *systrace_buffer;
|
static char *systrace_buffer;
|
||||||
|
|
||||||
static systrace_arg_t *RCTProfileSystraceArgsFromNSDictionary(NSDictionary *args)
|
static systrace_arg_t *systraceArgsFromDictionary(NSDictionary<NSString *, NSString *> *args)
|
||||||
{
|
{
|
||||||
if (args.count == 0) {
|
if (args.count == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -79,14 +79,11 @@ static systrace_arg_t *RCTProfileSystraceArgsFromNSDictionary(NSDictionary *args
|
|||||||
|
|
||||||
systrace_arg_t *systrace_args = malloc(sizeof(systrace_arg_t) * args.count);
|
systrace_arg_t *systrace_args = malloc(sizeof(systrace_arg_t) * args.count);
|
||||||
__block size_t i = 0;
|
__block size_t i = 0;
|
||||||
[args enumerateKeysAndObjectsUsingBlock:^(id key, id value, __unused BOOL *stop) {
|
[args enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *value, __unused BOOL *stop) {
|
||||||
const char *keyc = [key description].UTF8String;
|
systrace_args[i].key = [key UTF8String];
|
||||||
systrace_args[i].key = keyc;
|
systrace_args[i].key_len = [key length];
|
||||||
systrace_args[i].key_len = (int)strlen(keyc);
|
systrace_args[i].value = [value UTF8String];
|
||||||
|
systrace_args[i].value_len = [value length];
|
||||||
const char *valuec = RCTJSONStringify(value, NULL).UTF8String;
|
|
||||||
systrace_args[i].value = valuec;
|
|
||||||
systrace_args[i].value_len = (int)strlen(valuec);
|
|
||||||
i++;
|
i++;
|
||||||
}];
|
}];
|
||||||
return systrace_args;
|
return systrace_args;
|
||||||
@ -123,7 +120,7 @@ static NSDictionary *RCTProfileGetMemoryUsage(void)
|
|||||||
TASK_BASIC_INFO,
|
TASK_BASIC_INFO,
|
||||||
(task_info_t)&info,
|
(task_info_t)&info,
|
||||||
&size);
|
&size);
|
||||||
if( kerr == KERN_SUCCESS ) {
|
if ( kerr == KERN_SUCCESS ) {
|
||||||
return @{
|
return @{
|
||||||
@"suspend_count": @(info.suspend_count),
|
@"suspend_count": @(info.suspend_count),
|
||||||
@"virtual_size": RCTProfileMemory(info.virtual_size),
|
@"virtual_size": RCTProfileMemory(info.virtual_size),
|
||||||
@ -545,12 +542,12 @@ void _RCTProfileBeginEvent(
|
|||||||
NSTimeInterval time,
|
NSTimeInterval time,
|
||||||
uint64_t tag,
|
uint64_t tag,
|
||||||
NSString *name,
|
NSString *name,
|
||||||
NSDictionary *args
|
NSDictionary<NSString *, NSString *> *args
|
||||||
) {
|
) {
|
||||||
CHECK();
|
CHECK();
|
||||||
|
|
||||||
if (callbacks != NULL) {
|
if (callbacks != NULL) {
|
||||||
callbacks->begin_section(tag, name.UTF8String, args.count, RCTProfileSystraceArgsFromNSDictionary(args));
|
callbacks->begin_section(tag, name.UTF8String, args.count, systraceArgsFromDictionary(args));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,7 +600,7 @@ void _RCTProfileEndEvent(
|
|||||||
NSUInteger RCTProfileBeginAsyncEvent(
|
NSUInteger RCTProfileBeginAsyncEvent(
|
||||||
uint64_t tag,
|
uint64_t tag,
|
||||||
NSString *name,
|
NSString *name,
|
||||||
NSDictionary *args
|
NSDictionary<NSString *, NSString *> *args
|
||||||
) {
|
) {
|
||||||
CHECK(0);
|
CHECK(0);
|
||||||
|
|
||||||
@ -613,7 +610,8 @@ NSUInteger RCTProfileBeginAsyncEvent(
|
|||||||
NSUInteger currentEventID = ++eventID;
|
NSUInteger currentEventID = ++eventID;
|
||||||
|
|
||||||
if (callbacks != NULL) {
|
if (callbacks != NULL) {
|
||||||
callbacks->begin_async_section(tag, name.UTF8String, (int)(currentEventID % INT_MAX), args.count, RCTProfileSystraceArgsFromNSDictionary(args));
|
callbacks->begin_async_section(tag, name.UTF8String, (int)(currentEventID % INT_MAX),
|
||||||
|
args.count, systraceArgsFromDictionary(args));
|
||||||
} else {
|
} else {
|
||||||
dispatch_async(RCTProfileGetQueue(), ^{
|
dispatch_async(RCTProfileGetQueue(), ^{
|
||||||
RCTProfileOngoingEvents[@(currentEventID)] = @[
|
RCTProfileOngoingEvents[@(currentEventID)] = @[
|
||||||
|
@ -10,6 +10,10 @@
|
|||||||
#include <cxxreact/JsArgumentHelpers.h>
|
#include <cxxreact/JsArgumentHelpers.h>
|
||||||
#include <cxxreact/NativeModule.h>
|
#include <cxxreact/NativeModule.h>
|
||||||
|
|
||||||
|
#ifdef WITH_FBSYSTRACE
|
||||||
|
#include <fbsystrace.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "CatalystInstanceImpl.h"
|
#include "CatalystInstanceImpl.h"
|
||||||
#include "ReadableNativeArray.h"
|
#include "ReadableNativeArray.h"
|
||||||
|
|
||||||
@ -80,9 +84,14 @@ folly::dynamic JavaNativeModule::getConstants() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params) {
|
void JavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) {
|
||||||
messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params)] {
|
messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params), callId] {
|
||||||
static auto invokeMethod = wrapper_->getClass()->getMethod<void(jint, ReadableNativeArray::javaobject)>("invoke");
|
static auto invokeMethod = wrapper_->getClass()->getMethod<void(jint, ReadableNativeArray::javaobject)>("invoke");
|
||||||
|
#ifdef WITH_FBSYSTRACE
|
||||||
|
if (callId != -1) {
|
||||||
|
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
invokeMethod(
|
invokeMethod(
|
||||||
wrapper_,
|
wrapper_,
|
||||||
static_cast<jint>(reactMethodId),
|
static_cast<jint>(reactMethodId),
|
||||||
@ -148,13 +157,18 @@ folly::dynamic NewJavaNativeModule::getConstants() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewJavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params) {
|
void NewJavaNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) {
|
||||||
if (reactMethodId >= methods_.size()) {
|
if (reactMethodId >= methods_.size()) {
|
||||||
throw std::invalid_argument(
|
throw std::invalid_argument(
|
||||||
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]"));
|
folly::to<std::string>("methodId ", reactMethodId, " out of range [0..", methods_.size(), "]"));
|
||||||
}
|
}
|
||||||
CHECK(!methods_[reactMethodId].isSyncHook()) << "Trying to invoke a synchronous hook asynchronously";
|
CHECK(!methods_[reactMethodId].isSyncHook()) << "Trying to invoke a synchronous hook asynchronously";
|
||||||
messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params)] () mutable {
|
messageQueueThread_->runOnQueue([this, reactMethodId, params=std::move(params), callId] () mutable {
|
||||||
|
#ifdef WITH_FBSYSTRACE
|
||||||
|
if (callId != -1) {
|
||||||
|
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
invokeInner(reactMethodId, std::move(params));
|
invokeInner(reactMethodId, std::move(params));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ class JavaNativeModule : public NativeModule {
|
|||||||
std::string getName() override;
|
std::string getName() override;
|
||||||
folly::dynamic getConstants() override;
|
folly::dynamic getConstants() override;
|
||||||
std::vector<MethodDescriptor> getMethods() override;
|
std::vector<MethodDescriptor> getMethods() override;
|
||||||
void invoke(unsigned int reactMethodId, folly::dynamic&& params) override;
|
void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) override;
|
||||||
MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) override;
|
MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -80,7 +80,7 @@ class NewJavaNativeModule : public NativeModule {
|
|||||||
std::string getName() override;
|
std::string getName() override;
|
||||||
std::vector<MethodDescriptor> getMethods() override;
|
std::vector<MethodDescriptor> getMethods() override;
|
||||||
folly::dynamic getConstants() override;
|
folly::dynamic getConstants() override;
|
||||||
void invoke(unsigned int reactMethodId, folly::dynamic&& params) override;
|
void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) override;
|
||||||
MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) override;
|
MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& params) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -7,7 +7,8 @@
|
|||||||
|
|
||||||
#include <folly/json.h>
|
#include <folly/json.h>
|
||||||
|
|
||||||
#include <cxxreact/JsArgumentHelpers.h>
|
#include "JsArgumentHelpers.h"
|
||||||
|
#include "SystraceSection.h"
|
||||||
|
|
||||||
using facebook::xplat::module::CxxModule;
|
using facebook::xplat::module::CxxModule;
|
||||||
|
|
||||||
@ -75,7 +76,7 @@ folly::dynamic CxxNativeModule::getConstants() {
|
|||||||
return constants;
|
return constants;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CxxNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params) {
|
void CxxNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) {
|
||||||
if (reactMethodId >= methods_.size()) {
|
if (reactMethodId >= methods_.size()) {
|
||||||
throw std::invalid_argument(folly::to<std::string>("methodId ", reactMethodId,
|
throw std::invalid_argument(folly::to<std::string>("methodId ", reactMethodId,
|
||||||
" out of range [0..", methods_.size(), "]"));
|
" out of range [0..", methods_.size(), "]"));
|
||||||
@ -128,7 +129,13 @@ void CxxNativeModule::invoke(unsigned int reactMethodId, folly::dynamic&& params
|
|||||||
// stack. I'm told that will be possible in the future. TODO
|
// stack. I'm told that will be possible in the future. TODO
|
||||||
// mhorowitz #7128529: convert C++ exceptions to Java
|
// mhorowitz #7128529: convert C++ exceptions to Java
|
||||||
|
|
||||||
messageQueueThread_->runOnQueue([method, params=std::move(params), first, second] () {
|
messageQueueThread_->runOnQueue([method, params=std::move(params), first, second, callId] () {
|
||||||
|
#ifdef WITH_FBSYSTRACE
|
||||||
|
if (callId != -1) {
|
||||||
|
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
SystraceSection s(method.name.c_str());
|
||||||
try {
|
try {
|
||||||
method.func(std::move(params), first, second);
|
method.func(std::move(params), first, second);
|
||||||
} catch (const facebook::xplat::JsArgumentException& ex) {
|
} catch (const facebook::xplat::JsArgumentException& ex) {
|
||||||
|
@ -27,7 +27,7 @@ public:
|
|||||||
std::string getName() override;
|
std::string getName() override;
|
||||||
std::vector<MethodDescriptor> getMethods() override;
|
std::vector<MethodDescriptor> getMethods() override;
|
||||||
folly::dynamic getConstants() override;
|
folly::dynamic getConstants() override;
|
||||||
void invoke(unsigned int reactMethodId, folly::dynamic&& params) override;
|
void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) override;
|
||||||
MethodCallResult callSerializableNativeHook(unsigned int hookId, folly::dynamic&& args) override;
|
MethodCallResult callSerializableNativeHook(unsigned int hookId, folly::dynamic&& args) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -182,7 +182,7 @@ static bool canUseInspector(JSContextRef context) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void JSCExecutor::initOnJSVMThread() throw(JSException) {
|
void JSCExecutor::initOnJSVMThread() throw(JSException) {
|
||||||
SystraceSection s("JSCExecutor.initOnJSVMThread");
|
SystraceSection s("JSCExecutor::initOnJSVMThread");
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
const bool useCustomJSC = m_jscConfig.getDefault("UseCustomJSC", false).getBool();
|
const bool useCustomJSC = m_jscConfig.getDefault("UseCustomJSC", false).getBool();
|
||||||
@ -353,20 +353,15 @@ void JSCExecutor::loadApplicationScript(std::unique_ptr<const JSBigString> scrip
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef WITH_FBSYSTRACE
|
String jsScript;
|
||||||
fbsystrace_begin_section(
|
{
|
||||||
TRACE_TAG_REACT_CXX_BRIDGE,
|
SystraceSection s_("JSCExecutor::loadApplicationScript-createExpectingAscii");
|
||||||
"JSCExecutor::loadApplicationScript-createExpectingAscii");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ReactMarker::logMarker(ReactMarker::JS_BUNDLE_STRING_CONVERT_START);
|
ReactMarker::logMarker(ReactMarker::JS_BUNDLE_STRING_CONVERT_START);
|
||||||
String jsScript = jsStringFromBigString(m_context, *script);
|
jsScript = jsStringFromBigString(m_context, *script);
|
||||||
ReactMarker::logMarker(ReactMarker::JS_BUNDLE_STRING_CONVERT_STOP);
|
ReactMarker::logMarker(ReactMarker::JS_BUNDLE_STRING_CONVERT_STOP);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WITH_FBSYSTRACE
|
SystraceSection s_("JSCExecutor::loadApplicationScript-evaluateScript");
|
||||||
fbsystrace_end_section(TRACE_TAG_REACT_CXX_BRIDGE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
evaluateScript(m_context, jsScript, jsSourceURL);
|
evaluateScript(m_context, jsScript, jsSourceURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,9 +452,9 @@ void JSCExecutor::flush() {
|
|||||||
|
|
||||||
void JSCExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) {
|
void JSCExecutor::callFunction(const std::string& moduleId, const std::string& methodId, const folly::dynamic& arguments) {
|
||||||
SystraceSection s("JSCExecutor::callFunction");
|
SystraceSection s("JSCExecutor::callFunction");
|
||||||
|
|
||||||
// This weird pattern is because Value is not default constructible.
|
// This weird pattern is because Value is not default constructible.
|
||||||
// The lambda is inlined, so there's no overhead.
|
// The lambda is inlined, so there's no overhead.
|
||||||
|
|
||||||
auto result = [&] {
|
auto result = [&] {
|
||||||
try {
|
try {
|
||||||
if (!m_callFunctionReturnResultAndFlushedQueueJS) {
|
if (!m_callFunctionReturnResultAndFlushedQueueJS) {
|
||||||
@ -524,8 +519,7 @@ Value JSCExecutor::callFunctionSyncWithValue(
|
|||||||
|
|
||||||
void JSCExecutor::setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue) {
|
void JSCExecutor::setGlobalVariable(std::string propName, std::unique_ptr<const JSBigString> jsonValue) {
|
||||||
try {
|
try {
|
||||||
SystraceSection s("JSCExecutor.setGlobalVariable",
|
SystraceSection s("JSCExecutor::setGlobalVariable", "propName", propName);
|
||||||
"propName", propName);
|
|
||||||
|
|
||||||
auto valueToInject = Value::fromJSON(m_context, jsStringFromBigString(m_context, *jsonValue));
|
auto valueToInject = Value::fromJSON(m_context, jsStringFromBigString(m_context, *jsonValue));
|
||||||
Object::getGlobalObject(m_context).setProperty(propName.c_str(), valueToInject);
|
Object::getGlobalObject(m_context).setProperty(propName.c_str(), valueToInject);
|
||||||
|
@ -118,14 +118,7 @@ void ModuleRegistry::callNativeMethod(unsigned int moduleId, unsigned int method
|
|||||||
throw std::runtime_error(
|
throw std::runtime_error(
|
||||||
folly::to<std::string>("moduleId ", moduleId, " out of range [0..", modules_.size(), ")"));
|
folly::to<std::string>("moduleId ", moduleId, " out of range [0..", modules_.size(), ")"));
|
||||||
}
|
}
|
||||||
|
modules_[moduleId]->invoke(methodId, std::move(params), callId);
|
||||||
#ifdef WITH_FBSYSTRACE
|
|
||||||
if (callId != -1) {
|
|
||||||
fbsystrace_end_async_flow(TRACE_TAG_REACT_APPS, "native", callId);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
modules_[moduleId]->invoke(methodId, std::move(params));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodCallResult ModuleRegistry::callSerializableNativeHook(unsigned int moduleId, unsigned int methodId, folly::dynamic&& params) {
|
MethodCallResult ModuleRegistry::callSerializableNativeHook(unsigned int moduleId, unsigned int methodId, folly::dynamic&& params) {
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <folly/dynamic.h>
|
|
||||||
#include <cxxreact/Executor.h>
|
#include <cxxreact/Executor.h>
|
||||||
|
#include <folly/dynamic.h>
|
||||||
|
|
||||||
namespace facebook {
|
namespace facebook {
|
||||||
namespace react {
|
namespace react {
|
||||||
@ -29,7 +29,7 @@ class NativeModule {
|
|||||||
virtual folly::dynamic getConstants() = 0;
|
virtual folly::dynamic getConstants() = 0;
|
||||||
// TODO mhorowitz: do we need initialize()/onCatalystInstanceDestroy() in C++
|
// TODO mhorowitz: do we need initialize()/onCatalystInstanceDestroy() in C++
|
||||||
// or only Java?
|
// or only Java?
|
||||||
virtual void invoke(unsigned int reactMethodId, folly::dynamic&& params) = 0;
|
virtual void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) = 0;
|
||||||
virtual MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& args) = 0;
|
virtual MethodCallResult callSerializableNativeHook(unsigned int reactMethodId, folly::dynamic&& args) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,27 +124,21 @@ void NativeToJsBridge::callFunction(
|
|||||||
int systraceCookie = -1;
|
int systraceCookie = -1;
|
||||||
#ifdef WITH_FBSYSTRACE
|
#ifdef WITH_FBSYSTRACE
|
||||||
systraceCookie = m_systraceCookie++;
|
systraceCookie = m_systraceCookie++;
|
||||||
std::string tracingName = fbsystrace_is_tracing(TRACE_TAG_REACT_CXX_BRIDGE) ?
|
|
||||||
folly::to<std::string>("JSCall__", module, '_', method) : std::string();
|
|
||||||
SystraceSection s(tracingName.c_str());
|
|
||||||
FbSystraceAsyncFlow::begin(
|
FbSystraceAsyncFlow::begin(
|
||||||
TRACE_TAG_REACT_CXX_BRIDGE,
|
TRACE_TAG_REACT_CXX_BRIDGE,
|
||||||
tracingName.c_str(),
|
"JSCall",
|
||||||
systraceCookie);
|
systraceCookie);
|
||||||
#else
|
|
||||||
std::string tracingName;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
runOnExecutorQueue([module = std::move(module), method = std::move(method), arguments = std::move(arguments), tracingName = std::move(tracingName), systraceCookie]
|
runOnExecutorQueue([module = std::move(module), method = std::move(method), arguments = std::move(arguments), systraceCookie]
|
||||||
(JSExecutor* executor) {
|
(JSExecutor* executor) {
|
||||||
#ifdef WITH_FBSYSTRACE
|
#ifdef WITH_FBSYSTRACE
|
||||||
FbSystraceAsyncFlow::end(
|
FbSystraceAsyncFlow::end(
|
||||||
TRACE_TAG_REACT_CXX_BRIDGE,
|
TRACE_TAG_REACT_CXX_BRIDGE,
|
||||||
tracingName.c_str(),
|
"JSCall",
|
||||||
systraceCookie);
|
systraceCookie);
|
||||||
SystraceSection s(tracingName.c_str());
|
SystraceSection s("NativeToJsBridge::callFunction", "module", module, "method", method);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// This is safe because we are running on the executor's thread: it won't
|
// This is safe because we are running on the executor's thread: it won't
|
||||||
// destruct until after it's been unregistered (which we check above) and
|
// destruct until after it's been unregistered (which we check above) and
|
||||||
// that will happen on this thread
|
// that will happen on this thread
|
||||||
@ -169,9 +163,8 @@ void NativeToJsBridge::invokeCallback(double callbackId, folly::dynamic&& argume
|
|||||||
TRACE_TAG_REACT_CXX_BRIDGE,
|
TRACE_TAG_REACT_CXX_BRIDGE,
|
||||||
"<callback>",
|
"<callback>",
|
||||||
systraceCookie);
|
systraceCookie);
|
||||||
SystraceSection s("NativeToJsBridge.invokeCallback");
|
SystraceSection s("NativeToJsBridge::invokeCallback");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
executor->invokeCallback(callbackId, arguments);
|
executor->invokeCallback(callbackId, arguments);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -123,9 +123,6 @@ void removeGlobal(JSGlobalContextRef ctx, const char* name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JSValueRef evaluateScript(JSContextRef context, JSStringRef script, JSStringRef source) {
|
JSValueRef evaluateScript(JSContextRef context, JSStringRef script, JSStringRef source) {
|
||||||
#ifdef WITH_FBSYSTRACE
|
|
||||||
fbsystrace::FbSystraceSection s(TRACE_TAG_REACT_CXX_BRIDGE, "evaluateScript");
|
|
||||||
#endif
|
|
||||||
JSValueRef exn, result;
|
JSValueRef exn, result;
|
||||||
result = JSC_JSEvaluateScript(context, script, NULL, source, 0, &exn);
|
result = JSC_JSEvaluateScript(context, script, NULL, source, 0, &exn);
|
||||||
if (result == nullptr) {
|
if (result == nullptr) {
|
||||||
|
@ -41,9 +41,10 @@ private:
|
|||||||
|
|
||||||
class String : public noncopyable {
|
class String : public noncopyable {
|
||||||
public:
|
public:
|
||||||
explicit String(JSContextRef context, const char* utf8) :
|
explicit String(): m_context(nullptr), m_string(nullptr) {} // dummy empty constructor
|
||||||
m_context(context), m_string(JSC_JSStringCreateWithUTF8CString(context, utf8))
|
|
||||||
{}
|
explicit String(JSContextRef context, const char* utf8)
|
||||||
|
: m_context(context), m_string(JSC_JSStringCreateWithUTF8CString(context, utf8)) {}
|
||||||
|
|
||||||
String(String&& other) :
|
String(String&& other) :
|
||||||
m_context(other.m_context), m_string(other.m_string)
|
m_context(other.m_context), m_string(other.m_string)
|
||||||
@ -65,18 +66,30 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String& operator=(String&& other) {
|
||||||
|
if (m_string) {
|
||||||
|
JSC_JSStringRelease(m_context, m_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_context = other.m_context;
|
||||||
|
m_string = other.m_string;
|
||||||
|
other.m_string = nullptr;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
operator JSStringRef() const {
|
operator JSStringRef() const {
|
||||||
return m_string;
|
return m_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Length in characters
|
// Length in characters
|
||||||
size_t length() const {
|
size_t length() const {
|
||||||
return JSC_JSStringGetLength(m_context, m_string);
|
return m_string ? JSC_JSStringGetLength(m_context, m_string) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Length in bytes of a null-terminated utf8 encoded value
|
// Length in bytes of a null-terminated utf8 encoded value
|
||||||
size_t utf8Size() const {
|
size_t utf8Size() const {
|
||||||
return JSC_JSStringGetMaximumUTF8CStringSize(m_context, m_string);
|
return m_string ? JSC_JSStringGetMaximumUTF8CStringSize(m_context, m_string) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -94,6 +107,9 @@ public:
|
|||||||
* https://mathiasbynens.be/notes/javascript-unicode
|
* https://mathiasbynens.be/notes/javascript-unicode
|
||||||
*/
|
*/
|
||||||
std::string str() const {
|
std::string str() const {
|
||||||
|
if (!m_string) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
const JSChar* utf16 = JSC_JSStringGetCharactersPtr(m_context, m_string);
|
const JSChar* utf16 = JSC_JSStringGetCharactersPtr(m_context, m_string);
|
||||||
size_t stringLength = JSC_JSStringGetLength(m_context, m_string);
|
size_t stringLength = JSC_JSStringGetLength(m_context, m_string);
|
||||||
return unicode::utf16toUTF8(utf16, stringLength);
|
return unicode::utf16toUTF8(utf16, stringLength);
|
||||||
@ -101,7 +117,7 @@ public:
|
|||||||
|
|
||||||
// Assumes that utf8 is null terminated
|
// Assumes that utf8 is null terminated
|
||||||
bool equals(const char* utf8) {
|
bool equals(const char* utf8) {
|
||||||
return JSC_JSStringIsEqualToUTF8CString(m_context, m_string, utf8);
|
return m_string ? JSC_JSStringIsEqualToUTF8CString(m_context, m_string, utf8) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This assumes ascii is nul-terminated.
|
// This assumes ascii is nul-terminated.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user