PHP WebShell
Текущая директория: /usr/lib/node_modules/bitgo/node_modules/react-native/ReactCommon/hermes/inspector-modern/chrome
Просмотр файла: HermesRuntimeSamplingProfileSerializer.cpp
/*
* 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.
*/
#include <variant>
#include "HermesRuntimeSamplingProfileSerializer.h"
namespace facebook::react::jsinspector_modern::tracing {
namespace {
namespace fhsp = facebook::hermes::sampling_profiler;
/// Fallback script ID for call frames, when Hermes didn't provide one or when
/// this frame is part of the VM, like native functions, used for parity with
/// Chromium + V8.
constexpr uint32_t FALLBACK_SCRIPT_ID = 0;
/// Garbage collector frame name, used for parity with Chromium + V8.
constexpr std::string_view GARBAGE_COLLECTOR_FRAME_NAME = "(garbage collector)";
/// Filters out Hermes Suspend frames related to Debugger.
/// Even though Debugger domain is expected to be disabled, Hermes might run
/// Debugger loop while recording sampling profile. We only allow GC frames.
inline bool shouldIgnoreHermesFrame(
const fhsp::ProfileSampleCallStackSuspendFrame& suspendFrame) {
return suspendFrame.getSuspendFrameKind() !=
fhsp::ProfileSampleCallStackSuspendFrame::SuspendFrameKind::GC;
}
RuntimeSamplingProfile::SampleCallStackFrame convertNativeHermesFrame(
const fhsp::ProfileSampleCallStackNativeFunctionFrame& frame) {
return RuntimeSamplingProfile::SampleCallStackFrame{
RuntimeSamplingProfile::SampleCallStackFrame::Kind::NativeFunction,
FALLBACK_SCRIPT_ID, // JavaScript Runtime defines the implementation
// for native function, no script ID to reference.
frame.getFunctionName(),
};
}
RuntimeSamplingProfile::SampleCallStackFrame convertHostFunctionHermesFrame(
const fhsp::ProfileSampleCallStackHostFunctionFrame& frame) {
return RuntimeSamplingProfile::SampleCallStackFrame{
RuntimeSamplingProfile::SampleCallStackFrame::Kind::HostFunction,
FALLBACK_SCRIPT_ID, // JavaScript Runtime defines the implementation
// for host function, no script ID to reference.
frame.getFunctionName(),
};
}
RuntimeSamplingProfile::SampleCallStackFrame convertSuspendHermesFrame(
const fhsp::ProfileSampleCallStackSuspendFrame& frame) {
if (frame.getSuspendFrameKind() ==
fhsp::ProfileSampleCallStackSuspendFrame::SuspendFrameKind::GC) {
return RuntimeSamplingProfile::SampleCallStackFrame{
RuntimeSamplingProfile::SampleCallStackFrame::Kind::GarbageCollector,
FALLBACK_SCRIPT_ID, // GC frames are part of the VM, no script ID to
// reference.
GARBAGE_COLLECTOR_FRAME_NAME,
};
}
// We should have filtered out Debugger Suspend frames before in
// shouldFilterOutHermesFrame().
throw std::logic_error{"Unexpected Suspend frame found in Hermes call stack"};
}
RuntimeSamplingProfile::SampleCallStackFrame convertJSFunctionHermesFrame(
const fhsp::ProfileSampleCallStackJSFunctionFrame& frame) {
return RuntimeSamplingProfile::SampleCallStackFrame{
RuntimeSamplingProfile::SampleCallStackFrame::Kind::JSFunction,
frame.getScriptId(),
frame.getFunctionName(),
frame.hasScriptUrl()
? std::optional<std::string_view>{frame.getScriptUrl()}
: std::nullopt,
frame.hasFunctionLineNumber()
? std::optional<uint32_t>{frame.getFunctionLineNumber() - 1}
// Hermes VM keeps line numbers as 1-based. Convert
// to 0-based.
: std::nullopt,
frame.hasFunctionColumnNumber()
? std::optional<uint32_t>{frame.getFunctionColumnNumber() - 1}
// Hermes VM keeps column numbers as 1-based. Convert to
// 0-based.
: std::nullopt,
};
}
RuntimeSamplingProfile::Sample convertHermesSampleToTracingSample(
const fhsp::ProfileSample& hermesSample) {
uint64_t reconciledTimestamp = hermesSample.getTimestamp();
const auto callStackRange = hermesSample.getCallStackFramesRange();
std::vector<RuntimeSamplingProfile::SampleCallStackFrame>
reconciledSampleCallStack;
reconciledSampleCallStack.reserve(hermesSample.getCallStackFramesCount());
for (const auto& hermesFrame : callStackRange) {
if (std::holds_alternative<fhsp::ProfileSampleCallStackSuspendFrame>(
hermesFrame)) {
const auto& suspendFrame =
std::get<fhsp::ProfileSampleCallStackSuspendFrame>(hermesFrame);
if (shouldIgnoreHermesFrame(suspendFrame)) {
continue;
}
reconciledSampleCallStack.emplace_back(
convertSuspendHermesFrame(suspendFrame));
} else if (std::holds_alternative<
fhsp::ProfileSampleCallStackNativeFunctionFrame>(
hermesFrame)) {
const auto& nativeFunctionFrame =
std::get<fhsp::ProfileSampleCallStackNativeFunctionFrame>(
hermesFrame);
reconciledSampleCallStack.emplace_back(
convertNativeHermesFrame(nativeFunctionFrame));
} else if (std::holds_alternative<
fhsp::ProfileSampleCallStackHostFunctionFrame>(
hermesFrame)) {
const auto& hostFunctionFrame =
std::get<fhsp::ProfileSampleCallStackHostFunctionFrame>(hermesFrame);
reconciledSampleCallStack.emplace_back(
convertHostFunctionHermesFrame(hostFunctionFrame));
} else if (std::holds_alternative<
fhsp::ProfileSampleCallStackJSFunctionFrame>(hermesFrame)) {
const auto& jsFunctionFrame =
std::get<fhsp::ProfileSampleCallStackJSFunctionFrame>(hermesFrame);
reconciledSampleCallStack.emplace_back(
convertJSFunctionHermesFrame(jsFunctionFrame));
} else {
throw std::logic_error{"Unknown Hermes stack frame kind"};
}
}
return RuntimeSamplingProfile::Sample{
reconciledTimestamp,
hermesSample.getThreadId(),
std::move(reconciledSampleCallStack)};
}
} // namespace
/* static */ RuntimeSamplingProfile
HermesRuntimeSamplingProfileSerializer::serializeToTracingSamplingProfile(
hermes::sampling_profiler::Profile hermesProfile) {
const auto samplesRange = hermesProfile.getSamplesRange();
std::vector<RuntimeSamplingProfile::Sample> reconciledSamples;
reconciledSamples.reserve(hermesProfile.getSamplesCount());
for (const auto& hermesSample : samplesRange) {
RuntimeSamplingProfile::Sample reconciledSample =
convertHermesSampleToTracingSample(hermesSample);
reconciledSamples.push_back(std::move(reconciledSample));
}
return RuntimeSamplingProfile{
"Hermes",
std::move(reconciledSamples),
std::make_unique<RawHermesRuntimeProfile>(std::move(hermesProfile))};
}
} // namespace facebook::react::jsinspector_modern::tracing
Выполнить команду
Для локальной разработки. Не используйте в интернете!