GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: node_perf.h Lines: 21 30 70.0 %
Date: 2022-05-21 04:15:56 Branches: 12 31 38.7 %

Line Branch Exec Source
1
#ifndef SRC_NODE_PERF_H_
2
#define SRC_NODE_PERF_H_
3
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6
#include "base_object-inl.h"
7
#include "histogram.h"
8
#include "node.h"
9
#include "node_internals.h"
10
#include "node_perf_common.h"
11
12
#include "v8.h"
13
#include "uv.h"
14
15
#include <string>
16
17
namespace node {
18
19
class Environment;
20
class ExternalReferenceRegistry;
21
22
namespace performance {
23
24
extern const uint64_t timeOrigin;
25
26
46
inline const char* GetPerformanceMilestoneName(
27
    PerformanceMilestone milestone) {
28

46
  switch (milestone) {
29
#define V(name, label) case NODE_PERFORMANCE_MILESTONE_##name: return label;
30
46
  NODE_PERFORMANCE_MILESTONES(V)
31
#undef V
32
    default:
33
      UNREACHABLE();
34
  }
35
}
36
37
inline PerformanceMilestone ToPerformanceMilestoneEnum(const char* str) {
38
#define V(name, label)                                                        \
39
  if (strcmp(str, label) == 0) return NODE_PERFORMANCE_MILESTONE_##name;
40
  NODE_PERFORMANCE_MILESTONES(V)
41
#undef V
42
  return NODE_PERFORMANCE_MILESTONE_INVALID;
43
}
44
45
16
inline const char* GetPerformanceEntryTypeName(
46
    PerformanceEntryType type) {
47

16
  switch (type) {
48
#define V(name, label) case NODE_PERFORMANCE_ENTRY_TYPE_##name: return label;
49
16
  NODE_PERFORMANCE_ENTRY_TYPES(V)
50
#undef V
51
    default:
52
      UNREACHABLE();
53
  }
54
}
55
56
inline PerformanceEntryType ToPerformanceEntryTypeEnum(
57
    const char* type) {
58
#define V(name, label)                                                        \
59
  if (strcmp(type, label) == 0) return NODE_PERFORMANCE_ENTRY_TYPE_##name;
60
  NODE_PERFORMANCE_ENTRY_TYPES(V)
61
#undef V
62
  return NODE_PERFORMANCE_ENTRY_TYPE_INVALID;
63
}
64
65
enum PerformanceGCKind {
66
  NODE_PERFORMANCE_GC_MAJOR = v8::GCType::kGCTypeMarkSweepCompact,
67
  NODE_PERFORMANCE_GC_MINOR = v8::GCType::kGCTypeScavenge,
68
  NODE_PERFORMANCE_GC_INCREMENTAL = v8::GCType::kGCTypeIncrementalMarking,
69
  NODE_PERFORMANCE_GC_WEAKCB = v8::GCType::kGCTypeProcessWeakCallbacks
70
};
71
72
enum PerformanceGCFlags {
73
  NODE_PERFORMANCE_GC_FLAGS_NO =
74
    v8::GCCallbackFlags::kNoGCCallbackFlags,
75
  NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED =
76
    v8::GCCallbackFlags::kGCCallbackFlagConstructRetainedObjectInfos,
77
  NODE_PERFORMANCE_GC_FLAGS_FORCED =
78
    v8::GCCallbackFlags::kGCCallbackFlagForced,
79
  NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING =
80
    v8::GCCallbackFlags::kGCCallbackFlagSynchronousPhantomCallbackProcessing,
81
  NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE =
82
    v8::GCCallbackFlags::kGCCallbackFlagCollectAllAvailableGarbage,
83
  NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY =
84
    v8::GCCallbackFlags::kGCCallbackFlagCollectAllExternalMemory,
85
  NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE =
86
    v8::GCCallbackFlags::kGCCallbackScheduleIdleGarbageCollection
87
};
88
89
template <typename Traits>
90
struct PerformanceEntry {
91
  using Details = typename Traits::Details;
92
  std::string name;
93
  double start_time;
94
  double duration;
95
  Details details;
96
97
31
  PerformanceEntry(
98
    const std::string& name_,
99
    double start_time_,
100
    double duration_,
101
    const Details& details_)
102
    : name(name_),
103
      start_time(start_time_),
104
      duration(duration_),
105
31
      details(details_) {}
106
107
  static v8::MaybeLocal<v8::Object> GetDetails(
108
      Environment* env,
109
      const PerformanceEntry<Traits>& entry) {
110
    return Traits::GetDetails(env, entry);
111
  }
112
113
16
  void Notify(Environment* env) {
114
16
    v8::HandleScope handle_scope(env->isolate());
115
16
    v8::Context::Scope scope(env->context());
116
16
    AliasedUint32Array& observers = env->performance_state()->observers;
117

48
    if (env->performance_entry_callback().IsEmpty() ||
118
32
        !observers[Traits::kType]) {
119
      return;
120
    }
121
122
    v8::Local<v8::Object> detail;
123
32
    if (!Traits::GetDetails(env, *this).ToLocal(&detail)) {
124
      // TODO(@jasnell): Handle the error here
125
      return;
126
    }
127
128
80
    v8::Local<v8::Value> argv[] = {
129
      OneByteString(env->isolate(), name.c_str()),
130
      OneByteString(env->isolate(), GetPerformanceEntryTypeName(Traits::kType)),
131
      v8::Number::New(env->isolate(), start_time),
132
      v8::Number::New(env->isolate(), duration),
133
      detail
134
    };
135
136
32
    node::MakeSyncCallback(
137
        env->isolate(),
138
32
        env->context()->Global(),
139
        env->performance_entry_callback(),
140
16
        arraysize(argv),
141
        argv);
142
  }
143
};
144
145
struct GCPerformanceEntryTraits {
146
  static constexpr PerformanceEntryType kType =
147
      NODE_PERFORMANCE_ENTRY_TYPE_GC;
148
  struct Details {
149
    PerformanceGCKind kind;
150
    PerformanceGCFlags flags;
151
152
1
    Details(PerformanceGCKind kind_, PerformanceGCFlags flags_)
153
1
        : kind(kind_), flags(flags_) {}
154
  };
155
156
  static v8::MaybeLocal<v8::Object> GetDetails(
157
      Environment* env,
158
      const PerformanceEntry<GCPerformanceEntryTraits>& entry);
159
};
160
161
using GCPerformanceEntry = PerformanceEntry<GCPerformanceEntryTraits>;
162
163
}  // namespace performance
164
}  // namespace node
165
166
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
167
168
#endif  // SRC_NODE_PERF_H_