Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/react-native/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ let reactFabric = RNTarget(
"components/virtualview",
"components/root/tests",
],
dependencies: [.reactNativeDependencies, .reactJsiExecutor, .rctTypesafety, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .reactRendererDebug, .reactGraphics, .yoga],
dependencies: [.reactNativeDependencies, .reactJsiExecutor, .rctTypesafety, .reactTurboModuleCore, .jsi, .logger, .reactDebug, .reactFeatureFlags, .reactUtils, .reactRuntimeScheduler, .reactCxxReact, .reactRendererDebug, .reactGraphics, .yoga, .reactJsInspectorTracing],
sources: ["animated", "animationbackend", "animations", "attributedstring", "core", "componentregistry", "componentregistry/native", "components/root", "components/view", "components/view/platform/cxx", "components/scrollview", "components/scrollview/platform/cxx", "components/scrollview/platform/ios", "components/legacyviewmanagerinterop", "components/legacyviewmanagerinterop/platform/ios", "dom", "scheduler", "mounting", "observers/events", "observers/intersection", "observers/mutation", "telemetry", "consistency", "leakchecker", "uimanager", "uimanager/consistency", "viewtransition"]
)

Expand Down
1 change: 1 addition & 0 deletions packages/react-native/ReactAndroid/api/ReactAndroid.api
Original file line number Diff line number Diff line change
Expand Up @@ -3114,6 +3114,7 @@ public final class com/facebook/react/soloader/OpenSourceMergedSoMapping : com/f
public final fun libreact_devsupportjni_so ()I
public final fun libreact_featureflagsjni_so ()I
public final fun libreact_newarchdefaults_so ()I
public final fun libreact_tracingjni_so ()I
public final fun libreactnative_so ()I
public final fun libreactnativeblob_so ()I
public final fun libreactnativejni_common_so ()I
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.facebook.react.fabric.FabricUIManager
import com.facebook.react.fabric.mounting.mountitems.DispatchCommandMountItem
import com.facebook.react.fabric.mounting.mountitems.MountItem
import com.facebook.react.internal.featureflags.ReactNativeFeatureFlags
import com.facebook.react.internal.tracing.PerformanceTracer
import com.facebook.systrace.Systrace
import java.util.Queue
import java.util.concurrent.ConcurrentLinkedQueue
Expand Down Expand Up @@ -201,9 +202,16 @@ internal class MountItemDispatcher(
"MountItemDispatcher::mountViews viewCommandMountItems",
)

for (command in commands) {
dispatchViewCommand(command)
}
PerformanceTracer.trace(
"view commands",
"Renderer",
"\u269b Native",
{ ->
for (command in commands) {
dispatchViewCommand(command)
}
},
)

Systrace.endSection(Systrace.TRACE_TAG_REACT)
}
Expand All @@ -215,12 +223,21 @@ internal class MountItemDispatcher(
Systrace.TRACE_TAG_REACT,
"MountItemDispatcher::mountViews preMountItems",
)
for (preMountItem in preMountItems) {
if (ReactNativeFeatureFlags.enableFabricLogs()) {
printMountItem(preMountItem, "dispatchMountItems: Executing preMountItem")
}
executeOrEnqueue(preMountItem)
}

PerformanceTracer.trace(
"premount",
"Renderer",
"\u269b Native",
{ ->
for (preMountItem in preMountItems) {
if (ReactNativeFeatureFlags.enableFabricLogs()) {
printMountItem(preMountItem, "dispatchMountItems: Executing preMountItem")
}
executeOrEnqueue(preMountItem)
}
},
)

Systrace.endSection(Systrace.TRACE_TAG_REACT)
}

Expand All @@ -229,46 +246,58 @@ internal class MountItemDispatcher(
Systrace.TRACE_TAG_REACT,
"MountItemDispatcher::mountViews mountItems to execute",
)
val batchedExecutionStartTime = SystemClock.uptimeMillis()

