44#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55
66#include < cinttypes>
7+ #include < iostream>
78#include " util-inl.h"
89#include " v8.h"
910
1011namespace node {
1112
13+ typedef size_t AliasedBufferInfo;
14+
1215/* *
1316 * Do not use this class directly when creating instances of it - use the
1417 * Aliased*Array defined at the end of this file instead.
@@ -32,9 +35,15 @@ template <class NativeT,
3235 typename = std::enable_if_t <std::is_scalar<NativeT>::value>>
3336class AliasedBufferBase {
3437 public:
35- AliasedBufferBase (v8::Isolate* isolate, const size_t count)
36- : isolate_(isolate), count_(count), byte_offset_(0 ) {
38+ AliasedBufferBase (v8::Isolate* isolate,
39+ const size_t count,
40+ const AliasedBufferInfo* info = nullptr )
41+ : isolate_(isolate), count_(count), byte_offset_(0 ), info_(info) {
3742 CHECK_GT (count, 0 );
43+ if (info != nullptr ) {
44+ // Will be deserialized later.
45+ return ;
46+ }
3847 const v8::HandleScope handle_scope (isolate_);
3948 const size_t size_in_bytes =
4049 MultiplyWithOverflowCheck (sizeof (NativeT), count);
@@ -62,10 +71,17 @@ class AliasedBufferBase {
6271 v8::Isolate* isolate,
6372 const size_t byte_offset,
6473 const size_t count,
65- const AliasedBufferBase<uint8_t , v8::Uint8Array>& backing_buffer)
66- : isolate_(isolate), count_(count), byte_offset_(byte_offset) {
74+ const AliasedBufferBase<uint8_t , v8::Uint8Array>& backing_buffer,
75+ const AliasedBufferInfo* info = nullptr )
76+ : isolate_(isolate),
77+ count_ (count),
78+ byte_offset_(byte_offset),
79+ info_(info) {
80+ if (info != nullptr ) {
81+ // Will be deserialized later.
82+ return ;
83+ }
6784 const v8::HandleScope handle_scope (isolate_);
68-
6985 v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer ();
7086
7187 // validate that the byte_offset is aligned with sizeof(NativeT)
@@ -86,10 +102,33 @@ class AliasedBufferBase {
86102 count_(that.count_),
87103 byte_offset_(that.byte_offset_),
88104 buffer_(that.buffer_) {
105+ DCHECK_NULL (info_);
89106 js_array_ = v8::Global<V8T>(that.isolate_ , that.GetJSArray ());
90107 }
91108
109+ AliasedBufferInfo Serialize (v8::Local<v8::Context> context,
110+ v8::SnapshotCreator* creator) {
111+ DCHECK_NULL (info_);
112+ return creator->AddData (context, GetJSArray ());
113+ }
114+
115+ inline void Deserialize (v8::Local<v8::Context> context) {
116+ DCHECK_NOT_NULL (info_);
117+ v8::Local<V8T> arr =
118+ context->GetDataFromSnapshotOnce <V8T>(*info_).ToLocalChecked ();
119+ // These may not hold true for AliasedBuffers that have grown, so should
120+ // be removed when we expand the snapshot support.
121+ DCHECK_EQ (count_, arr->Length ());
122+ DCHECK_EQ (byte_offset_, arr->ByteOffset ());
123+ uint8_t * raw =
124+ static_cast <uint8_t *>(arr->Buffer ()->GetBackingStore ()->Data ());
125+ buffer_ = reinterpret_cast <NativeT*>(raw + byte_offset_);
126+ js_array_.Reset (isolate_, arr);
127+ info_ = nullptr ;
128+ }
129+
92130 AliasedBufferBase& operator =(AliasedBufferBase&& that) noexcept {
131+ DCHECK_NULL (info_);
93132 this ->~AliasedBufferBase ();
94133 isolate_ = that.isolate_ ;
95134 count_ = that.count_ ;
@@ -155,6 +194,7 @@ class AliasedBufferBase {
155194 * Get the underlying v8 TypedArray overlayed on top of the native buffer
156195 */
157196 v8::Local<V8T> GetJSArray () const {
197+ DCHECK_NULL (info_);
158198 return js_array_.Get (isolate_);
159199 }
160200
@@ -171,6 +211,7 @@ class AliasedBufferBase {
171211 * through the GetValue/SetValue/operator[] methods
172212 */
173213 inline const NativeT* GetNativeBuffer () const {
214+ DCHECK_NULL (info_);
174215 return buffer_;
175216 }
176217
@@ -186,13 +227,15 @@ class AliasedBufferBase {
186227 */
187228 inline void SetValue (const size_t index, NativeT value) {
188229 DCHECK_LT (index, count_);
230+ DCHECK_NULL (info_);
189231 buffer_[index] = value;
190232 }
191233
192234 /* *
193235 * Get value at position index
194236 */
195237 inline const NativeT GetValue (const size_t index) const {
238+ DCHECK_NULL (info_);
196239 DCHECK_LT (index, count_);
197240 return buffer_[index];
198241 }
@@ -201,6 +244,7 @@ class AliasedBufferBase {
201244 * Effectively, a synonym for GetValue/SetValue
202245 */
203246 Reference operator [](size_t index) {
247+ DCHECK_NULL (info_);
204248 return Reference (this , index);
205249 }
206250
@@ -216,6 +260,7 @@ class AliasedBufferBase {
216260 // Should only be used on an owning array, not one created as a sub array of
217261 // an owning `AliasedBufferBase`.
218262 void reserve (size_t new_capacity) {
263+ DCHECK_NULL (info_);
219264 DCHECK_GE (new_capacity, count_);
220265 DCHECK_EQ (byte_offset_, 0 );
221266 const v8::HandleScope handle_scope (isolate_);
@@ -244,11 +289,14 @@ class AliasedBufferBase {
244289 }
245290
246291 private:
247- v8::Isolate* isolate_;
248- size_t count_;
249- size_t byte_offset_;
250- NativeT* buffer_;
292+ v8::Isolate* isolate_ = nullptr ;
293+ size_t count_ = 0 ;
294+ size_t byte_offset_ = 0 ;
295+ NativeT* buffer_ = nullptr ;
251296 v8::Global<V8T> js_array_;
297+
298+ // Deserialize data
299+ const AliasedBufferInfo* info_ = nullptr ;
252300};
253301
254302typedef AliasedBufferBase<int32_t , v8::Int32Array> AliasedInt32Array;
0 commit comments