@@ -465,15 +465,29 @@ static void ReallyExit(const FunctionCallbackInfo<Value>& args) {
465
465
466
466
namespace process {
467
467
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)) {
470
475
Isolate* isolate = realm->isolate ();
471
476
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 ();
477
491
}
478
492
479
493
v8::CFunction BindingData::fast_number_ (v8::CFunction::Make(FastNumber));
@@ -503,7 +517,7 @@ BindingData* BindingData::FromV8Value(Local<Value> value) {
503
517
}
504
518
505
519
void BindingData::MemoryInfo (MemoryTracker* tracker) const {
506
- tracker->TrackField (" array_buffer " , array_buffer_ );
520
+ tracker->TrackField (" hrtime_buffer " , hrtime_buffer_ );
507
521
}
508
522
509
523
// This is the legacy version of hrtime before BigInt was introduced in
@@ -516,20 +530,19 @@ void BindingData::MemoryInfo(MemoryTracker* tracker) const {
516
530
// because there is no Uint64Array in JS.
517
531
// The third entry contains the remaining nanosecond part of the value.
518
532
void BindingData::NumberImpl (BindingData* receiver) {
519
- // Make sure we don't accidentally access buffers wiped for snapshot.
520
- CHECK (!receiver->array_buffer_ .IsEmpty ());
521
533
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;
526
537
}
527
538
528
539
void BindingData::BigIntImpl (BindingData* receiver) {
529
- // Make sure we don't accidentally access buffers wiped for snapshot.
530
- CHECK (!receiver->array_buffer_ .IsEmpty ());
531
540
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 ()));
533
546
fields[0 ] = t;
534
547
}
535
548
@@ -543,18 +556,19 @@ void BindingData::SlowNumber(const v8::FunctionCallbackInfo<v8::Value>& args) {
543
556
544
557
bool BindingData::PrepareForSerialization (Local<Context> context,
545
558
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);
549
563
// Return true because we need to maintain the reference to the binding from
550
564
// JS land.
551
565
return true ;
552
566
}
553
567
554
568
InternalFieldInfoBase* BindingData::Serialize (int index) {
555
569
DCHECK_IS_SNAPSHOT_SLOT (index );
556
- InternalFieldInfo* info =
557
- InternalFieldInfoBase::New<InternalFieldInfo>( type ()) ;
570
+ InternalFieldInfo* info = internal_field_info_;
571
+ internal_field_info_ = nullptr ;
558
572
return info;
559
573
}
560
574
@@ -566,7 +580,9 @@ void BindingData::Deserialize(Local<Context> context,
566
580
v8::HandleScope scope (context->GetIsolate ());
567
581
Realm* realm = Realm::GetCurrent (context);
568
582
// 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);
570
586
CHECK_NOT_NULL (binding);
571
587
}
572
588
0 commit comments