@@ -72,6 +72,27 @@ class SignalMutex {
72
72
inline ~SignalMutex () { store (false ); }
73
73
};
74
74
75
+ // This class is used to update the context count metric when it goes out of
76
+ // scope.
77
+ class ContextCountMetricUpdater {
78
+ uint32_t * fields_;
79
+ std::unordered_set<PersistentContextPtr*>& liveContextPtrs_;
80
+
81
+ public:
82
+ inline ContextCountMetricUpdater (
83
+ uint32_t * fields,
84
+ std::unordered_set<PersistentContextPtr*>& liveContextPtrs)
85
+ : fields_(fields), liveContextPtrs_(liveContextPtrs) {}
86
+
87
+ inline ~ContextCountMetricUpdater () {
88
+ std::atomic_store_explicit (
89
+ reinterpret_cast <std::atomic<uint32_t >*>(
90
+ &fields_[WallProfiler::Fields::kCPEDContextCount ]),
91
+ liveContextPtrs_.size (),
92
+ std::memory_order_relaxed);
93
+ }
94
+ };
95
+
75
96
void SetContextPtr (ContextPtr& contextPtr,
76
97
Isolate* isolate,
77
98
Local<Value> value) {
@@ -673,6 +694,7 @@ void WallProfiler::Dispose(Isolate* isolate, bool removeFromMap) {
673
694
node::RemoveEnvironmentCleanupHook (
674
695
isolate, &WallProfiler::CleanupHook, isolate);
675
696
697
+ ContextCountMetricUpdater updater (fields_, liveContextPtrs_);
676
698
for (auto ptr : liveContextPtrs_) {
677
699
ptr->UnregisterFromGC ();
678
700
delete ptr;
@@ -853,6 +875,7 @@ v8::ProfilerId WallProfiler::StartInternal() {
853
875
if (withContexts_ || workaroundV8Bug_) {
854
876
SignalHandler::IncreaseUseCount ();
855
877
fields_[kSampleCount ] = 0 ;
878
+ fields_[kCPEDContextCount ] = 0 ;
856
879
}
857
880
858
881
if (collectCpuTime_) {
@@ -1072,6 +1095,11 @@ NAN_MODULE_INIT(WallProfiler::Init) {
1072
1095
Nan::New<Integer>(kSampleCount ),
1073
1096
ReadOnlyDontDelete)
1074
1097
.FromJust ();
1098
+ Nan::DefineOwnProperty (constants,
1099
+ Nan::New (" kCPEDContextCount" ).ToLocalChecked (),
1100
+ Nan::New<Integer>(kCPEDContextCount ),
1101
+ ReadOnlyDontDelete)
1102
+ .FromJust ();
1075
1103
Nan::DefineOwnProperty (target,
1076
1104
Nan::New (" constants" ).ToLocalChecked (),
1077
1105
constants,
@@ -1116,6 +1144,8 @@ void WallProfiler::SetContext(Isolate* isolate, Local<Value> value) {
1116
1144
return ;
1117
1145
}
1118
1146
1147
+ ContextCountMetricUpdater updater (fields_, liveContextPtrs_);
1148
+
1119
1149
// Clean up dead context pointers
1120
1150
for (auto ptr : deadContextPtrs_) {
1121
1151
liveContextPtrs_.erase (ptr);
@@ -1140,6 +1170,12 @@ void WallProfiler::SetContext(Isolate* isolate, Local<Value> value) {
1140
1170
auto profData = maybeProfData.ToLocalChecked ();
1141
1171
SignalMutex m (setInProgress_);
1142
1172
if (profData->IsUndefined ()) {
1173
+ if (value->IsNullOrUndefined ()) {
1174
+ // Don't go to the trouble of mutating the CPED for null or undefined as
1175
+ // the absence of a sample context will be interpreted as undefined in
1176
+ // GetContextPtr anyway.
1177
+ return ;
1178
+ }
1143
1179
contextPtr = new PersistentContextPtr (&deadContextPtrs_);
1144
1180
1145
1181
auto external = External::New (isolate, contextPtr);
0 commit comments