Introduce TurboModulePerfLogger Java class

Summary:
We need to instrument the following markers for TurboModules in Java:
- **Java:** moduleDataCreate
- **Java:** moduleCreate

**Problem:** Perf-logging can be on or off in production. This means that we have to guard every perf-logger call, which can be a bit tedious. Therefore, this diff introduces a Java class called `TurboModulePerfLogger`, which:
1. Enables perf-logging by accepting a `NativeModulePerfLogger` `jni::HybridObject` in its `enableLogging` method.
2. Exposes static methods that call into the `NativeModulePerfLogger`'s Java part, when perf-logging is enabled.

We actually have C++ markers as well:
- **C++:** moduleJSRequireBeginning
- **C++:** moduleJSRequireEnding
- **C++:** syncMethodCall
- **C++:** asyncMethodCall
- **C++:** asyncMethodCallExecution

Therefore, `TurboModulePerfLogger.java` also calls its native method `jniEnableCppLogging` to setup C++ TurboModule perf-logging.

TurboModule C++ logging is done via a similar setup (to Java), using `TurboModulePerfLogger.cpp`. The `jniEnableCppLogging` native method calls into `TurboModulePerfLogger::enableLogging` with the C++ part of `NativeModulePerfLogger`. Then, the TurboModules C++ infra uses the static methods on `TurboModulePerfLogger.cpp` to start/end markers.

Changelog: [Internal]

Reviewed By: PeteTheHeat

Differential Revision: D22444246

fbshipit-source-id: 66f191056cdcf5d7932ff1916a1de70b82e5f32b
This commit is contained in:
Ramanpreet Nara
2020-07-11 09:36:33 -07:00
committed by Facebook GitHub Bot
parent c0dd11e532
commit 41d948c8d6
6 changed files with 101 additions and 1 deletions
@@ -22,6 +22,7 @@ rn_android_library(
react_native_dep("third-party/java/infer-annotations:infer-annotations"),
react_native_dep("third-party/java/jsr-305:jsr-305"),
react_native_target("java/com/facebook/react/common:common"),
react_native_target("java/com/facebook/react/reactperflogger:reactperflogger"),
react_native_target("java/com/facebook/react/turbomodule/core/jni:jni"),
react_native_target("java/com/facebook/debug/holder:holder"),
react_native_target("java/com/facebook/react/bridge:interfaces"),
@@ -0,0 +1,83 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package com.facebook.react.turbomodule.core;
import com.facebook.react.perflogger.NativeModulePerfLogger;
import com.facebook.soloader.SoLoader;
import javax.annotation.Nullable;
public class TurboModulePerfLogger {
@Nullable private static NativeModulePerfLogger sNativeModulePerfLogger = null;
static {
SoLoader.loadLibrary("turbomodulejsijni");
}
public static void moduleDataCreateStart(String moduleName, int id) {
if (sNativeModulePerfLogger != null) {
sNativeModulePerfLogger.moduleDataCreateStart(moduleName, id);
}
}
public static void moduleDataCreateEnd(String moduleName, int id) {
if (sNativeModulePerfLogger != null) {
sNativeModulePerfLogger.moduleDataCreateEnd(moduleName, id);
}
}
public static void moduleCreateStart(String moduleName, int id) {
if (sNativeModulePerfLogger != null) {
sNativeModulePerfLogger.moduleCreateStart(moduleName, id);
}
}
public static void moduleCreateCacheHit(String moduleName, int id) {
if (sNativeModulePerfLogger != null) {
sNativeModulePerfLogger.moduleCreateCacheHit(moduleName, id);
}
}
public static void moduleCreateConstructStart(String moduleName, int id) {
if (sNativeModulePerfLogger != null) {
sNativeModulePerfLogger.moduleCreateConstructStart(moduleName, id);
}
}
public static void moduleCreateConstructEnd(String moduleName, int id) {
if (sNativeModulePerfLogger != null) {
sNativeModulePerfLogger.moduleCreateConstructEnd(moduleName, id);
}
}
public static void moduleCreateSetUpStart(String moduleName, int id) {
if (sNativeModulePerfLogger != null) {
sNativeModulePerfLogger.moduleCreateSetUpStart(moduleName, id);
}
}
public static void moduleCreateSetUpEnd(String moduleName, int id) {
if (sNativeModulePerfLogger != null) {
sNativeModulePerfLogger.moduleCreateSetUpEnd(moduleName, id);
}
}
public static void moduleCreateEnd(String moduleName, int id) {
if (sNativeModulePerfLogger != null) {
sNativeModulePerfLogger.moduleCreateEnd(moduleName, id);
}
}
private static native void jniEnableCppLogging(NativeModulePerfLogger perfLogger);
public static void enableLogging(NativeModulePerfLogger perfLogger) {
if (perfLogger != null) {
sNativeModulePerfLogger = perfLogger;
jniEnableCppLogging(perfLogger);
}
}
}
@@ -15,7 +15,7 @@ LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall
LOCAL_STATIC_LIBRARIES = libcallinvoker
LOCAL_STATIC_LIBRARIES = libcallinvoker libreactperfloggerjni
LOCAL_SHARED_LIBRARIES = libfb libfbjni
@@ -35,6 +35,7 @@ rn_xplat_cxx_library(
":callinvokerholder",
"//xplat/jsi:jsi",
react_native_xplat_target("turbomodule/core:core"),
react_native_target("java/com/facebook/react/reactperflogger/jni:jni"),
],
)
@@ -5,15 +5,29 @@
* LICENSE file in the root directory of this source tree.
*/
#include <ReactCommon/TurboModulePerfLogger.h>
#include <fb/xplat_init.h>
#include <fbjni/fbjni.h>
#include <reactperflogger/JNativeModulePerfLogger.h>
#include "TurboModuleManager.h"
void jniEnableCppLogging(
jni::alias_ref<jclass> cls,
jni::alias_ref<facebook::react::JNativeModulePerfLogger::javaobject>
perfLogger) {
facebook::react::TurboModulePerfLogger::enableLogging(
perfLogger->cthis()->get());
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
return facebook::xplat::initialize(vm, [] {
// TODO: dvacca ramanpreet unify this with the way
// "ComponentDescriptorFactory" is defined in Fabric
facebook::react::TurboModuleManager::registerNatives();
facebook::jni::registerNatives(
"com/facebook/react/turbomodule/core/TurboModulePerfLogger",
{makeNativeMethod("jniEnableCppLogging", jniEnableCppLogging)});
});
}