/* * 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. */ #pragma once #include "TraceEvent.h" #include #include #include #include #include namespace facebook::react::jsinspector_modern::tracing { /// Opaque class to represent the original runtime profile returned by the /// Runtime. RuntimeSamplingProfile class is designed to be agnostic to the /// Runtime where sampling occurred. class RawRuntimeProfile { public: virtual ~RawRuntimeProfile() = default; }; /// Contains relevant information about the sampled runtime from start to /// finish. struct RuntimeSamplingProfile { public: /// Represents a single frame inside the captured sample stack. struct SampleCallStackFrame { public: /// Represents type of frame inside of recorded call stack. enum class Kind { JSFunction, /// JavaScript function frame. NativeFunction, /// Native built-in functions, like arrayPrototypeMap. HostFunction, /// Native functions, defined by Host, a.k.a. Host /// functions. GarbageCollector, /// Garbage collection frame. }; inline bool operator==(const SampleCallStackFrame &rhs) const noexcept = default; /// type of the call stack frame Kind kind; /// id of the corresponding script in the VM. uint32_t scriptId; /// name of the function that represents call frame. /// Storing a std::string_view should be considered safe here, beacause /// the lifetime of the string contents are guaranteed as long as the raw // Sampling Profiler object from Hermes is allocated. std::string_view functionName; /// source url of the corresponding script in the VM. /// Storing a std::string_view should be considered safe here, beacause /// the lifetime of the string contents are guaranteed as long as the raw // Sampling Profiler object from Hermes is allocated. std::optional scriptURL = std::nullopt; /// 0-based line number of the corresponding call frame. std::optional lineNumber = std::nullopt; /// 0-based column number of the corresponding call frame. std::optional columnNumber = std::nullopt; }; /// A pair of a timestamp and a snapshot of the call stack at this point in /// time. struct Sample { public: Sample(uint64_t timestamp, ThreadId threadId, std::vector callStack) : timestamp(timestamp), threadId(threadId), callStack(std::move(callStack)) { } // Movable. Sample &operator=(Sample &&) = default; Sample(Sample &&) = default; // Not copyable. Sample(const Sample &) = delete; Sample &operator=(const Sample &) = delete; ~Sample() = default; /// When the call stack snapshot was taken (μs). uint64_t timestamp; /// Thread id where sample was recorded. ThreadId threadId; /// Snapshot of the call stack. The first element of the vector is /// the lowest frame in the stack. std::vector callStack; }; RuntimeSamplingProfile( std::string runtimeName, ProcessId processId, std::vector samples, std::unique_ptr rawRuntimeProfile) : runtimeName(std::move(runtimeName)), processId(processId), samples(std::move(samples)), rawRuntimeProfile(std::move(rawRuntimeProfile)) { } // Movable. RuntimeSamplingProfile &operator=(RuntimeSamplingProfile &&) = default; RuntimeSamplingProfile(RuntimeSamplingProfile &&) = default; // Not copyable. RuntimeSamplingProfile(const RuntimeSamplingProfile &) = delete; RuntimeSamplingProfile &operator=(const RuntimeSamplingProfile &) = delete; ~RuntimeSamplingProfile() = default; /// Name of the runtime, where sampling occurred: Hermes, V8, etc. std::string runtimeName; /// The ID of the OS-level process where the sampling occurred. ProcessId processId; /// List of recorded samples, should be chronologically sorted. std::vector samples; /// A unique pointer to the original raw runtime profile, collected from the /// runtime in RuntimeTargetDelegate. Keeping a pointer to the original /// profile allows it to remain alive as long as RuntimeSamplingProfile is /// alive, since it may be using the same std::string_view. std::unique_ptr rawRuntimeProfile; }; } // namespace facebook::react::jsinspector_modern::tracing