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
7 changes: 7 additions & 0 deletions private/react-native-fantom/runner/EnvironmentOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const VALID_ENVIRONMENT_VARIABLES = [
'FANTOM_PRINT_OUTPUT',
'FANTOM_DEBUG_JS',
'FANTOM_PROFILE_JS',
'FANTOM_PROFILE_CPP',
'FANTOM_ENABLE_JS_MEMORY_INSTRUMENTATION',
];

Expand Down Expand Up @@ -69,6 +70,12 @@ export const debugJS: boolean = Boolean(process.env.FANTOM_DEBUG_JS);

export const profileJS: boolean = Boolean(process.env.FANTOM_PROFILE_JS);

/**
* Enables C++ sampling profiler using Linux perf.
* Saves perf.data files to .out/cpp-traces/ for analysis.
*/
export const profileCpp: boolean = Boolean(process.env.FANTOM_PROFILE_CPP);

/**
* Enables address sanitizer (ASAN) build mode for the C++ side.
*/
Expand Down
51 changes: 48 additions & 3 deletions private/react-native-fantom/runner/executables/tester.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

import type {AsyncCommandResult, HermesVariant} from '../utils';

import {debugCpp, isCI} from '../EnvironmentOptions';
import {NATIVE_BUILD_OUTPUT_PATH} from '../paths';
import {debugCpp, isCI, profileCpp} from '../EnvironmentOptions';
import {CPP_TRACES_OUTPUT_PATH, NATIVE_BUILD_OUTPUT_PATH} from '../paths';
import {
getBuckModesForPlatform,
getBuckOptionsForHermes,
Expand Down Expand Up @@ -84,6 +84,10 @@ export function run(
throw new Error('Cannot run Fantom with C++ debugging on CI');
}

if (isCI && profileCpp) {
throw new Error('Cannot run Fantom with C++ profiling on CI');
}

if (!isCI && !debugCpp) {
build(options);
}
Expand All @@ -104,5 +108,46 @@ export function run(
);
}

return runCommand(getFantomTesterPath(options), args);
const testerPath = getFantomTesterPath(options);

if (profileCpp) {
// Ensure output directory exists
if (!fs.existsSync(CPP_TRACES_OUTPUT_PATH)) {
fs.mkdirSync(CPP_TRACES_OUTPUT_PATH, {recursive: true});
}

// Generate unique output path for perf data
const perfOutputPath = path.join(
CPP_TRACES_OUTPUT_PATH,
`perf-${Date.now()}.data`,
);

// Wrap command with perf record
// -g: enable call-graph (stack traces)
// -F 997: sample at 997 Hz (prime number to avoid aliasing)
// --call-graph dwarf: use DWARF for accurate stack traces
const result = runCommand('perf', [
'record',
'-g',
'-F',
'997',
'--call-graph',
'dwarf',
'-o',
perfOutputPath,
'--',
testerPath,
...args,
]);

// Log the output path after the command starts
console.log(
`\n🔥 C++ sampling profiler recording to: ${perfOutputPath}\n` +
` View with: perf report -i ${perfOutputPath}\n`,
);

return result;
}

return runCommand(testerPath, args);
}
4 changes: 4 additions & 0 deletions private/react-native-fantom/runner/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export const JS_TRACES_OUTPUT_PATH: string = path.join(
OUTPUT_PATH,
'js-traces',
);
export const CPP_TRACES_OUTPUT_PATH: string = path.join(
OUTPUT_PATH,
'cpp-traces',
);
export const JS_HEAP_SNAPSHOTS_OUTPUT_PATH: string = path.join(
OUTPUT_PATH,
'js-heap-snapshots',
Expand Down
Loading