diff --git a/src/env-inl.h b/src/env-inl.h index b61634774a64ad..956153bb965f44 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -348,7 +348,7 @@ inline Environment::Environment(IsolateData* isolate_data, AssignToContext(context); destroy_async_id_list_.reserve(512); - performance_state_ = Calloc(1); + performance_state_.reset(new performance::performance_state(isolate())); performance_state_->milestones[ performance::NODE_PERFORMANCE_MILESTONE_ENVIRONMENT] = PERFORMANCE_NOW(); @@ -378,7 +378,6 @@ inline Environment::~Environment() { delete[] heap_statistics_buffer_; delete[] heap_space_statistics_buffer_; delete[] http_parser_buffer_; - free(performance_state_); } inline v8::Isolate* Environment::isolate() const { @@ -550,7 +549,7 @@ void Environment::SetImmediate(native_immediate_callback cb, void* data) { } inline performance::performance_state* Environment::performance_state() { - return performance_state_; + return performance_state_.get(); } inline std::map* Environment::performance_marks() { diff --git a/src/env.h b/src/env.h index 40b8c666b7bdf4..6113e6d2de26ea 100644 --- a/src/env.h +++ b/src/env.h @@ -48,7 +48,7 @@ struct nghttp2_rcbuf; namespace node { namespace performance { -struct performance_state; +class performance_state; } namespace loader { @@ -717,7 +717,7 @@ class Environment { AliasedBuffer scheduled_immediate_count_; - performance::performance_state* performance_state_ = nullptr; + std::unique_ptr performance_state_; std::map performance_marks_; #if HAVE_INSPECTOR diff --git a/src/node_perf.cc b/src/node_perf.cc index 94c3a0f8e0c047..02145eeffdba12 100644 --- a/src/node_perf.cc +++ b/src/node_perf.cc @@ -41,10 +41,10 @@ void PerformanceEntry::New(const FunctionCallbackInfo& args) { void PerformanceEntry::NotifyObservers(Environment* env, PerformanceEntry* entry) { - uint32_t* observers = env->performance_state()->observers; + AliasedBuffer& observers = + env->performance_state()->observers; PerformanceEntryType type = ToPerformanceEntryTypeEnum(entry->type().c_str()); - if (observers == nullptr || - type == NODE_PERFORMANCE_ENTRY_TYPE_INVALID || + if (type == NODE_PERFORMANCE_ENTRY_TYPE_INVALID || !observers[type]) { return; } @@ -88,7 +88,8 @@ void Measure(const FunctionCallbackInfo& args) { Utf8Value startMark(isolate, args[1]); Utf8Value endMark(isolate, args[2]); - double* milestones = env->performance_state()->milestones; + AliasedBuffer& milestones = + env->performance_state()->milestones; uint64_t startTimestamp = timeOrigin; uint64_t start = GetPerformanceMark(env, *startMark); @@ -155,7 +156,8 @@ void GetPerformanceEntryDuration(const Local prop, void MarkMilestone(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); Local context = env->context(); - double* milestones = env->performance_state()->milestones; + AliasedBuffer& milestones = + env->performance_state()->milestones; PerformanceMilestone milestone = static_cast( args[0]->Int32Value(context).ToChecked()); @@ -182,7 +184,8 @@ void PerformanceGCCallback(uv_async_t* handle) { Local obj; PerformanceGCKind kind = static_cast(data->data()); - uint32_t* observers = env->performance_state()->observers; + AliasedBuffer& observers = + env->performance_state()->observers; if (!observers[NODE_PERFORMANCE_ENTRY_TYPE_GC]) { goto cleanup; } @@ -285,8 +288,8 @@ void TimerFunctionCall(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(ret.ToLocalChecked()); } - - uint32_t* observers = env->performance_state()->observers; + AliasedBuffer& observers = + env->performance_state()->observers; if (!observers[NODE_PERFORMANCE_ENTRY_TYPE_FUNCTION]) return; @@ -319,16 +322,12 @@ void Init(Local target, performance_state* state = env->performance_state(); auto state_ab = ArrayBuffer::New(isolate, state, sizeof(*state)); - #define SET_STATE_TYPEDARRAY(name, type, field) \ - target->Set(context, \ - FIXED_ONE_BYTE_STRING(isolate, (name)), \ - type::New(state_ab, \ - offsetof(performance_state, field), \ - arraysize(state->field))) \ - .FromJust() - SET_STATE_TYPEDARRAY("observerCounts", v8::Uint32Array, observers); - SET_STATE_TYPEDARRAY("milestones", v8::Float64Array, milestones); - #undef SET_STATE_TYPEDARRAY + target->Set(context, + FIXED_ONE_BYTE_STRING(isolate, "observerCounts"), + state->observers.GetJSArray()).FromJust(); + target->Set(context, + FIXED_ONE_BYTE_STRING(isolate, "milestones"), + state->milestones.GetJSArray()).FromJust(); Local performanceEntryString = FIXED_ONE_BYTE_STRING(isolate, "PerformanceEntry"); diff --git a/src/node_perf_common.h b/src/node_perf_common.h index dc884cac97ce88..02c3cc2d6650f0 100644 --- a/src/node_perf_common.h +++ b/src/node_perf_common.h @@ -60,10 +60,33 @@ enum PerformanceEntryType { node::performance::NODE_PERFORMANCE_MILESTONE_##n); \ } while (0); -struct performance_state { - // doubles first so that they are always sizeof(double)-aligned - double milestones[NODE_PERFORMANCE_MILESTONE_INVALID]; - uint32_t observers[NODE_PERFORMANCE_ENTRY_TYPE_INVALID]; +class performance_state { + public: + explicit performance_state(v8::Isolate* isolate) : + root( + isolate, + sizeof(performance_state_internal)), + milestones( + isolate, + offsetof(performance_state_internal, milestones), + NODE_PERFORMANCE_MILESTONE_INVALID, + root), + observers( + isolate, + offsetof(performance_state_internal, observers), + NODE_PERFORMANCE_ENTRY_TYPE_INVALID, + root) {} + + AliasedBuffer root; + AliasedBuffer milestones; + AliasedBuffer observers; + + private: + struct performance_state_internal { + // doubles first so that they are always sizeof(double)-aligned + double milestones[NODE_PERFORMANCE_MILESTONE_INVALID]; + uint32_t observers[NODE_PERFORMANCE_ENTRY_TYPE_INVALID]; + }; }; } // namespace performance