mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
This patch moves the serialization of coverage profiles into C++. With this we no longer need to patch `process.reallyExit` and hook into the exit events, but instead hook into relevant places in C++ which are safe from user manipulation. This also makes the code easier to reuse for other types of profiles. PR-URL: https://github.com/nodejs/node/pull/26874 Reviewed-By: Ben Coe <bencoe@gmail.com>
167 lines
4.3 KiB
C++
167 lines
4.3 KiB
C++
#ifndef SRC_NODE_PERF_H_
|
|
#define SRC_NODE_PERF_H_
|
|
|
|
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
|
|
#include "node.h"
|
|
#include "node_perf_common.h"
|
|
#include "env.h"
|
|
#include "base_object-inl.h"
|
|
#include "histogram-inl.h"
|
|
|
|
#include "v8.h"
|
|
#include "uv.h"
|
|
|
|
#include <string>
|
|
|
|
namespace node {
|
|
namespace performance {
|
|
|
|
using v8::FunctionCallbackInfo;
|
|
using v8::GCType;
|
|
using v8::Local;
|
|
using v8::Object;
|
|
using v8::Value;
|
|
|
|
extern const uint64_t timeOrigin;
|
|
|
|
static inline const char* GetPerformanceMilestoneName(
|
|
enum PerformanceMilestone milestone) {
|
|
switch (milestone) {
|
|
#define V(name, label) case NODE_PERFORMANCE_MILESTONE_##name: return label;
|
|
NODE_PERFORMANCE_MILESTONES(V)
|
|
#undef V
|
|
default:
|
|
UNREACHABLE();
|
|
}
|
|
}
|
|
|
|
static inline PerformanceMilestone ToPerformanceMilestoneEnum(const char* str) {
|
|
#define V(name, label) \
|
|
if (strcmp(str, label) == 0) return NODE_PERFORMANCE_MILESTONE_##name;
|
|
NODE_PERFORMANCE_MILESTONES(V)
|
|
#undef V
|
|
return NODE_PERFORMANCE_MILESTONE_INVALID;
|
|
}
|
|
|
|
static inline PerformanceEntryType ToPerformanceEntryTypeEnum(
|
|
const char* type) {
|
|
#define V(name, label) \
|
|
if (strcmp(type, label) == 0) return NODE_PERFORMANCE_ENTRY_TYPE_##name;
|
|
NODE_PERFORMANCE_ENTRY_TYPES(V)
|
|
#undef V
|
|
return NODE_PERFORMANCE_ENTRY_TYPE_INVALID;
|
|
}
|
|
|
|
class PerformanceEntry {
|
|
public:
|
|
static void Notify(Environment* env,
|
|
PerformanceEntryType type,
|
|
Local<Value> object);
|
|
|
|
static void New(const FunctionCallbackInfo<Value>& args);
|
|
|
|
PerformanceEntry(Environment* env,
|
|
const char* name,
|
|
const char* type,
|
|
uint64_t startTime,
|
|
uint64_t endTime) : env_(env),
|
|
name_(name),
|
|
type_(type),
|
|
startTime_(startTime),
|
|
endTime_(endTime) { }
|
|
|
|
virtual ~PerformanceEntry() { }
|
|
|
|
virtual v8::MaybeLocal<Object> ToObject() const;
|
|
|
|
Environment* env() const { return env_; }
|
|
|
|
const std::string& name() const { return name_; }
|
|
|
|
const std::string& type() const { return type_; }
|
|
|
|
PerformanceEntryType kind() {
|
|
return ToPerformanceEntryTypeEnum(type().c_str());
|
|
}
|
|
|
|
double startTime() const { return startTimeNano() / 1e6; }
|
|
|
|
double duration() const { return durationNano() / 1e6; }
|
|
|
|
uint64_t startTimeNano() const { return startTime_ - timeOrigin; }
|
|
|
|
uint64_t durationNano() const { return endTime_ - startTime_; }
|
|
|
|
private:
|
|
Environment* env_;
|
|
const std::string name_;
|
|
const std::string type_;
|
|
const uint64_t startTime_;
|
|
const uint64_t endTime_;
|
|
};
|
|
|
|
enum PerformanceGCKind {
|
|
NODE_PERFORMANCE_GC_MAJOR = GCType::kGCTypeMarkSweepCompact,
|
|
NODE_PERFORMANCE_GC_MINOR = GCType::kGCTypeScavenge,
|
|
NODE_PERFORMANCE_GC_INCREMENTAL = GCType::kGCTypeIncrementalMarking,
|
|
NODE_PERFORMANCE_GC_WEAKCB = GCType::kGCTypeProcessWeakCallbacks
|
|
};
|
|
|
|
class GCPerformanceEntry : public PerformanceEntry {
|
|
public:
|
|
GCPerformanceEntry(Environment* env,
|
|
PerformanceGCKind gckind,
|
|
uint64_t startTime,
|
|
uint64_t endTime) :
|
|
PerformanceEntry(env, "gc", "gc", startTime, endTime),
|
|
gckind_(gckind) { }
|
|
|
|
PerformanceGCKind gckind() const { return gckind_; }
|
|
|
|
private:
|
|
PerformanceGCKind gckind_;
|
|
};
|
|
|
|
class ELDHistogram : public BaseObject, public Histogram {
|
|
public:
|
|
ELDHistogram(Environment* env,
|
|
Local<Object> wrap,
|
|
int32_t resolution);
|
|
|
|
~ELDHistogram() override;
|
|
|
|
bool RecordDelta();
|
|
bool Enable();
|
|
bool Disable();
|
|
void ResetState() {
|
|
Reset();
|
|
exceeds_ = 0;
|
|
prev_ = 0;
|
|
}
|
|
int64_t Exceeds() { return exceeds_; }
|
|
|
|
void MemoryInfo(MemoryTracker* tracker) const override {
|
|
tracker->TrackFieldWithSize("histogram", GetMemorySize());
|
|
}
|
|
|
|
SET_MEMORY_INFO_NAME(ELDHistogram)
|
|
SET_SELF_SIZE(ELDHistogram)
|
|
|
|
private:
|
|
void CloseTimer();
|
|
|
|
bool enabled_ = false;
|
|
int32_t resolution_ = 0;
|
|
int64_t exceeds_ = 0;
|
|
uint64_t prev_ = 0;
|
|
uv_timer_t* timer_;
|
|
};
|
|
|
|
} // namespace performance
|
|
} // namespace node
|
|
|
|
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
|
|
|
#endif // SRC_NODE_PERF_H_
|