11cb0ef41Sopenharmony_ci#include "node_perf.h"
21cb0ef41Sopenharmony_ci#include "aliased_buffer-inl.h"
31cb0ef41Sopenharmony_ci#include "env-inl.h"
41cb0ef41Sopenharmony_ci#include "histogram-inl.h"
51cb0ef41Sopenharmony_ci#include "memory_tracker-inl.h"
61cb0ef41Sopenharmony_ci#include "node_buffer.h"
71cb0ef41Sopenharmony_ci#include "node_external_reference.h"
81cb0ef41Sopenharmony_ci#include "node_internals.h"
91cb0ef41Sopenharmony_ci#include "node_process-inl.h"
101cb0ef41Sopenharmony_ci#include "util-inl.h"
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include <cinttypes>
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_cinamespace node {
151cb0ef41Sopenharmony_cinamespace performance {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciusing v8::Context;
181cb0ef41Sopenharmony_ciusing v8::DontDelete;
191cb0ef41Sopenharmony_ciusing v8::Function;
201cb0ef41Sopenharmony_ciusing v8::FunctionCallbackInfo;
211cb0ef41Sopenharmony_ciusing v8::FunctionTemplate;
221cb0ef41Sopenharmony_ciusing v8::GCCallbackFlags;
231cb0ef41Sopenharmony_ciusing v8::GCType;
241cb0ef41Sopenharmony_ciusing v8::Int32;
251cb0ef41Sopenharmony_ciusing v8::Integer;
261cb0ef41Sopenharmony_ciusing v8::Isolate;
271cb0ef41Sopenharmony_ciusing v8::Local;
281cb0ef41Sopenharmony_ciusing v8::MaybeLocal;
291cb0ef41Sopenharmony_ciusing v8::Number;
301cb0ef41Sopenharmony_ciusing v8::Object;
311cb0ef41Sopenharmony_ciusing v8::PropertyAttribute;
321cb0ef41Sopenharmony_ciusing v8::ReadOnly;
331cb0ef41Sopenharmony_ciusing v8::String;
341cb0ef41Sopenharmony_ciusing v8::Value;
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci// Microseconds in a millisecond, as a float.
371cb0ef41Sopenharmony_ci#define MICROS_PER_MILLIS 1e3
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci// https://w3c.github.io/hr-time/#dfn-time-origin
401cb0ef41Sopenharmony_ciconst uint64_t timeOrigin = PERFORMANCE_NOW();
411cb0ef41Sopenharmony_ci// https://w3c.github.io/hr-time/#dfn-time-origin-timestamp
421cb0ef41Sopenharmony_ciconst double timeOriginTimestamp = GetCurrentTimeInMicroseconds();
431cb0ef41Sopenharmony_ciuint64_t performance_v8_start;
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ciPerformanceState::PerformanceState(Isolate* isolate,
461cb0ef41Sopenharmony_ci                                   const PerformanceState::SerializeInfo* info)
471cb0ef41Sopenharmony_ci    : root(isolate,
481cb0ef41Sopenharmony_ci           sizeof(performance_state_internal),
491cb0ef41Sopenharmony_ci           MAYBE_FIELD_PTR(info, root)),
501cb0ef41Sopenharmony_ci      milestones(isolate,
511cb0ef41Sopenharmony_ci                 offsetof(performance_state_internal, milestones),
521cb0ef41Sopenharmony_ci                 NODE_PERFORMANCE_MILESTONE_INVALID,
531cb0ef41Sopenharmony_ci                 root,
541cb0ef41Sopenharmony_ci                 MAYBE_FIELD_PTR(info, milestones)),
551cb0ef41Sopenharmony_ci      observers(isolate,
561cb0ef41Sopenharmony_ci                offsetof(performance_state_internal, observers),
571cb0ef41Sopenharmony_ci                NODE_PERFORMANCE_ENTRY_TYPE_INVALID,
581cb0ef41Sopenharmony_ci                root,
591cb0ef41Sopenharmony_ci                MAYBE_FIELD_PTR(info, observers)) {
601cb0ef41Sopenharmony_ci  if (info == nullptr) {
611cb0ef41Sopenharmony_ci    for (size_t i = 0; i < milestones.Length(); i++) milestones[i] = -1.;
621cb0ef41Sopenharmony_ci  }
631cb0ef41Sopenharmony_ci}
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ciPerformanceState::SerializeInfo PerformanceState::Serialize(
661cb0ef41Sopenharmony_ci    v8::Local<v8::Context> context, v8::SnapshotCreator* creator) {
671cb0ef41Sopenharmony_ci  SerializeInfo info{root.Serialize(context, creator),
681cb0ef41Sopenharmony_ci                     milestones.Serialize(context, creator),
691cb0ef41Sopenharmony_ci                     observers.Serialize(context, creator)};
701cb0ef41Sopenharmony_ci  return info;
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_civoid PerformanceState::Deserialize(v8::Local<v8::Context> context) {
741cb0ef41Sopenharmony_ci  root.Deserialize(context);
751cb0ef41Sopenharmony_ci  // This is just done to set up the pointers, we will actually reset
761cb0ef41Sopenharmony_ci  // all the milestones after deserialization.
771cb0ef41Sopenharmony_ci  milestones.Deserialize(context);
781cb0ef41Sopenharmony_ci  observers.Deserialize(context);
791cb0ef41Sopenharmony_ci}
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream& o,
821cb0ef41Sopenharmony_ci                         const PerformanceState::SerializeInfo& i) {
831cb0ef41Sopenharmony_ci  o << "{\n"
841cb0ef41Sopenharmony_ci    << "  " << i.root << ",  // root\n"
851cb0ef41Sopenharmony_ci    << "  " << i.milestones << ",  // milestones\n"
861cb0ef41Sopenharmony_ci    << "  " << i.observers << ",  // observers\n"
871cb0ef41Sopenharmony_ci    << "}";
881cb0ef41Sopenharmony_ci  return o;
891cb0ef41Sopenharmony_ci}
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_civoid PerformanceState::Mark(PerformanceMilestone milestone, uint64_t ts) {
921cb0ef41Sopenharmony_ci  this->milestones[milestone] = static_cast<double>(ts);
931cb0ef41Sopenharmony_ci  TRACE_EVENT_INSTANT_WITH_TIMESTAMP0(
941cb0ef41Sopenharmony_ci      TRACING_CATEGORY_NODE1(bootstrap),
951cb0ef41Sopenharmony_ci      GetPerformanceMilestoneName(milestone),
961cb0ef41Sopenharmony_ci      TRACE_EVENT_SCOPE_THREAD, ts / 1000);
971cb0ef41Sopenharmony_ci}
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci// Allows specific Node.js lifecycle milestones to be set from JavaScript
1001cb0ef41Sopenharmony_civoid MarkMilestone(const FunctionCallbackInfo<Value>& args) {
1011cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
1021cb0ef41Sopenharmony_ci  PerformanceMilestone milestone =
1031cb0ef41Sopenharmony_ci      static_cast<PerformanceMilestone>(args[0].As<Int32>()->Value());
1041cb0ef41Sopenharmony_ci  if (milestone != NODE_PERFORMANCE_MILESTONE_INVALID)
1051cb0ef41Sopenharmony_ci    env->performance_state()->Mark(milestone);
1061cb0ef41Sopenharmony_ci}
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_civoid SetupPerformanceObservers(const FunctionCallbackInfo<Value>& args) {
1091cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
1101cb0ef41Sopenharmony_ci  CHECK(args[0]->IsFunction());
1111cb0ef41Sopenharmony_ci  env->set_performance_entry_callback(args[0].As<Function>());
1121cb0ef41Sopenharmony_ci}
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_ci// Marks the start of a GC cycle
1151cb0ef41Sopenharmony_civoid MarkGarbageCollectionStart(
1161cb0ef41Sopenharmony_ci    Isolate* isolate,
1171cb0ef41Sopenharmony_ci    GCType type,
1181cb0ef41Sopenharmony_ci    GCCallbackFlags flags,
1191cb0ef41Sopenharmony_ci    void* data) {
1201cb0ef41Sopenharmony_ci  Environment* env = static_cast<Environment*>(data);
1211cb0ef41Sopenharmony_ci  // Prevent gc callback from reentering with different type
1221cb0ef41Sopenharmony_ci  // See https://github.com/nodejs/node/issues/44046
1231cb0ef41Sopenharmony_ci  if (env->performance_state()->current_gc_type != 0) {
1241cb0ef41Sopenharmony_ci    return;
1251cb0ef41Sopenharmony_ci  }
1261cb0ef41Sopenharmony_ci  env->performance_state()->performance_last_gc_start_mark = PERFORMANCE_NOW();
1271cb0ef41Sopenharmony_ci  env->performance_state()->current_gc_type = type;
1281cb0ef41Sopenharmony_ci}
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ciMaybeLocal<Object> GCPerformanceEntryTraits::GetDetails(
1311cb0ef41Sopenharmony_ci    Environment* env,
1321cb0ef41Sopenharmony_ci    const GCPerformanceEntry& entry) {
1331cb0ef41Sopenharmony_ci  Local<Object> obj = Object::New(env->isolate());
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  if (!obj->Set(
1361cb0ef41Sopenharmony_ci          env->context(),
1371cb0ef41Sopenharmony_ci          env->kind_string(),
1381cb0ef41Sopenharmony_ci          Integer::NewFromUnsigned(
1391cb0ef41Sopenharmony_ci              env->isolate(),
1401cb0ef41Sopenharmony_ci              entry.details.kind)).IsJust()) {
1411cb0ef41Sopenharmony_ci    return MaybeLocal<Object>();
1421cb0ef41Sopenharmony_ci  }
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci  if (!obj->Set(
1451cb0ef41Sopenharmony_ci          env->context(),
1461cb0ef41Sopenharmony_ci          env->flags_string(),
1471cb0ef41Sopenharmony_ci          Integer::NewFromUnsigned(
1481cb0ef41Sopenharmony_ci              env->isolate(),
1491cb0ef41Sopenharmony_ci              entry.details.flags)).IsJust()) {
1501cb0ef41Sopenharmony_ci    return MaybeLocal<Object>();
1511cb0ef41Sopenharmony_ci  }
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_ci  return obj;
1541cb0ef41Sopenharmony_ci}
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci// Marks the end of a GC cycle
1571cb0ef41Sopenharmony_civoid MarkGarbageCollectionEnd(
1581cb0ef41Sopenharmony_ci    Isolate* isolate,
1591cb0ef41Sopenharmony_ci    GCType type,
1601cb0ef41Sopenharmony_ci    GCCallbackFlags flags,
1611cb0ef41Sopenharmony_ci    void* data) {
1621cb0ef41Sopenharmony_ci  Environment* env = static_cast<Environment*>(data);
1631cb0ef41Sopenharmony_ci  PerformanceState* state = env->performance_state();
1641cb0ef41Sopenharmony_ci  if (type != state->current_gc_type) {
1651cb0ef41Sopenharmony_ci    return;
1661cb0ef41Sopenharmony_ci  }
1671cb0ef41Sopenharmony_ci  env->performance_state()->current_gc_type = 0;
1681cb0ef41Sopenharmony_ci  // If no one is listening to gc performance entries, do not create them.
1691cb0ef41Sopenharmony_ci  if (LIKELY(!state->observers[NODE_PERFORMANCE_ENTRY_TYPE_GC]))
1701cb0ef41Sopenharmony_ci    return;
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci  double start_time =
1731cb0ef41Sopenharmony_ci      (state->performance_last_gc_start_mark - timeOrigin) / 1e6;
1741cb0ef41Sopenharmony_ci  double duration =
1751cb0ef41Sopenharmony_ci      (PERFORMANCE_NOW() / 1e6) - (state->performance_last_gc_start_mark / 1e6);
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ci  std::unique_ptr<GCPerformanceEntry> entry =
1781cb0ef41Sopenharmony_ci      std::make_unique<GCPerformanceEntry>(
1791cb0ef41Sopenharmony_ci          "gc",
1801cb0ef41Sopenharmony_ci          start_time,
1811cb0ef41Sopenharmony_ci          duration,
1821cb0ef41Sopenharmony_ci          GCPerformanceEntry::Details(static_cast<PerformanceGCKind>(type),
1831cb0ef41Sopenharmony_ci                                      static_cast<PerformanceGCFlags>(flags)));
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci  env->SetImmediate([entry = std::move(entry)](Environment* env) {
1861cb0ef41Sopenharmony_ci    entry->Notify(env);
1871cb0ef41Sopenharmony_ci  }, CallbackFlags::kUnrefed);
1881cb0ef41Sopenharmony_ci}
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_civoid GarbageCollectionCleanupHook(void* data) {
1911cb0ef41Sopenharmony_ci  Environment* env = static_cast<Environment*>(data);
1921cb0ef41Sopenharmony_ci  // Reset current_gc_type to 0
1931cb0ef41Sopenharmony_ci  env->performance_state()->current_gc_type = 0;
1941cb0ef41Sopenharmony_ci  env->isolate()->RemoveGCPrologueCallback(MarkGarbageCollectionStart, data);
1951cb0ef41Sopenharmony_ci  env->isolate()->RemoveGCEpilogueCallback(MarkGarbageCollectionEnd, data);
1961cb0ef41Sopenharmony_ci}
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_cistatic void InstallGarbageCollectionTracking(
1991cb0ef41Sopenharmony_ci    const FunctionCallbackInfo<Value>& args) {
2001cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
2011cb0ef41Sopenharmony_ci  // Reset current_gc_type to 0
2021cb0ef41Sopenharmony_ci  env->performance_state()->current_gc_type = 0;
2031cb0ef41Sopenharmony_ci  env->isolate()->AddGCPrologueCallback(MarkGarbageCollectionStart,
2041cb0ef41Sopenharmony_ci                                        static_cast<void*>(env));
2051cb0ef41Sopenharmony_ci  env->isolate()->AddGCEpilogueCallback(MarkGarbageCollectionEnd,
2061cb0ef41Sopenharmony_ci                                        static_cast<void*>(env));
2071cb0ef41Sopenharmony_ci  env->AddCleanupHook(GarbageCollectionCleanupHook, env);
2081cb0ef41Sopenharmony_ci}
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_cistatic void RemoveGarbageCollectionTracking(
2111cb0ef41Sopenharmony_ci  const FunctionCallbackInfo<Value> &args) {
2121cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
2131cb0ef41Sopenharmony_ci
2141cb0ef41Sopenharmony_ci  env->RemoveCleanupHook(GarbageCollectionCleanupHook, env);
2151cb0ef41Sopenharmony_ci  GarbageCollectionCleanupHook(env);
2161cb0ef41Sopenharmony_ci}
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci// Notify a custom PerformanceEntry to observers
2191cb0ef41Sopenharmony_civoid Notify(const FunctionCallbackInfo<Value>& args) {
2201cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
2211cb0ef41Sopenharmony_ci  Utf8Value type(env->isolate(), args[0]);
2221cb0ef41Sopenharmony_ci  Local<Value> entry = args[1];
2231cb0ef41Sopenharmony_ci  PerformanceEntryType entry_type = ToPerformanceEntryTypeEnum(*type);
2241cb0ef41Sopenharmony_ci  AliasedUint32Array& observers = env->performance_state()->observers;
2251cb0ef41Sopenharmony_ci  if (entry_type != NODE_PERFORMANCE_ENTRY_TYPE_INVALID &&
2261cb0ef41Sopenharmony_ci      observers[entry_type]) {
2271cb0ef41Sopenharmony_ci    USE(env->performance_entry_callback()->
2281cb0ef41Sopenharmony_ci      Call(env->context(), Undefined(env->isolate()), 1, &entry));
2291cb0ef41Sopenharmony_ci  }
2301cb0ef41Sopenharmony_ci}
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci// Return idle time of the event loop
2331cb0ef41Sopenharmony_civoid LoopIdleTime(const FunctionCallbackInfo<Value>& args) {
2341cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
2351cb0ef41Sopenharmony_ci  uint64_t idle_time = uv_metrics_idle_time(env->event_loop());
2361cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(1.0 * idle_time / 1e6);
2371cb0ef41Sopenharmony_ci}
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_civoid CreateELDHistogram(const FunctionCallbackInfo<Value>& args) {
2401cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
2411cb0ef41Sopenharmony_ci  int64_t interval = args[0].As<Integer>()->Value();
2421cb0ef41Sopenharmony_ci  CHECK_GT(interval, 0);
2431cb0ef41Sopenharmony_ci  BaseObjectPtr<IntervalHistogram> histogram =
2441cb0ef41Sopenharmony_ci      IntervalHistogram::Create(env, interval, [](Histogram& histogram) {
2451cb0ef41Sopenharmony_ci        uint64_t delta = histogram.RecordDelta();
2461cb0ef41Sopenharmony_ci        TRACE_COUNTER1(TRACING_CATEGORY_NODE2(perf, event_loop),
2471cb0ef41Sopenharmony_ci                        "delay", delta);
2481cb0ef41Sopenharmony_ci        TRACE_COUNTER1(TRACING_CATEGORY_NODE2(perf, event_loop),
2491cb0ef41Sopenharmony_ci                      "min", histogram.Min());
2501cb0ef41Sopenharmony_ci        TRACE_COUNTER1(TRACING_CATEGORY_NODE2(perf, event_loop),
2511cb0ef41Sopenharmony_ci                      "max", histogram.Max());
2521cb0ef41Sopenharmony_ci        TRACE_COUNTER1(TRACING_CATEGORY_NODE2(perf, event_loop),
2531cb0ef41Sopenharmony_ci                      "mean", histogram.Mean());
2541cb0ef41Sopenharmony_ci        TRACE_COUNTER1(TRACING_CATEGORY_NODE2(perf, event_loop),
2551cb0ef41Sopenharmony_ci                      "stddev", histogram.Stddev());
2561cb0ef41Sopenharmony_ci      }, Histogram::Options { 1000 });
2571cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(histogram->object());
2581cb0ef41Sopenharmony_ci}
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_civoid GetTimeOrigin(const FunctionCallbackInfo<Value>& args) {
2611cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(Number::New(args.GetIsolate(), timeOrigin / 1e6));
2621cb0ef41Sopenharmony_ci}
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_civoid GetTimeOriginTimeStamp(const FunctionCallbackInfo<Value>& args) {
2651cb0ef41Sopenharmony_ci  args.GetReturnValue().Set(
2661cb0ef41Sopenharmony_ci      Number::New(args.GetIsolate(), timeOriginTimestamp / MICROS_PER_MILLIS));
2671cb0ef41Sopenharmony_ci}
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_civoid MarkBootstrapComplete(const FunctionCallbackInfo<Value>& args) {
2701cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(args);
2711cb0ef41Sopenharmony_ci  env->performance_state()->Mark(
2721cb0ef41Sopenharmony_ci      performance::NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
2731cb0ef41Sopenharmony_ci}
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_civoid Initialize(Local<Object> target,
2761cb0ef41Sopenharmony_ci                Local<Value> unused,
2771cb0ef41Sopenharmony_ci                Local<Context> context,
2781cb0ef41Sopenharmony_ci                void* priv) {
2791cb0ef41Sopenharmony_ci  Environment* env = Environment::GetCurrent(context);
2801cb0ef41Sopenharmony_ci  Isolate* isolate = env->isolate();
2811cb0ef41Sopenharmony_ci  PerformanceState* state = env->performance_state();
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci  target->Set(context,
2841cb0ef41Sopenharmony_ci              FIXED_ONE_BYTE_STRING(isolate, "observerCounts"),
2851cb0ef41Sopenharmony_ci              state->observers.GetJSArray()).Check();
2861cb0ef41Sopenharmony_ci  target->Set(context,
2871cb0ef41Sopenharmony_ci              FIXED_ONE_BYTE_STRING(isolate, "milestones"),
2881cb0ef41Sopenharmony_ci              state->milestones.GetJSArray()).Check();
2891cb0ef41Sopenharmony_ci
2901cb0ef41Sopenharmony_ci  Local<String> performanceEntryString =
2911cb0ef41Sopenharmony_ci      FIXED_ONE_BYTE_STRING(isolate, "PerformanceEntry");
2921cb0ef41Sopenharmony_ci
2931cb0ef41Sopenharmony_ci  Local<FunctionTemplate> pe = FunctionTemplate::New(isolate);
2941cb0ef41Sopenharmony_ci  pe->SetClassName(performanceEntryString);
2951cb0ef41Sopenharmony_ci  Local<Function> fn = pe->GetFunction(context).ToLocalChecked();
2961cb0ef41Sopenharmony_ci  target->Set(context, performanceEntryString, fn).Check();
2971cb0ef41Sopenharmony_ci  env->set_performance_entry_template(fn);
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_ci  SetMethod(context, target, "markMilestone", MarkMilestone);
3001cb0ef41Sopenharmony_ci  SetMethod(context, target, "setupObservers", SetupPerformanceObservers);
3011cb0ef41Sopenharmony_ci  SetMethod(context,
3021cb0ef41Sopenharmony_ci            target,
3031cb0ef41Sopenharmony_ci            "installGarbageCollectionTracking",
3041cb0ef41Sopenharmony_ci            InstallGarbageCollectionTracking);
3051cb0ef41Sopenharmony_ci  SetMethod(context,
3061cb0ef41Sopenharmony_ci            target,
3071cb0ef41Sopenharmony_ci            "removeGarbageCollectionTracking",
3081cb0ef41Sopenharmony_ci            RemoveGarbageCollectionTracking);
3091cb0ef41Sopenharmony_ci  SetMethod(context, target, "notify", Notify);
3101cb0ef41Sopenharmony_ci  SetMethod(context, target, "loopIdleTime", LoopIdleTime);
3111cb0ef41Sopenharmony_ci  SetMethod(context, target, "getTimeOrigin", GetTimeOrigin);
3121cb0ef41Sopenharmony_ci  SetMethod(context, target, "getTimeOriginTimestamp", GetTimeOriginTimeStamp);
3131cb0ef41Sopenharmony_ci  SetMethod(context, target, "createELDHistogram", CreateELDHistogram);
3141cb0ef41Sopenharmony_ci  SetMethod(context, target, "markBootstrapComplete", MarkBootstrapComplete);
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci  Local<Object> constants = Object::New(isolate);
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(constants, NODE_PERFORMANCE_GC_MAJOR);
3191cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(constants, NODE_PERFORMANCE_GC_MINOR);
3201cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(constants, NODE_PERFORMANCE_GC_INCREMENTAL);
3211cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(constants, NODE_PERFORMANCE_GC_WEAKCB);
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(
3241cb0ef41Sopenharmony_ci    constants, NODE_PERFORMANCE_GC_FLAGS_NO);
3251cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(
3261cb0ef41Sopenharmony_ci    constants, NODE_PERFORMANCE_GC_FLAGS_CONSTRUCT_RETAINED);
3271cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(
3281cb0ef41Sopenharmony_ci    constants, NODE_PERFORMANCE_GC_FLAGS_FORCED);
3291cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(
3301cb0ef41Sopenharmony_ci    constants, NODE_PERFORMANCE_GC_FLAGS_SYNCHRONOUS_PHANTOM_PROCESSING);
3311cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(
3321cb0ef41Sopenharmony_ci    constants, NODE_PERFORMANCE_GC_FLAGS_ALL_AVAILABLE_GARBAGE);
3331cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(
3341cb0ef41Sopenharmony_ci    constants, NODE_PERFORMANCE_GC_FLAGS_ALL_EXTERNAL_MEMORY);
3351cb0ef41Sopenharmony_ci  NODE_DEFINE_CONSTANT(
3361cb0ef41Sopenharmony_ci    constants, NODE_PERFORMANCE_GC_FLAGS_SCHEDULE_IDLE);
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci#define V(name, _)                                                            \
3391cb0ef41Sopenharmony_ci  NODE_DEFINE_HIDDEN_CONSTANT(constants, NODE_PERFORMANCE_ENTRY_TYPE_##name);
3401cb0ef41Sopenharmony_ci  NODE_PERFORMANCE_ENTRY_TYPES(V)
3411cb0ef41Sopenharmony_ci#undef V
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci#define V(name, _)                                                            \
3441cb0ef41Sopenharmony_ci  NODE_DEFINE_HIDDEN_CONSTANT(constants, NODE_PERFORMANCE_MILESTONE_##name);
3451cb0ef41Sopenharmony_ci  NODE_PERFORMANCE_MILESTONES(V)
3461cb0ef41Sopenharmony_ci#undef V
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ci  PropertyAttribute attr =
3491cb0ef41Sopenharmony_ci      static_cast<PropertyAttribute>(ReadOnly | DontDelete);
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_ci  target->DefineOwnProperty(context,
3521cb0ef41Sopenharmony_ci                            env->constants_string(),
3531cb0ef41Sopenharmony_ci                            constants,
3541cb0ef41Sopenharmony_ci                            attr).ToChecked();
3551cb0ef41Sopenharmony_ci
3561cb0ef41Sopenharmony_ci  HistogramBase::Initialize(env, target);
3571cb0ef41Sopenharmony_ci}
3581cb0ef41Sopenharmony_ci
3591cb0ef41Sopenharmony_civoid RegisterExternalReferences(ExternalReferenceRegistry* registry) {
3601cb0ef41Sopenharmony_ci  registry->Register(MarkMilestone);
3611cb0ef41Sopenharmony_ci  registry->Register(SetupPerformanceObservers);
3621cb0ef41Sopenharmony_ci  registry->Register(InstallGarbageCollectionTracking);
3631cb0ef41Sopenharmony_ci  registry->Register(RemoveGarbageCollectionTracking);
3641cb0ef41Sopenharmony_ci  registry->Register(Notify);
3651cb0ef41Sopenharmony_ci  registry->Register(LoopIdleTime);
3661cb0ef41Sopenharmony_ci  registry->Register(GetTimeOrigin);
3671cb0ef41Sopenharmony_ci  registry->Register(GetTimeOriginTimeStamp);
3681cb0ef41Sopenharmony_ci  registry->Register(CreateELDHistogram);
3691cb0ef41Sopenharmony_ci  registry->Register(MarkBootstrapComplete);
3701cb0ef41Sopenharmony_ci  HistogramBase::RegisterExternalReferences(registry);
3711cb0ef41Sopenharmony_ci  IntervalHistogram::RegisterExternalReferences(registry);
3721cb0ef41Sopenharmony_ci}
3731cb0ef41Sopenharmony_ci}  // namespace performance
3741cb0ef41Sopenharmony_ci}  // namespace node
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_ciNODE_BINDING_CONTEXT_AWARE_INTERNAL(performance, node::performance::Initialize)
3771cb0ef41Sopenharmony_ciNODE_BINDING_EXTERNAL_REFERENCE(performance,
3781cb0ef41Sopenharmony_ci                                node::performance::RegisterExternalReferences)
379