Skip to content

Commit 946f19b

Browse files
joyeecheungtargos
authored andcommitted
src: move AliasedBuffer implementation to -inl.h
Drive-by: Replace the SFINAE with a static_assert because we don't have (or need) an implementation for non-scalar AliasedBufferBase otherwise. Add forward declarations to memory_tracker.h now that aliased-buffer.h no longer includes util-inl.h. PR-URL: #46817 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 04dad9c commit 946f19b

11 files changed

+268
-168
lines changed

node.gyp

+1
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,7 @@
579579
'src/uv.cc',
580580
# headers to make for a more pleasant IDE experience
581581
'src/aliased_buffer.h',
582+
'src/aliased_buffer-inl.h',
582583
'src/aliased_struct.h',
583584
'src/aliased_struct-inl.h',
584585
'src/async_wrap.h',

src/aliased_buffer-inl.h

+213
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
#ifndef SRC_ALIASED_BUFFER_INL_H_
2+
#define SRC_ALIASED_BUFFER_INL_H_
3+
4+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5+
6+
#include "aliased_buffer.h"
7+
#include "util-inl.h"
8+
9+
namespace node {
10+
11+
typedef size_t AliasedBufferIndex;
12+
13+
template <typename NativeT, typename V8T>
14+
AliasedBufferBase<NativeT, V8T>::AliasedBufferBase(
15+
v8::Isolate* isolate, const size_t count, const AliasedBufferIndex* index)
16+
: isolate_(isolate), count_(count), byte_offset_(0), index_(index) {
17+
CHECK_GT(count, 0);
18+
if (index != nullptr) {
19+
// Will be deserialized later.
20+
return;
21+
}
22+
const v8::HandleScope handle_scope(isolate_);
23+
const size_t size_in_bytes =
24+
MultiplyWithOverflowCheck(sizeof(NativeT), count);
25+
26+
// allocate v8 ArrayBuffer
27+
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(isolate_, size_in_bytes);
28+
buffer_ = static_cast<NativeT*>(ab->Data());
29+
30+
// allocate v8 TypedArray
31+
v8::Local<V8T> js_array = V8T::New(ab, byte_offset_, count);
32+
js_array_ = v8::Global<V8T>(isolate, js_array);
33+
}
34+
35+
template <typename NativeT, typename V8T>
36+
AliasedBufferBase<NativeT, V8T>::AliasedBufferBase(
37+
v8::Isolate* isolate,
38+
const size_t byte_offset,
39+
const size_t count,
40+
const AliasedBufferBase<uint8_t, v8::Uint8Array>& backing_buffer,
41+
const AliasedBufferIndex* index)
42+
: isolate_(isolate),
43+
count_(count),
44+
byte_offset_(byte_offset),
45+
index_(index) {
46+
if (index != nullptr) {
47+
// Will be deserialized later.
48+
return;
49+
}
50+
const v8::HandleScope handle_scope(isolate_);
51+
v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer();
52+
53+
// validate that the byte_offset is aligned with sizeof(NativeT)
54+
CHECK_EQ(byte_offset & (sizeof(NativeT) - 1), 0);
55+
// validate this fits inside the backing buffer
56+
CHECK_LE(MultiplyWithOverflowCheck(sizeof(NativeT), count),
57+
ab->ByteLength() - byte_offset);
58+
59+
buffer_ = reinterpret_cast<NativeT*>(
60+
const_cast<uint8_t*>(backing_buffer.GetNativeBuffer() + byte_offset));
61+
62+
v8::Local<V8T> js_array = V8T::New(ab, byte_offset, count);
63+
js_array_ = v8::Global<V8T>(isolate, js_array);
64+
}
65+
66+
template <typename NativeT, typename V8T>
67+
AliasedBufferBase<NativeT, V8T>::AliasedBufferBase(
68+
const AliasedBufferBase& that)
69+
: isolate_(that.isolate_),
70+
count_(that.count_),
71+
byte_offset_(that.byte_offset_),
72+
buffer_(that.buffer_) {
73+
DCHECK_NULL(index_);
74+
js_array_ = v8::Global<V8T>(that.isolate_, that.GetJSArray());
75+
}
76+
77+
template <typename NativeT, typename V8T>
78+
AliasedBufferIndex AliasedBufferBase<NativeT, V8T>::Serialize(
79+
v8::Local<v8::Context> context, v8::SnapshotCreator* creator) {
80+
DCHECK_NULL(index_);
81+
return creator->AddData(context, GetJSArray());
82+
}
83+
84+
template <typename NativeT, typename V8T>
85+
inline void AliasedBufferBase<NativeT, V8T>::Deserialize(
86+
v8::Local<v8::Context> context) {
87+
DCHECK_NOT_NULL(index_);
88+
v8::Local<V8T> arr =
89+
context->GetDataFromSnapshotOnce<V8T>(*index_).ToLocalChecked();
90+
// These may not hold true for AliasedBuffers that have grown, so should
91+
// be removed when we expand the snapshot support.
92+
DCHECK_EQ(count_, arr->Length());
93+
DCHECK_EQ(byte_offset_, arr->ByteOffset());
94+
uint8_t* raw = static_cast<uint8_t*>(arr->Buffer()->Data());
95+
buffer_ = reinterpret_cast<NativeT*>(raw + byte_offset_);
96+
js_array_.Reset(isolate_, arr);
97+
index_ = nullptr;
98+
}
99+
100+
template <typename NativeT, typename V8T>
101+
AliasedBufferBase<NativeT, V8T>& AliasedBufferBase<NativeT, V8T>::operator=(
102+
AliasedBufferBase<NativeT, V8T>&& that) noexcept {
103+
DCHECK_NULL(index_);
104+
this->~AliasedBufferBase();
105+
isolate_ = that.isolate_;
106+
count_ = that.count_;
107+
byte_offset_ = that.byte_offset_;
108+
buffer_ = that.buffer_;
109+
110+
js_array_.Reset(isolate_, that.js_array_.Get(isolate_));
111+
112+
that.buffer_ = nullptr;
113+
that.js_array_.Reset();
114+
return *this;
115+
}
116+
117+
template <typename NativeT, typename V8T>
118+
v8::Local<V8T> AliasedBufferBase<NativeT, V8T>::GetJSArray() const {
119+
DCHECK_NULL(index_);
120+
return js_array_.Get(isolate_);
121+
}
122+
123+
template <typename NativeT, typename V8T>
124+
void AliasedBufferBase<NativeT, V8T>::Release() {
125+
DCHECK_NULL(index_);
126+
js_array_.Reset();
127+
}
128+
129+
template <typename NativeT, typename V8T>
130+
v8::Local<v8::ArrayBuffer> AliasedBufferBase<NativeT, V8T>::GetArrayBuffer()
131+
const {
132+
return GetJSArray()->Buffer();
133+
}
134+
135+
template <typename NativeT, typename V8T>
136+
inline const NativeT* AliasedBufferBase<NativeT, V8T>::GetNativeBuffer() const {
137+
DCHECK_NULL(index_);
138+
return buffer_;
139+
}
140+
141+
template <typename NativeT, typename V8T>
142+
inline const NativeT* AliasedBufferBase<NativeT, V8T>::operator*() const {
143+
return GetNativeBuffer();
144+
}
145+
146+
template <typename NativeT, typename V8T>
147+
inline void AliasedBufferBase<NativeT, V8T>::SetValue(const size_t index,
148+
NativeT value) {
149+
DCHECK_LT(index, count_);
150+
DCHECK_NULL(index_);
151+
buffer_[index] = value;
152+
}
153+
154+
template <typename NativeT, typename V8T>
155+
inline const NativeT AliasedBufferBase<NativeT, V8T>::GetValue(
156+
const size_t index) const {
157+
DCHECK_NULL(index_);
158+
DCHECK_LT(index, count_);
159+
return buffer_[index];
160+
}
161+
162+
template <typename NativeT, typename V8T>
163+
typename AliasedBufferBase<NativeT, V8T>::Reference
164+
AliasedBufferBase<NativeT, V8T>::operator[](size_t index) {
165+
DCHECK_NULL(index_);
166+
return Reference(this, index);
167+
}
168+
169+
template <typename NativeT, typename V8T>
170+
NativeT AliasedBufferBase<NativeT, V8T>::operator[](size_t index) const {
171+
return GetValue(index);
172+
}
173+
174+
template <typename NativeT, typename V8T>
175+
size_t AliasedBufferBase<NativeT, V8T>::Length() const {
176+
return count_;
177+
}
178+
179+
template <typename NativeT, typename V8T>
180+
void AliasedBufferBase<NativeT, V8T>::reserve(size_t new_capacity) {
181+
DCHECK_NULL(index_);
182+
DCHECK_GE(new_capacity, count_);
183+
DCHECK_EQ(byte_offset_, 0);
184+
const v8::HandleScope handle_scope(isolate_);
185+
186+
const size_t old_size_in_bytes = sizeof(NativeT) * count_;
187+
const size_t new_size_in_bytes =
188+
MultiplyWithOverflowCheck(sizeof(NativeT), new_capacity);
189+
190+
// allocate v8 new ArrayBuffer
191+
v8::Local<v8::ArrayBuffer> ab =
192+
v8::ArrayBuffer::New(isolate_, new_size_in_bytes);
193+
194+
// allocate new native buffer
195+
NativeT* new_buffer = static_cast<NativeT*>(ab->Data());
196+
// copy old content
197+
memcpy(new_buffer, buffer_, old_size_in_bytes);
198+
199+
// allocate v8 TypedArray
200+
v8::Local<V8T> js_array = V8T::New(ab, byte_offset_, new_capacity);
201+
202+
// move over old v8 TypedArray
203+
js_array_ = std::move(v8::Global<V8T>(isolate_, js_array));
204+
205+
buffer_ = new_buffer;
206+
count_ = new_capacity;
207+
}
208+
209+
} // namespace node
210+
211+
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
212+
213+
#endif // SRC_ALIASED_BUFFER_INL_H_

0 commit comments

Comments
 (0)