for (mountItem in items) {
if (ReactNativeFeatureFlags.enableFabricLogs()) {
printMountItem(mountItem, "dispatchMountItems: Executing mountItem")
}
PerformanceTracer.trace(
"mount",
"Renderer",
"\u269b Native",
{ ->
val batchedExecutionStartTime = SystemClock.uptimeMillis()

val command = mountItem as? DispatchCommandMountItem
if (command != null) {
dispatchViewCommand(command)
continue
}
for (mountItem in items) {
if (ReactNativeFeatureFlags.enableFabricLogs()) {
printMountItem(mountItem, "dispatchMountItems: Executing mountItem")
}

try {
executeOrEnqueue(mountItem)
} catch (e: Throwable) {
// If there's an exception, we want to log diagnostics in prod and rethrow.
FLog.e(TAG, "dispatchMountItems: caught exception, displaying mount state", e)
if (ReactNativeFeatureFlags.enableFabricLogs()) {
for (m in items) {
if (m === mountItem) {
// We want to mark the mount item that caused exception
FLog.e(TAG, "dispatchMountItems: mountItem: next mountItem triggered exception!")
val command = mountItem as? DispatchCommandMountItem
if (command != null) {
dispatchViewCommand(command)
continue
}
printMountItem(m, "dispatchMountItems: mountItem")
}
}

if (mountItem.getSurfaceId() != View.NO_ID) {
mountingManager.getSurfaceManager(mountItem.getSurfaceId())?.printSurfaceState()
}
try {
executeOrEnqueue(mountItem)
} catch (e: Throwable) {
// If there's an exception, we want to log diagnostics in prod and rethrow.
FLog.e(TAG, "dispatchMountItems: caught exception, displaying mount state", e)
if (ReactNativeFeatureFlags.enableFabricLogs()) {
for (m in items) {
if (m === mountItem) {
// We want to mark the mount item that caused exception
FLog.e(
TAG,
"dispatchMountItems: mountItem: next mountItem triggered exception!",
)
}
printMountItem(m, "dispatchMountItems: mountItem")
}
}

if (mountItem.getSurfaceId() != View.NO_ID) {
mountingManager.getSurfaceManager(mountItem.getSurfaceId())?.printSurfaceState()
}

if (ReactIgnorableMountingException.isIgnorable(e)) {
ReactSoftExceptionLogger.logSoftException(TAG, e)
} else {
throw e
}
}
}
batchedExecutionTime += SystemClock.uptimeMillis() - batchedExecutionStartTime
},
)

if (ReactIgnorableMountingException.isIgnorable(e)) {
ReactSoftExceptionLogger.logSoftException(TAG, e)
} else {
throw e
}
}
}
batchedExecutionTime += SystemClock.uptimeMillis() - batchedExecutionStartTime
Systrace.endSection(Systrace.TRACE_TAG_REACT)
}

