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