@@ -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
@@ -419,29 +437,157 @@ void IntervalHistogram::OnStop() {
419437}
420438
421439void IntervalHistogram::Start (const FunctionCallbackInfo<Value>& args) {
422- IntervalHistogram* histogram;
423- ASSIGN_OR_RETURN_UNWRAP (&histogram, args.This ());
424- histogram->OnStart (args[0 ]->IsTrue () ? StartFlags::RESET : StartFlags::NONE );
440+ StartHandleHistogram<IntervalHistogram>(args.This (), args[0 ]->IsTrue ());
425441}
426442
427443void IntervalHistogram::FastStart (Local<Value> receiver, bool reset) {
428444 TRACK_V8_FAST_API_CALL (" histogram.start" );
429- IntervalHistogram* histogram;
430- ASSIGN_OR_RETURN_UNWRAP (&histogram, receiver);
431- histogram->OnStart (reset ? StartFlags::RESET : StartFlags::NONE );
445+ StartHandleHistogram<IntervalHistogram>(receiver, reset);
432446}
433447
434448void IntervalHistogram::Stop (const FunctionCallbackInfo<Value>& args) {
435- IntervalHistogram* histogram;
436- ASSIGN_OR_RETURN_UNWRAP (&histogram, args.This ());
437- histogram->OnStop ();
449+ StopHandleHistogram<IntervalHistogram>(args.This ());
438450}
439451
440452void IntervalHistogram::FastStop (Local<Value> receiver) {
441453 TRACK_V8_FAST_API_CALL (" histogram.stop" );
442- IntervalHistogram* histogram;
443- ASSIGN_OR_RETURN_UNWRAP (&histogram, receiver);
444- histogram->OnStop ();
454+ StopHandleHistogram<IntervalHistogram>(receiver);
455+ }
456+
457+ Local<FunctionTemplate> IterationHistogram::GetConstructorTemplate (
458+ Environment* env) {
459+ Local<FunctionTemplate> tmpl = env->iterationhistogram_constructor_template ();
460+ if (tmpl.IsEmpty ()) {
461+ Isolate* isolate = env->isolate ();
462+ tmpl = NewFunctionTemplate (isolate, nullptr );
463+ tmpl->Inherit (HandleWrap::GetConstructorTemplate (env));
464+ tmpl->SetClassName (FIXED_ONE_BYTE_STRING (isolate, " Histogram" ));
465+ auto instance = tmpl->InstanceTemplate ();
466+ instance->SetInternalFieldCount (IterationHistogram::kInternalFieldCount );
467+ HistogramImpl::AddMethods (isolate, tmpl);
468+ SetFastMethod (isolate, instance, " start" , Start, &fast_start_);
469+ SetFastMethod (isolate, instance, " stop" , Stop, &fast_stop_);
470+ env->set_iterationhistogram_constructor_template (tmpl);
471+ }
472+ return tmpl;
473+ }
474+
475+ void IterationHistogram::RegisterExternalReferences (
476+ ExternalReferenceRegistry* registry) {
477+ registry->Register (Start);
478+ registry->Register (Stop);
479+ registry->Register (fast_start_);
480+ registry->Register (fast_stop_);
481+ HistogramImpl::RegisterExternalReferences (registry);
482+ }
483+
484+ IterationHistogram::IterationHistogram (Environment* env,
485+ Local<Object> wrap,
486+ AsyncWrap::ProviderType type,
487+ const Histogram::Options& options)
488+ : HandleWrap(
489+ env, wrap, reinterpret_cast <uv_handle_t *>(&check_handle_), type),
490+ HistogramImpl(options) {
491+ MakeWeak ();
492+ wrap->SetAlignedPointerInInternalField (
493+ HistogramImpl::InternalFields::kImplField ,
494+ static_cast <HistogramImpl*>(this ),
495+ EmbedderDataTag::kDefault );
496+ uv_check_init (env->event_loop (), &check_handle_);
497+ uv_prepare_init (env->event_loop (), &prepare_handle_);
498+ uv_unref (reinterpret_cast <uv_handle_t *>(&check_handle_));
499+ uv_unref (reinterpret_cast <uv_handle_t *>(&prepare_handle_));
500+ prepare_handle_.data = this ;
501+ }
502+
503+ BaseObjectPtr<IterationHistogram> IterationHistogram::Create (
504+ Environment* env, const Histogram::Options& options) {
505+ Local<Object> obj;
506+ if (!GetConstructorTemplate (env)
507+ ->InstanceTemplate ()
508+ ->NewInstance (env->context ())
509+ .ToLocal (&obj)) {
510+ return nullptr ;
511+ }
512+
513+ return MakeBaseObject<IterationHistogram>(
514+ env, obj, AsyncWrap::PROVIDER_ELDHISTOGRAM , options);
515+ }
516+
517+ void IterationHistogram::PrepareCB (uv_prepare_t * handle) {
518+ IterationHistogram* self = static_cast <IterationHistogram*>(handle->data );
519+ if (!self->enabled_ ) return ;
520+ self->prepare_time_ = uv_hrtime ();
521+ self->timeout_ = uv_backend_timeout (handle->loop );
522+ }
523+
524+ void IterationHistogram::CheckCB (uv_check_t * handle) {
525+ IterationHistogram* self =
526+ ContainerOf (&IterationHistogram::check_handle_, handle);
527+ if (!self->enabled_ ) return ;
528+
529+ uint64_t check_time = uv_hrtime ();
530+ uint64_t poll_time = check_time - self->prepare_time_ ;
531+ uint64_t latency = self->prepare_time_ - self->check_time_ ;
532+
533+ if (self->timeout_ >= 0 ) {
534+ uint64_t timeout_ns = static_cast <uint64_t >(self->timeout_ ) * 1000 * 1000 ;
535+ if (poll_time > timeout_ns) {
536+ latency += poll_time - timeout_ns;
537+ }
538+ }
539+
540+ self->histogram ()->Record (latency == 0 ? 1 : latency);
541+ self->check_time_ = check_time;
542+ }
543+
544+ void IterationHistogram::MemoryInfo (MemoryTracker* tracker) const {
545+ tracker->TrackField (" histogram" , histogram ());
546+ }
547+
548+ void IterationHistogram::OnStart (StartFlags flags) {
549+ if (enabled_ || IsHandleClosing ()) return ;
550+ enabled_ = true ;
551+ if (flags == StartFlags::RESET ) histogram ()->Reset ();
552+ check_time_ = uv_hrtime ();
553+ prepare_time_ = check_time_;
554+ timeout_ = 0 ;
555+ uv_check_start (&check_handle_, CheckCB);
556+ uv_prepare_start (&prepare_handle_, PrepareCB);
557+ uv_unref (reinterpret_cast <uv_handle_t *>(&check_handle_));
558+ uv_unref (reinterpret_cast <uv_handle_t *>(&prepare_handle_));
559+ }
560+
561+ void IterationHistogram::OnStop () {
562+ if (!enabled_ || IsHandleClosing ()) return ;
563+ enabled_ = false ;
564+ uv_check_stop (&check_handle_);
565+ uv_prepare_stop (&prepare_handle_);
566+ }
567+
568+ void IterationHistogram::Close (Local<Value> close_callback) {
569+ if (IsHandleClosing ()) return ;
570+ OnStop ();
571+ HandleWrap::Close (close_callback);
572+ uv_close (reinterpret_cast <uv_handle_t *>(&prepare_handle_), nullptr );
573+ }
574+
575+ void IterationHistogram::Start (const FunctionCallbackInfo<Value>& args) {
576+ StartHandleHistogram<IterationHistogram>(args.This (), args[0 ]->IsTrue ());
577+ }
578+
579+ void IterationHistogram::FastStart (Local<Value> receiver, bool reset) {
580+ TRACK_V8_FAST_API_CALL (" histogram.eventLoopDelay.start" );
581+ StartHandleHistogram<IterationHistogram>(receiver, reset);
582+ }
583+
584+ void IterationHistogram::Stop (const FunctionCallbackInfo<Value>& args) {
585+ StopHandleHistogram<IterationHistogram>(args.This ());
586+ }
587+
588+ void IterationHistogram::FastStop (Local<Value> receiver) {
589+ TRACK_V8_FAST_API_CALL (" histogram.eventLoopDelay.stop" );
590+ StopHandleHistogram<IterationHistogram>(receiver);
445591}
446592
447593void HistogramImpl::GetCount (const FunctionCallbackInfo<Value>& args) {
@@ -607,6 +753,11 @@ HistogramImpl* HistogramImpl::FromJSObject(Local<Value> value) {
607753 HistogramImpl::kImplField , EmbedderDataTag::kDefault ));
608754}
609755
756+ std::unique_ptr<worker::TransferData> IterationHistogram::CloneForMessaging ()
757+ const {
758+ return std::make_unique<HistogramBase::HistogramTransferData>(histogram ());
759+ }
760+
610761std::unique_ptr<worker::TransferData>
611762IntervalHistogram::CloneForMessaging () const {
612763 return std::make_unique<HistogramBase::HistogramTransferData>(histogram ());
0 commit comments