4
4
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
5
6
6
#include < cinttypes>
7
+ #include < iostream>
7
8
#include " util-inl.h"
8
9
#include " v8.h"
9
10
10
11
namespace node {
11
12
13
+ typedef size_t AliasedBufferInfo;
14
+
12
15
/* *
13
16
* Do not use this class directly when creating instances of it - use the
14
17
* Aliased*Array defined at the end of this file instead.
@@ -32,9 +35,15 @@ template <class NativeT,
32
35
typename = std::enable_if_t <std::is_scalar<NativeT>::value>>
33
36
class AliasedBufferBase {
34
37
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) {
37
42
CHECK_GT (count, 0 );
43
+ if (info != nullptr ) {
44
+ // Will be deserialized later.
45
+ return ;
46
+ }
38
47
const v8::HandleScope handle_scope (isolate_);
39
48
const size_t size_in_bytes =
40
49
MultiplyWithOverflowCheck (sizeof (NativeT), count);
@@ -62,10 +71,17 @@ class AliasedBufferBase {
62
71
v8::Isolate* isolate,
63
72
const size_t byte_offset,
64
73
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
+ }
67
84
const v8::HandleScope handle_scope (isolate_);
68
-
69
85
v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer ();
70
86
71
87
// validate that the byte_offset is aligned with sizeof(NativeT)
@@ -86,10 +102,33 @@ class AliasedBufferBase {
86
102
count_(that.count_),
87
103
byte_offset_(that.byte_offset_),
88
104
buffer_(that.buffer_) {
105
+ DCHECK_NULL (info_);
89
106
js_array_ = v8::Global<V8T>(that.isolate_ , that.GetJSArray ());
90
107
}
91
108
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
+
92
130
AliasedBufferBase& operator =(AliasedBufferBase&& that) noexcept {
131
+ DCHECK_NULL (info_);
93
132
this ->~AliasedBufferBase ();
94
133
isolate_ = that.isolate_ ;
95
134
count_ = that.count_ ;
@@ -155,6 +194,7 @@ class AliasedBufferBase {
155
194
* Get the underlying v8 TypedArray overlayed on top of the native buffer
156
195
*/
157
196
v8::Local<V8T> GetJSArray () const {
197
+ DCHECK_NULL (info_);
158
198
return js_array_.Get (isolate_);
159
199
}
160
200
@@ -171,6 +211,7 @@ class AliasedBufferBase {
171
211
* through the GetValue/SetValue/operator[] methods
172
212
*/
173
213
inline const NativeT* GetNativeBuffer () const {
214
+ DCHECK_NULL (info_);
174
215
return buffer_;
175
216
}
176
217
@@ -186,13 +227,15 @@ class AliasedBufferBase {
186
227
*/
187
228
inline void SetValue (const size_t index, NativeT value) {
188
229
DCHECK_LT (index , count_);
230
+ DCHECK_NULL (info_);
189
231
buffer_[index ] = value;
190
232
}
191
233
192
234
/* *
193
235
* Get value at position index
194
236
*/
195
237
inline const NativeT GetValue (const size_t index) const {
238
+ DCHECK_NULL (info_);
196
239
DCHECK_LT (index , count_);
197
240
return buffer_[index ];
198
241
}
@@ -201,6 +244,7 @@ class AliasedBufferBase {
201
244
* Effectively, a synonym for GetValue/SetValue
202
245
*/
203
246
Reference operator [](size_t index) {
247
+ DCHECK_NULL (info_);
204
248
return Reference (this , index );
205
249
}
206
250
@@ -216,6 +260,7 @@ class AliasedBufferBase {
216
260
// Should only be used on an owning array, not one created as a sub array of
217
261
// an owning `AliasedBufferBase`.
218
262
void reserve (size_t new_capacity) {
263
+ DCHECK_NULL (info_);
219
264
DCHECK_GE (new_capacity, count_);
220
265
DCHECK_EQ (byte_offset_, 0 );
221
266
const v8::HandleScope handle_scope (isolate_);
@@ -244,11 +289,14 @@ class AliasedBufferBase {
244
289
}
245
290
246
291
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 ;
251
296
v8::Global<V8T> js_array_;
297
+
298
+ // Deserialize data
299
+ const AliasedBufferInfo* info_ = nullptr ;
252
300
};
253
301
254
302
typedef AliasedBufferBase<int32_t , v8::Int32Array> AliasedInt32Array;
0 commit comments