Expand Down Expand Up @@ -299,26 +328,34 @@ internal class MountItemDispatcher(
private fun dispatchPreMountItemsImpl(deadline: Long) {
Systrace.beginSection(Systrace.TRACE_TAG_REACT, "MountItemDispatcher::premountViews")

// dispatchPreMountItems cannot be reentrant, but we want to prevent dispatchMountItems from
// reentering during dispatchPreMountItems
inDispatch = true

try {
while (true) {
if (System.nanoTime() > deadline) {
break
}
PerformanceTracer.trace(
"premount",
"Renderer",
"\u269b Native",
{ ->
// dispatchPreMountItems cannot be reentrant, but we want to prevent dispatchMountItems
// from
// reentering during dispatchPreMountItems
inDispatch = true

try {
while (true) {
if (System.nanoTime() > deadline) {
break
}

// If list is empty, `poll` will return null, or var will never be set
val preMountItemToDispatch = preMountItems.poll() ?: break
if (ReactNativeFeatureFlags.enableFabricLogs()) {
printMountItem(preMountItemToDispatch, "dispatchPreMountItems")
}
executeOrEnqueue(preMountItemToDispatch)
}
} finally {
inDispatch = false
}
// If list is empty, `poll` will return null, or var will never be set
val preMountItemToDispatch = preMountItems.poll() ?: break
if (ReactNativeFeatureFlags.enableFabricLogs()) {
printMountItem(preMountItemToDispatch, "dispatchPreMountItems")
}
executeOrEnqueue(preMountItemToDispatch)
}
} finally {
inDispatch = false
}
},
)

Systrace.endSection(Systrace.TRACE_TAG_REACT)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import com.facebook.soloader.SoLoader
@DoNotStrip
public object PerformanceTracer {
init {
SoLoader.loadLibrary("react_performancetracerjni")
SoLoader.loadLibrary("react_tracingjni")
}

public fun <T> trace(name: String, block: () -> T): T {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public object OpenSourceMergedSoMapping : ExternalSoMapping {
"react_devsupportjni",
"react_featureflagsjni",
"react_newarchdefaults",
"react_tracingjni",
"reactnativeblob",
"reactnativejni",
"reactnativejni_common",
Expand Down Expand Up @@ -57,6 +58,7 @@ public object OpenSourceMergedSoMapping : ExternalSoMapping {
"react_devsupportjni" -> libreact_devsupportjni_so()
"react_featureflagsjni" -> libreact_featureflagsjni_so()
"react_newarchdefaults" -> libreact_newarchdefaults_so()
"react_tracingjni" -> libreact_tracingjni_so()
"reactnative" -> libreactnative_so()
"reactnativeblob" -> libreactnativeblob_so()
"reactnativejni" -> libreactnativejni_so()
Expand Down Expand Up @@ -88,6 +90,8 @@ public object OpenSourceMergedSoMapping : ExternalSoMapping {

public external fun libreact_newarchdefaults_so(): Int

public external fun libreact_tracingjni_so(): Int

public external fun libreactnative_so(): Int

public external fun libreactnativeblob_so(): Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ add_react_android_subdir(src/main/jni/react/hermes/instrumentation/)
add_react_android_subdir(src/main/jni/react/runtime/cxxreactpackage)
add_react_android_subdir(src/main/jni/react/runtime/jni)
add_react_android_subdir(src/main/jni/react/runtime/hermes/jni)
add_react_android_subdir(src/main/jni/react/tracing)
add_react_android_subdir(src/main/jni/react/devsupport)

# SoMerging Utils
Expand Down Expand Up @@ -231,6 +232,7 @@ add_library(reactnative
$<TARGET_OBJECTS:react_renderer_uimanager>
$<TARGET_OBJECTS:react_renderer_uimanager_consistency>
$<TARGET_OBJECTS:react_renderer_viewtransition>
$<TARGET_OBJECTS:react_tracingjni>
$<TARGET_OBJECTS:react_utils>
$<TARGET_OBJECTS:reactnativeblob>
$<TARGET_OBJECTS:reactnativejni>
Expand Down Expand Up @@ -331,6 +333,7 @@ target_include_directories(reactnative
$<TARGET_PROPERTY:react_renderer_uimanager,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:react_renderer_uimanager_consistency,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:react_renderer_viewtransition,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:react_tracingjni,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:react_utils,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:reactnativeblob,INTERFACE_INCLUDE_DIRECTORIES>
$<TARGET_PROPERTY:reactnativejni,INTERFACE_INCLUDE_DIRECTORIES>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.

cmake_minimum_required(VERSION 3.13)
set(CMAKE_VERBOSE_MAKEFILE on)

include(${REACT_ANDROID_DIR}/src/main/jni/first-party/jni-lib-merge/SoMerging-utils.cmake)
include(${REACT_COMMON_DIR}/cmake-utils/react-native-flags.cmake)

file(GLOB react_tracingjni_SRC CONFIGURE_DEPENDS *.cpp)

add_library(react_tracingjni OBJECT ${react_tracingjni_SRC})

target_merge_so(react_tracingjni)

target_include_directories(react_tracingjni PUBLIC .)

target_link_libraries(react_tracingjni
fbjni
folly_runtime
jsinspector
jsinspector_tracing
react_timing
reactnativejni)

target_compile_reactnative_options(react_tracingjni PRIVATE)
1 change: 1 addition & 0 deletions packages/react-native/ReactCommon/React-Fabric.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ Pod::Spec.new do |s|
end

s.subspec "mounting" do |ss|
ss.dependency "React-jsinspectortracing"
ss.source_files = podspec_sources("react/renderer/mounting/**/*.{m,mm,cpp,h}", "react/renderer/mounting/**/*.h")
ss.exclude_files = "react/renderer/mounting/tests"
ss.header_dir = "react/renderer/mounting"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ target_link_libraries(react_renderer_mounting
glog
glog_init
jsi
jsinspector_tracing
react_debug
react_renderer_core
react_renderer_debug
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "ShadowTree.h"

#include <cxxreact/TraceSection.h>
#include <jsinspector-modern/tracing/PerformanceTracerSection.h>
#include <react/debug/react_native_assert.h>
#include <react/renderer/components/root/RootComponentDescriptor.h>
#include <react/renderer/components/view/ViewShadowNode.h>
Expand All @@ -24,6 +25,19 @@ namespace facebook::react {

namespace {
const int MAX_COMMIT_ATTEMPTS_BEFORE_LOCKING = 3;

std::string getShadowTreeCommitSourceName(ShadowTreeCommitSource source) {
switch (source) {
case ShadowTreeCommitSource::Unknown:
return "Unknown";
case ShadowTreeCommitSource::React:
return "React";
case ShadowTreeCommitSource::AnimationEndSync:
return "AnimationEndSync";
case ShadowTreeCommitSource::ReactRevisionMerge:
return "ReactRevisionMerge";
}
}
} // namespace

using CommitStatus = ShadowTree::CommitStatus;
Expand Down Expand Up @@ -316,6 +330,13 @@ CommitStatus ShadowTree::tryCommit(
const ShadowTreeCommitTransaction& transaction,
const CommitOptions& commitOptions) const {
TraceSection s("ShadowTree::commit");
jsinspector_modern::tracing::PerformanceTracerSection s1(
"commit",
"Renderer",
"\u269b Native",
nullptr,
"source",
getShadowTreeCommitSourceName(commitOptions.source));

auto isReactBranch = ReactNativeFeatureFlags::enableFabricCommitBranching() &&
commitOptions.source == CommitSource::React;
Expand Down Expand Up @@ -382,7 +403,11 @@ CommitStatus ShadowTree::tryCommit(

telemetry.willLayout();
telemetry.setAsThreadLocal();
newRootShadowNode->layoutIfNeeded(&affectedLayoutableNodes);
{
jsinspector_modern::tracing::PerformanceTracerSection s2(
"layout", "Renderer", "\u269b Native");
newRootShadowNode->layoutIfNeeded(&affectedLayoutableNodes);
}
telemetry.unsetAsThreadLocal();
telemetry.didLayout(static_cast<int>(affectedLayoutableNodes.size()));

Expand Down
Loading