@@ -465,15 +465,29 @@ static void ReallyExit(const FunctionCallbackInfo<Value>& args) {
465465
466466namespace process {
467467
468- BindingData::BindingData (Realm* realm, v8::Local<v8::Object> object)
469- : SnapshotableObject(realm, object, type_int) {
468+ BindingData::BindingData (Realm* realm,
469+ v8::Local<v8::Object> object,
470+ InternalFieldInfo* info)
471+ : SnapshotableObject(realm, object, type_int),
472+ hrtime_buffer_ (realm->isolate (),
473+ kHrTimeBufferLength,
474+ MAYBE_FIELD_PTR(info, hrtime_buffer)) {
470475 Isolate* isolate = realm->isolate ();
471476 Local<Context> context = realm->context ();
472- Local<ArrayBuffer> ab = ArrayBuffer::New (isolate, kBufferSize );
473- array_buffer_.Reset (isolate, ab);
474- object->Set (context, FIXED_ONE_BYTE_STRING (isolate, " hrtimeBuffer" ), ab)
475- .ToChecked ();
476- backing_store_ = ab->GetBackingStore ();
477+
478+ if (info == nullptr ) {
479+ object
480+ ->Set (context,
481+ FIXED_ONE_BYTE_STRING (isolate, " hrtimeBuffer" ),
482+ hrtime_buffer_.GetJSArray ())
483+ .ToChecked ();
484+ } else {
485+ hrtime_buffer_.Deserialize (realm->context ());
486+ }
487+
488+ // The hrtime buffer is referenced from the binding data js object.
489+ // Make the native handle weak to avoid keeping the realm alive.
490+ hrtime_buffer_.MakeWeak ();
477491}
478492
479493v8::CFunction BindingData::fast_number_ (v8::CFunction::Make(FastNumber));
@@ -503,7 +517,7 @@ BindingData* BindingData::FromV8Value(Local<Value> value) {
503517}
504518
505519void BindingData::MemoryInfo (MemoryTracker* tracker) const {
506- tracker->TrackField (" array_buffer " , array_buffer_ );
520+ tracker->TrackField (" hrtime_buffer " , hrtime_buffer_ );
507521}
508522
509523// This is the legacy version of hrtime before BigInt was introduced in
@@ -516,20 +530,19 @@ void BindingData::MemoryInfo(MemoryTracker* tracker) const {
516530// because there is no Uint64Array in JS.
517531// The third entry contains the remaining nanosecond part of the value.
518532void BindingData::NumberImpl (BindingData* receiver) {
519- // Make sure we don't accidentally access buffers wiped for snapshot.
520- CHECK (!receiver->array_buffer_ .IsEmpty ());
521533 uint64_t t = uv_hrtime ();
522- uint32_t * fields = static_cast <uint32_t *>(receiver->backing_store_ ->Data ());
523- fields[0 ] = (t / NANOS_PER_SEC) >> 32 ;
524- fields[1 ] = (t / NANOS_PER_SEC) & 0xffffffff ;
525- fields[2 ] = t % NANOS_PER_SEC;
534+ receiver->hrtime_buffer_ [0 ] = (t / NANOS_PER_SEC) >> 32 ;
535+ receiver->hrtime_buffer_ [1 ] = (t / NANOS_PER_SEC) & 0xffffffff ;
536+ receiver->hrtime_buffer_ [2 ] = t % NANOS_PER_SEC;
526537}
527538
528539void BindingData::BigIntImpl (BindingData* receiver) {
529- // Make sure we don't accidentally access buffers wiped for snapshot.
530- CHECK (!receiver->array_buffer_ .IsEmpty ());
531540 uint64_t t = uv_hrtime ();
532- uint64_t * fields = static_cast <uint64_t *>(receiver->backing_store_ ->Data ());
541+ // The buffer is a Uint32Array, so we need to reinterpret it as a
542+ // Uint64Array to write the value. The buffer is valid at this scope so we
543+ // can safely cast away the constness.
544+ uint64_t * fields = reinterpret_cast <uint64_t *>(
545+ const_cast <uint32_t *>(receiver->hrtime_buffer_ .GetNativeBuffer ()));
533546 fields[0 ] = t;
534547}
535548
@@ -543,18 +556,19 @@ void BindingData::SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args) {
543556
544557bool BindingData::PrepareForSerialization (Local<Context> context,
545558 v8::SnapshotCreator* creator) {
546- // It's not worth keeping.
547- // Release it, we will recreate it when the instance is dehydrated.
548- array_buffer_.Reset ();
559+ DCHECK_NULL (internal_field_info_);
560+ internal_field_info_ = InternalFieldInfoBase::New<InternalFieldInfo>(type ());
561+ internal_field_info_->hrtime_buffer =
562+ hrtime_buffer_.Serialize (context, creator);
549563 // Return true because we need to maintain the reference to the binding from
550564 // JS land.
551565 return true ;
552566}
553567
554568InternalFieldInfoBase* BindingData::Serialize (int index) {
555569 DCHECK_IS_SNAPSHOT_SLOT (index);
556- InternalFieldInfo* info =
557- InternalFieldInfoBase::New<InternalFieldInfo>( type ()) ;
570+ InternalFieldInfo* info = internal_field_info_;
571+ internal_field_info_ = nullptr ;
558572 return info;
559573}
560574
@@ -566,7 +580,9 @@ void BindingData::Deserialize(Local<Context> context,
566580 v8::HandleScope scope (context->GetIsolate ());
567581 Realm* realm = Realm::GetCurrent (context);
568582 // Recreate the buffer in the constructor.
569- BindingData* binding = realm->AddBindingData <BindingData>(holder);
583+ InternalFieldInfo* casted_info = static_cast <InternalFieldInfo*>(info);
584+ BindingData* binding =
585+ realm->AddBindingData <BindingData>(holder, casted_info);
570586 CHECK_NOT_NULL (binding);
571587}
572588
0 commit comments