@@ -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