@@ -25,6 +25,20 @@ using v8::String;
2525using v8::Uint32;
2626using v8::Value;
2727
28+ template <typename T>
29+ void StartHandleHistogram (Local<Value> receiver, bool reset) {
30+ T* histogram;
31+ ASSIGN_OR_RETURN_UNWRAP (&histogram, receiver);
32+ histogram->OnStart (reset ? T::StartFlags::RESET : T::StartFlags::NONE );
33+ }
34+
35+ template <typename T>
36+ void StopHandleHistogram (Local<Value> receiver) {
37+ T* histogram;
38+ ASSIGN_OR_RETURN_UNWRAP (&histogram, receiver);
39+ histogram->OnStop ();
40+ }
41+
2842Histogram::Histogram (const Options& options) {
2943 hdr_histogram* histogram;
3044 CHECK_EQ (0 , hdr_init (options.lowest ,
@@ -68,6 +82,10 @@ CFunction IntervalHistogram::fast_start_(
6882 CFunction::Make (&IntervalHistogram::FastStart));
6983CFunction IntervalHistogram::fast_stop_ (
7084 CFunction::Make (&IntervalHistogram::FastStop));
85+ CFunction IterationHistogram::fast_start_ (
86+ CFunction::Make (&IterationHistogram::FastStart));
87+ CFunction IterationHistogram::fast_stop_ (
88+ CFunction::Make (&IterationHistogram::FastStop));
7189
7290void HistogramImpl::AddMethods (Isolate* isolate, Local<FunctionTemplate> tmpl) {
7391 // TODO(@jasnell): The bigint API variations do not yet support fast
@@ -416,29 +434,157 @@ void IntervalHistogram::OnStop() {
416434}
417435
418436void IntervalHistogram::Start (const FunctionCallbackInfo<Value>& args) {
419- IntervalHistogram* histogram;
420- ASSIGN_OR_RETURN_UNWRAP (&histogram, args.This ());
421- histogram->OnStart (args[0 ]->IsTrue () ? StartFlags::RESET : StartFlags::NONE );
437+ StartHandleHistogram<IntervalHistogram>(args.This (), args[0 ]->IsTrue ());
422438}
423439
424440void IntervalHistogram::FastStart (Local<Value> receiver, bool reset) {
425441 TRACK_V8_FAST_API_CALL (" histogram.start" );
426- IntervalHistogram* histogram;
427- ASSIGN_OR_RETURN_UNWRAP (&histogram, receiver);
428- histogram->OnStart (reset ? StartFlags::RESET : StartFlags::NONE );
442+ StartHandleHistogram<IntervalHistogram>(receiver, reset);
429443}
430444
431445void IntervalHistogram::Stop (const FunctionCallbackInfo<Value>& args) {
432- IntervalHistogram* histogram;
433- ASSIGN_OR_RETURN_UNWRAP (&histogram, args.This ());
434- histogram->OnStop ();
446+ StopHandleHistogram<IntervalHistogram>(args.This ());
435447}
436448
437449void IntervalHistogram::FastStop (Local<Value> receiver) {
438450 TRACK_V8_FAST_API_CALL (" histogram.stop" );
439- IntervalHistogram* histogram;
440- ASSIGN_OR_RETURN_UNWRAP (&histogram, receiver);
441- histogram->OnStop ();
451+ StopHandleHistogram<IntervalHistogram>(receiver);
452+ }
453+
454+ Local<FunctionTemplate> IterationHistogram::GetConstructorTemplate (
455+ Environment* env) {
456+ Local<FunctionTemplate> tmpl = env->iterationhistogram_constructor_template ();
457+ if (tmpl.IsEmpty ()) {
458+ Isolate* isolate = env->isolate ();
459+ tmpl = NewFunctionTemplate (isolate, nullptr );
460+ tmpl->Inherit (HandleWrap::GetConstructorTemplate (env));
461+ tmpl->SetClassName (FIXED_ONE_BYTE_STRING (isolate, " Histogram" ));
462+ auto instance = tmpl->InstanceTemplate ();
463+ instance->SetInternalFieldCount (IterationHistogram::kInternalFieldCount );
464+ HistogramImpl::AddMethods (isolate, tmpl);
465+ SetFastMethod (isolate, instance, " start" , Start, &fast_start_);
466+ SetFastMethod (isolate, instance, " stop" , Stop, &fast_stop_);
467+ env->set_iterationhistogram_constructor_template (tmpl);
468+ }
469+ return tmpl;
470+ }
471+
472+ void IterationHistogram::RegisterExternalReferences (
473+ ExternalReferenceRegistry* registry) {
474+ registry->Register (Start);
475+ registry->Register (Stop);
476+ registry->Register (fast_start_);
477+ registry->Register (fast_stop_);
478+ HistogramImpl::RegisterExternalReferences (registry);
479+ }
480+
481+ IterationHistogram::IterationHistogram (Environment* env,
482+ Local<Object> wrap,
483+ AsyncWrap::ProviderType type,
484+ const Histogram::Options& options)
485+ : HandleWrap(
486+ env, wrap, reinterpret_cast <uv_handle_t *>(&check_handle_), type),
487+ HistogramImpl(options) {
488+ MakeWeak ();
489+ wrap->SetAlignedPointerInInternalField (
490+ HistogramImpl::InternalFields::kImplField ,
491+ static_cast <HistogramImpl*>(this ),
492+ EmbedderDataTag::kDefault );
493+ uv_check_init (env->event_loop (), &check_handle_);
494+ uv_prepare_init (env->event_loop (), &prepare_handle_);
495+ uv_unref (reinterpret_cast <uv_handle_t *>(&check_handle_));
496+ uv_unref (reinterpret_cast <uv_handle_t *>(&prepare_handle_));
497+ prepare_handle_.data = this ;
498+ }
499+
500+ BaseObjectPtr<IterationHistogram> IterationHistogram::Create (
501+ Environment* env, const Histogram::Options& options) {
502+ Local<Object> obj;
503+ if (!GetConstructorTemplate (env)
504+ ->InstanceTemplate ()
505+ ->NewInstance (env->context ())
506+ .ToLocal (&obj)) {
507+ return nullptr ;
508+ }
509+
510+ return MakeBaseObject<IterationHistogram>(
511+ env, obj, AsyncWrap::PROVIDER_ELDHISTOGRAM , options);
512+ }
513+
514+ void IterationHistogram::PrepareCB (uv_prepare_t * handle) {
515+ IterationHistogram* self = static_cast <IterationHistogram*>(handle->data );
516+ if (!self->enabled_ ) return ;
517+ self->prepare_time_ = uv_hrtime ();
518+ self->timeout_ = uv_backend_timeout (handle->loop );
519+ }
520+
521+ void IterationHistogram::CheckCB (uv_check_t * handle) {
522+ IterationHistogram* self =
523+ ContainerOf (&IterationHistogram::check_handle_, handle);
524+ if (!self->enabled_ ) return ;
525+
526+ uint64_t check_time = uv_hrtime ();
527+ uint64_t poll_time = check_time - self->prepare_time_ ;
528+ uint64_t latency = self->prepare_time_ - self->check_time_ ;
529+
530+ if (self->timeout_ >= 0 ) {
531+ uint64_t timeout_ns = static_cast <uint64_t >(self->timeout_ ) * 1000 * 1000 ;
532+ if (poll_time > timeout_ns) {
533+ latency += poll_time - timeout_ns;
534+ }
535+ }
536+
537+ self->histogram ()->Record (latency == 0 ? 1 : latency);
538+ self->check_time_ = check_time;
539+ }
540+
541+ void IterationHistogram::MemoryInfo (MemoryTracker* tracker) const {
542+ tracker->TrackField (" histogram" , histogram ());
543+ }
544+
545+ void IterationHistogram::OnStart (StartFlags flags) {
546+ if (enabled_ || IsHandleClosing ()) return ;
547+ enabled_ = true ;
548+ if (flags == StartFlags::RESET ) histogram ()->Reset ();
549+ check_time_ = uv_hrtime ();
550+ prepare_time_ = check_time_;
551+ timeout_ = 0 ;
552+ uv_check_start (&check_handle_, CheckCB);
553+ uv_prepare_start (&prepare_handle_, PrepareCB);
554+ uv_unref (reinterpret_cast <uv_handle_t *>(&check_handle_));
555+ uv_unref (reinterpret_cast <uv_handle_t *>(&prepare_handle_));
556+ }
557+
558+ void IterationHistogram::OnStop () {
559+ if (!enabled_ || IsHandleClosing ()) return ;
560+ enabled_ = false ;
561+ uv_check_stop (&check_handle_);
562+ uv_prepare_stop (&prepare_handle_);
563+ }
564+
565+ void IterationHistogram::Close (Local<Value> close_callback) {
566+ if (IsHandleClosing ()) return ;
567+ OnStop ();
568+ HandleWrap::Close (close_callback);
569+ uv_close (reinterpret_cast <uv_handle_t *>(&prepare_handle_), nullptr );
570+ }
571+
572+ void IterationHistogram::Start (const FunctionCallbackInfo<Value>& args) {
573+ StartHandleHistogram<IterationHistogram>(args.This (), args[0 ]->IsTrue ());
574+ }
575+
576+ void IterationHistogram::FastStart (Local<Value> receiver, bool reset) {
577+ TRACK_V8_FAST_API_CALL (" histogram.eventLoopDelay.start" );
578+ StartHandleHistogram<IterationHistogram>(receiver, reset);
579+ }
580+
581+ void IterationHistogram::Stop (const FunctionCallbackInfo<Value>& args) {
582+ StopHandleHistogram<IterationHistogram>(args.This ());
583+ }
584+
585+ void IterationHistogram::FastStop (Local<Value> receiver) {
586+ TRACK_V8_FAST_API_CALL (" histogram.eventLoopDelay.stop" );
587+ StopHandleHistogram<IterationHistogram>(receiver);
442588}
443589
444590void HistogramImpl::GetCount (const FunctionCallbackInfo<Value>& args) {
@@ -604,6 +750,11 @@ HistogramImpl* HistogramImpl::FromJSObject(Local<Value> value) {
604750 obj->GetAlignedPointerFromInternalField (HistogramImpl::kImplField ));
605751}
606752
753+ std::unique_ptr<worker::TransferData> IterationHistogram::CloneForMessaging ()
754+ const {
755+ return std::make_unique<HistogramBase::HistogramTransferData>(histogram ());
756+ }
757+
607758std::unique_ptr<worker::TransferData>
608759IntervalHistogram::CloneForMessaging () const {
609760 return std::make_unique<HistogramBase::HistogramTransferData>(histogram ());
0 commit comments