mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
b903ed7940
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/52827 Changelog: [internal] This adds **support for creating Hermes/JS sampling profiler traces in Fantom**, which is especially useful when running benchmarks. Usage: ``` FANTOM_PROFILE_JS=1 yarn fantom Animated-benchmark ``` Output: {F1980642216} After this, the trace is fully symbolicated. Can be opened directly in Google Chrome: {F1980642229} Or in the built-in viewer in VSCode: {F1980642242} {F1980642240} {F1980642241} When collapsing frames in the Flame Chart viewer in VSCode, we can quickly identify opportunities for optimizations. This also supports multi-config environments. In that case, trace file names are created using a short representation of the configuration. User guide for benchmarks in Fantom, including how to use this, will be done in a future diff. NOTE: This still doesn't work in OSS because we don't support optimized mode there. In dev mode, there's a segmentation fault coming from this line: `hermesRuntime->sampledTraceToStreamInDevToolsFormat(fileStream)` Reviewed By: sammy-SC Differential Revision: D78905646 fbshipit-source-id: 382ddd5034db601309bd118cedde2fe0d57fde98
165 lines
4.2 KiB
JavaScript
165 lines
4.2 KiB
JavaScript
/**
|
|
* 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.
|
|
*
|
|
* @flow strict-local
|
|
* @format
|
|
*/
|
|
|
|
import type {FeatureFlagValue} from '../../../packages/react-native/scripts/featureflags/types';
|
|
import type {FantomTestConfig} from '../runner/getFantomTestConfigs';
|
|
import type {HermesVariant} from '../runner/utils';
|
|
import type {PartialFantomTestConfig} from './getFantomTestConfigs';
|
|
|
|
import {FantomTestConfigHermesVariant} from '../runner/getFantomTestConfigs';
|
|
import {getOverrides} from './getFantomTestConfigs';
|
|
|
|
function formatModes(overrides: PartialFantomTestConfig) {
|
|
const parts = [];
|
|
|
|
if (
|
|
overrides.isNativeOptimized === false &&
|
|
overrides.isJsOptimized === false &&
|
|
overrides.isJsBytecode === false
|
|
) {
|
|
return ['mode 🐛'];
|
|
} else if (
|
|
overrides.isNativeOptimized === true &&
|
|
overrides.isJsOptimized === true &&
|
|
overrides.isJsBytecode === true
|
|
) {
|
|
return ['mode 🚀'];
|
|
}
|
|
|
|
if (overrides.isNativeOptimized != null) {
|
|
parts.push(overrides.isNativeOptimized ? 'native 🚀' : 'native 🐛');
|
|
}
|
|
|
|
if (overrides.isJsOptimized != null) {
|
|
parts.push(overrides.isJsOptimized ? 'js 🚀' : 'js 🐛');
|
|
}
|
|
|
|
if (overrides.isJsBytecode != null && overrides.isJsBytecode) {
|
|
parts.push('bytecode');
|
|
}
|
|
|
|
return parts;
|
|
}
|
|
|
|
function formatModesShort(overrides: PartialFantomTestConfig) {
|
|
const parts = [];
|
|
|
|
if (
|
|
overrides.isNativeOptimized === false &&
|
|
overrides.isJsOptimized === false &&
|
|
overrides.isJsBytecode === false
|
|
) {
|
|
return ['dev'];
|
|
} else if (
|
|
overrides.isNativeOptimized === true &&
|
|
overrides.isJsOptimized === true &&
|
|
overrides.isJsBytecode === true
|
|
) {
|
|
return ['opt'];
|
|
}
|
|
|
|
if (overrides.isNativeOptimized != null) {
|
|
parts.push(overrides.isNativeOptimized ? 'native-opt' : 'native-dev');
|
|
}
|
|
|
|
if (overrides.isJsOptimized != null) {
|
|
parts.push(overrides.isJsOptimized ? 'js-opt' : 'js-dev');
|
|
}
|
|
|
|
if (overrides.isJsBytecode != null && overrides.isJsBytecode) {
|
|
parts.push('bytecode');
|
|
}
|
|
|
|
return parts;
|
|
}
|
|
|
|
function formatFantomHermesVariant(hermesVariant: HermesVariant): string {
|
|
switch (hermesVariant) {
|
|
case FantomTestConfigHermesVariant.Hermes:
|
|
return 'hermes';
|
|
case FantomTestConfigHermesVariant.StaticHermesStable:
|
|
return 'shermes 🆕';
|
|
case FantomTestConfigHermesVariant.StaticHermesExperimental:
|
|
return 'shermes 🧪';
|
|
}
|
|
}
|
|
|
|
function formatFantomFeatureFlag(
|
|
flagName: string,
|
|
flagValue: FeatureFlagValue,
|
|
): string {
|
|
if (typeof flagValue === 'boolean') {
|
|
return `${flagName} ${flagValue ? '✅' : '🛑'}`;
|
|
}
|
|
|
|
return `🔐 ${flagName} = ${flagValue}`;
|
|
}
|
|
|
|
function formatFantomConfigPretty(config: PartialFantomTestConfig): string {
|
|
const parts = [];
|
|
|
|
parts.push(...formatModes(config));
|
|
|
|
if (config.hermesVariant) {
|
|
parts.push(formatFantomHermesVariant(config.hermesVariant));
|
|
}
|
|
|
|
if (config.flags) {
|
|
for (const flagType of ['common', 'jsOnly', 'reactInternal'] as const) {
|
|
if (config.flags[flagType]) {
|
|
for (const [flagName, flagValue] of Object.entries(
|
|
config.flags[flagType],
|
|
)) {
|
|
parts.push(formatFantomFeatureFlag(flagName, flagValue));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return parts.join(', ');
|
|
}
|
|
|
|
function formatFantomConfigShort(config: PartialFantomTestConfig): string {
|
|
const parts = [];
|
|
|
|
parts.push(...formatModesShort(config));
|
|
|
|
if (config.hermesVariant) {
|
|
parts.push((config.hermesVariant as string).toLocaleLowerCase());
|
|
}
|
|
|
|
if (config.flags) {
|
|
for (const flagType of ['common', 'jsOnly', 'reactInternal'] as const) {
|
|
if (config.flags[flagType]) {
|
|
for (const [flagName, flagValue] of Object.entries(
|
|
config.flags[flagType],
|
|
)) {
|
|
parts.push(`${flagName}[${String(flagValue)}]`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return parts.join('-');
|
|
}
|
|
|
|
export default function formatFantomConfig(
|
|
config: FantomTestConfig,
|
|
options?: ?{style?: 'pretty' | 'short'},
|
|
): string {
|
|
const overrides = getOverrides(config);
|
|
|
|
if (options?.style === 'short') {
|
|
return formatFantomConfigShort(overrides);
|
|
}
|
|
|
|
return formatFantomConfigPretty(overrides);
|
|
}
|