Skip to content

Commit 81e7b49

Browse files
joyeecheungtargos
authored andcommitted
src: use predefined AliasedBuffer types in the code base
Instead of allowing the callers to instantiate the template with any numeric types (such as aliasing a Uint8Array to double[]), predefine types that make sense and use those instead. PR-URL: #27334 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 8089d29 commit 81e7b49

12 files changed

+105
-123
lines changed

src/aliased_buffer.h

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@
33

44
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55

6-
#include "v8.h"
6+
#include <cinttypes>
77
#include "util-inl.h"
8+
#include "v8.h"
89

910
namespace node {
1011

1112
/**
13+
* Do not use this class directly when creating instances of it - use the
14+
* Aliased*Array defined at the end of this file instead.
15+
*
1216
* This class encapsulates the technique of having a native buffer mapped to
1317
* a JS object. Writes to the native buffer can happen efficiently without
1418
* going through JS, and the data is then available to user's via the exposed
@@ -22,18 +26,16 @@ namespace node {
2226
* The encapsulation herein provides a placeholder where such writes can be
2327
* observed. Any notification APIs will be left as a future exercise.
2428
*/
25-
template <class NativeT, class V8T,
29+
template <class NativeT,
30+
class V8T,
2631
// SFINAE NativeT to be scalar
2732
typename = std::enable_if_t<std::is_scalar<NativeT>::value>>
28-
class AliasedBuffer {
33+
class AliasedBufferBase {
2934
public:
30-
AliasedBuffer(v8::Isolate* isolate, const size_t count)
31-
: isolate_(isolate),
32-
count_(count),
33-
byte_offset_(0) {
35+
AliasedBufferBase(v8::Isolate* isolate, const size_t count)
36+
: isolate_(isolate), count_(count), byte_offset_(0) {
3437
CHECK_GT(count, 0);
3538
const v8::HandleScope handle_scope(isolate_);
36-
3739
const size_t size_in_bytes =
3840
MultiplyWithOverflowCheck(sizeof(NativeT), count);
3941

@@ -48,22 +50,20 @@ class AliasedBuffer {
4850
}
4951

5052
/**
51-
* Create an AliasedBuffer over a sub-region of another aliased buffer.
53+
* Create an AliasedBufferBase over a sub-region of another aliased buffer.
5254
* The two will share a v8::ArrayBuffer instance &
5355
* a native buffer, but will each read/write to different sections of the
5456
* native buffer.
5557
*
5658
* Note that byte_offset must by aligned by sizeof(NativeT).
5759
*/
58-
// TODO(refack): refactor into a non-owning `AliasedBufferView`
59-
AliasedBuffer(v8::Isolate* isolate,
60-
const size_t byte_offset,
61-
const size_t count,
62-
const AliasedBuffer<uint8_t,
63-
v8::Uint8Array>& backing_buffer)
64-
: isolate_(isolate),
65-
count_(count),
66-
byte_offset_(byte_offset) {
60+
// TODO(refack): refactor into a non-owning `AliasedBufferBaseView`
61+
AliasedBufferBase(
62+
v8::Isolate* isolate,
63+
const size_t byte_offset,
64+
const size_t count,
65+
const AliasedBufferBase<uint8_t, v8::Uint8Array>& backing_buffer)
66+
: isolate_(isolate), count_(count), byte_offset_(byte_offset) {
6767
const v8::HandleScope handle_scope(isolate_);
6868

6969
v8::Local<v8::ArrayBuffer> ab = backing_buffer.GetArrayBuffer();
@@ -81,16 +81,16 @@ class AliasedBuffer {
8181
js_array_ = v8::Global<V8T>(isolate, js_array);
8282
}
8383

84-
AliasedBuffer(const AliasedBuffer& that)
84+
AliasedBufferBase(const AliasedBufferBase& that)
8585
: isolate_(that.isolate_),
8686
count_(that.count_),
8787
byte_offset_(that.byte_offset_),
8888
buffer_(that.buffer_) {
8989
js_array_ = v8::Global<V8T>(that.isolate_, that.GetJSArray());
9090
}
9191

92-
AliasedBuffer& operator=(AliasedBuffer&& that) noexcept {
93-
this->~AliasedBuffer();
92+
AliasedBufferBase& operator=(AliasedBufferBase&& that) noexcept {
93+
this->~AliasedBufferBase();
9494
isolate_ = that.isolate_;
9595
count_ = that.count_;
9696
byte_offset_ = that.byte_offset_;
@@ -109,10 +109,8 @@ class AliasedBuffer {
109109
*/
110110
class Reference {
111111
public:
112-
Reference(AliasedBuffer<NativeT, V8T>* aliased_buffer, size_t index)
113-
: aliased_buffer_(aliased_buffer),
114-
index_(index) {
115-
}
112+
Reference(AliasedBufferBase<NativeT, V8T>* aliased_buffer, size_t index)
113+
: aliased_buffer_(aliased_buffer), index_(index) {}
116114

117115
Reference(const Reference& that)
118116
: aliased_buffer_(that.aliased_buffer_),
@@ -149,7 +147,7 @@ class AliasedBuffer {
149147
}
150148

151149
private:
152-
AliasedBuffer<NativeT, V8T>* aliased_buffer_;
150+
AliasedBufferBase<NativeT, V8T>* aliased_buffer_;
153151
size_t index_;
154152
};
155153

@@ -216,7 +214,7 @@ class AliasedBuffer {
216214

217215
// Should only be used to extend the array.
218216
// Should only be used on an owning array, not one created as a sub array of
219-
// an owning `AliasedBuffer`.
217+
// an owning `AliasedBufferBase`.
220218
void reserve(size_t new_capacity) {
221219
DCHECK_GE(new_capacity, count_);
222220
DCHECK_EQ(byte_offset_, 0);
@@ -251,6 +249,12 @@ class AliasedBuffer {
251249
NativeT* buffer_;
252250
v8::Global<V8T> js_array_;
253251
};
252+
253+
typedef AliasedBufferBase<int32_t, v8::Int32Array> AliasedInt32Array;
254+
typedef AliasedBufferBase<uint8_t, v8::Uint8Array> AliasedUint8Array;
255+
typedef AliasedBufferBase<uint32_t, v8::Uint32Array> AliasedUint32Array;
256+
typedef AliasedBufferBase<double, v8::Float64Array> AliasedFloat64Array;
257+
typedef AliasedBufferBase<uint64_t, v8::BigUint64Array> AliasedBigUint64Array;
254258
} // namespace node
255259

256260
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

src/env-inl.h

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -109,16 +109,15 @@ inline AsyncHooks::AsyncHooks()
109109
NODE_ASYNC_PROVIDER_TYPES(V)
110110
#undef V
111111
}
112-
113-
inline AliasedBuffer<uint32_t, v8::Uint32Array>& AsyncHooks::fields() {
112+
inline AliasedUint32Array& AsyncHooks::fields() {
114113
return fields_;
115114
}
116115

117-
inline AliasedBuffer<double, v8::Float64Array>& AsyncHooks::async_id_fields() {
116+
inline AliasedFloat64Array& AsyncHooks::async_id_fields() {
118117
return async_id_fields_;
119118
}
120119

121-
inline AliasedBuffer<double, v8::Float64Array>& AsyncHooks::async_ids_stack() {
120+
inline AliasedFloat64Array& AsyncHooks::async_ids_stack() {
122121
return async_ids_stack_;
123122
}
124123

@@ -243,8 +242,7 @@ inline void Environment::PopAsyncCallbackScope() {
243242
inline ImmediateInfo::ImmediateInfo(v8::Isolate* isolate)
244243
: fields_(isolate, kFieldsCount) {}
245244

246-
inline AliasedBuffer<uint32_t, v8::Uint32Array>&
247-
ImmediateInfo::fields() {
245+
inline AliasedUint32Array& ImmediateInfo::fields() {
248246
return fields_;
249247
}
250248

@@ -279,7 +277,7 @@ inline void ImmediateInfo::ref_count_dec(uint32_t decrement) {
279277
inline TickInfo::TickInfo(v8::Isolate* isolate)
280278
: fields_(isolate, kFieldsCount) {}
281279

282-
inline AliasedBuffer<uint8_t, v8::Uint8Array>& TickInfo::fields() {
280+
inline AliasedUint8Array& TickInfo::fields() {
283281
return fields_;
284282
}
285283

@@ -486,13 +484,11 @@ inline void Environment::set_abort_on_uncaught_exception(bool value) {
486484
options_->abort_on_uncaught_exception = value;
487485
}
488486

489-
inline AliasedBuffer<uint32_t, v8::Uint32Array>&
490-
Environment::should_abort_on_uncaught_toggle() {
487+
inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() {
491488
return should_abort_on_uncaught_toggle_;
492489
}
493490

494-
inline AliasedBuffer<int32_t, v8::Int32Array>&
495-
Environment::stream_base_state() {
491+
inline AliasedInt32Array& Environment::stream_base_state() {
496492
return stream_base_state_;
497493
}
498494

@@ -622,13 +618,11 @@ void Environment::set_debug_enabled(DebugCategory category, bool enabled) {
622618
debug_enabled_[static_cast<int>(category)] = enabled;
623619
}
624620

625-
inline AliasedBuffer<double, v8::Float64Array>*
626-
Environment::fs_stats_field_array() {
621+
inline AliasedFloat64Array* Environment::fs_stats_field_array() {
627622
return &fs_stats_field_array_;
628623
}
629624

630-
inline AliasedBuffer<uint64_t, v8::BigUint64Array>*
631-
Environment::fs_stats_field_bigint_array() {
625+
inline AliasedBigUint64Array* Environment::fs_stats_field_bigint_array() {
632626
return &fs_stats_field_bigint_array_;
633627
}
634628

src/env.h

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -611,9 +611,9 @@ class AsyncHooks : public MemoryRetainer {
611611
kUidFieldsCount,
612612
};
613613

614-
inline AliasedBuffer<uint32_t, v8::Uint32Array>& fields();
615-
inline AliasedBuffer<double, v8::Float64Array>& async_id_fields();
616-
inline AliasedBuffer<double, v8::Float64Array>& async_ids_stack();
614+
inline AliasedUint32Array& fields();
615+
inline AliasedFloat64Array& async_id_fields();
616+
inline AliasedFloat64Array& async_ids_stack();
617617

618618
inline v8::Local<v8::String> provider_string(int idx);
619619

@@ -652,12 +652,12 @@ class AsyncHooks : public MemoryRetainer {
652652
// Keep a list of all Persistent strings used for Provider types.
653653
std::array<v8::Eternal<v8::String>, AsyncWrap::PROVIDERS_LENGTH> providers_;
654654
// Stores the ids of the current execution context stack.
655-
AliasedBuffer<double, v8::Float64Array> async_ids_stack_;
655+
AliasedFloat64Array async_ids_stack_;
656656
// Attached to a Uint32Array that tracks the number of active hooks for
657657
// each type.
658-
AliasedBuffer<uint32_t, v8::Uint32Array> fields_;
658+
AliasedUint32Array fields_;
659659
// Attached to a Float64Array that tracks the state of async resources.
660-
AliasedBuffer<double, v8::Float64Array> async_id_fields_;
660+
AliasedFloat64Array async_id_fields_;
661661

662662
void grow_async_ids_stack();
663663
};
@@ -676,7 +676,7 @@ class AsyncCallbackScope {
676676

677677
class ImmediateInfo : public MemoryRetainer {
678678
public:
679-
inline AliasedBuffer<uint32_t, v8::Uint32Array>& fields();
679+
inline AliasedUint32Array& fields();
680680
inline uint32_t count() const;
681681
inline uint32_t ref_count() const;
682682
inline bool has_outstanding() const;
@@ -698,12 +698,12 @@ class ImmediateInfo : public MemoryRetainer {
698698

699699
enum Fields { kCount, kRefCount, kHasOutstanding, kFieldsCount };
700700

701-
AliasedBuffer<uint32_t, v8::Uint32Array> fields_;
701+
AliasedUint32Array fields_;
702702
};
703703

704704
class TickInfo : public MemoryRetainer {
705705
public:
706-
inline AliasedBuffer<uint8_t, v8::Uint8Array>& fields();
706+
inline AliasedUint8Array& fields();
707707
inline bool has_tick_scheduled() const;
708708
inline bool has_rejection_to_warn() const;
709709

@@ -720,7 +720,7 @@ class TickInfo : public MemoryRetainer {
720720

721721
enum Fields { kHasTickScheduled = 0, kHasRejectionToWarn, kFieldsCount };
722722

723-
AliasedBuffer<uint8_t, v8::Uint8Array> fields_;
723+
AliasedUint8Array fields_;
724724
};
725725

726726
class TrackingTraceStateObserver :
@@ -908,10 +908,9 @@ class Environment : public MemoryRetainer {
908908
// This is a pseudo-boolean that keeps track of whether an uncaught exception
909909
// should abort the process or not if --abort-on-uncaught-exception was
910910
// passed to Node. If the flag was not passed, it is ignored.
911-
inline AliasedBuffer<uint32_t, v8::Uint32Array>&
912-
should_abort_on_uncaught_toggle();
911+
inline AliasedUint32Array& should_abort_on_uncaught_toggle();
913912

914-
inline AliasedBuffer<int32_t, v8::Int32Array>& stream_base_state();
913+
inline AliasedInt32Array& stream_base_state();
915914

916915
// The necessary API for async_hooks.
917916
inline double new_async_id();
@@ -957,9 +956,8 @@ class Environment : public MemoryRetainer {
957956
inline void set_debug_enabled(DebugCategory category, bool enabled);
958957
void set_debug_categories(const std::string& cats, bool enabled);
959958

960-
inline AliasedBuffer<double, v8::Float64Array>* fs_stats_field_array();
961-
inline AliasedBuffer<uint64_t, v8::BigUint64Array>*
962-
fs_stats_field_bigint_array();
959+
inline AliasedFloat64Array* fs_stats_field_array();
960+
inline AliasedBigUint64Array* fs_stats_field_bigint_array();
963961

964962
inline std::vector<std::unique_ptr<fs::FileHandleReadWrap>>&
965963
file_handle_read_wrap_freelist();
@@ -1204,12 +1202,12 @@ class Environment : public MemoryRetainer {
12041202
uint32_t script_id_counter_ = 0;
12051203
uint32_t function_id_counter_ = 0;
12061204

1207-
AliasedBuffer<uint32_t, v8::Uint32Array> should_abort_on_uncaught_toggle_;
1205+
AliasedUint32Array should_abort_on_uncaught_toggle_;
12081206
int should_not_abort_scope_counter_ = 0;
12091207

12101208
std::unique_ptr<TrackingTraceStateObserver> trace_state_observer_;
12111209

1212-
AliasedBuffer<int32_t, v8::Int32Array> stream_base_state_;
1210+
AliasedInt32Array stream_base_state_;
12131211

12141212
std::unique_ptr<performance::performance_state> performance_state_;
12151213
std::unordered_map<std::string, uint64_t> performance_marks_;
@@ -1252,8 +1250,8 @@ class Environment : public MemoryRetainer {
12521250

12531251
bool debug_enabled_[static_cast<int>(DebugCategory::CATEGORY_COUNT)] = {0};
12541252

1255-
AliasedBuffer<double, v8::Float64Array> fs_stats_field_array_;
1256-
AliasedBuffer<uint64_t, v8::BigUint64Array> fs_stats_field_bigint_array_;
1253+
AliasedFloat64Array fs_stats_field_array_;
1254+
AliasedBigUint64Array fs_stats_field_bigint_array_;
12571255

12581256
std::vector<std::unique_ptr<fs::FileHandleReadWrap>>
12591257
file_handle_read_wrap_freelist_;

src/memory_tracker-inl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ void MemoryTracker::TrackField(const char* name,
226226

227227
template <class NativeT, class V8T>
228228
void MemoryTracker::TrackField(const char* name,
229-
const AliasedBuffer<NativeT, V8T>& value,
229+
const AliasedBufferBase<NativeT, V8T>& value,
230230
const char* node_name) {
231231
TrackField(name, value.GetJSArray(), "AliasedBuffer");
232232
}

src/memory_tracker.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ class MemoryTracker {
215215
const char* node_name = nullptr);
216216
template <class NativeT, class V8T>
217217
inline void TrackField(const char* edge_name,
218-
const AliasedBuffer<NativeT, V8T>& value,
218+
const AliasedBufferBase<NativeT, V8T>& value,
219219
const char* node_name = nullptr);
220220

221221
// Put a memory container into the graph, create an edge from

src/node_file.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -756,9 +756,9 @@ inline FSReqBase* GetReqWrap(Environment* env, Local<Value> value,
756756
return Unwrap<FSReqBase>(value.As<Object>());
757757
} else if (value->StrictEquals(env->fs_use_promises_symbol())) {
758758
if (use_bigint) {
759-
return FSReqPromise<uint64_t, BigUint64Array>::New(env, use_bigint);
759+
return FSReqPromise<AliasedBigUint64Array>::New(env, use_bigint);
760760
} else {
761-
return FSReqPromise<double, Float64Array>::New(env, use_bigint);
761+
return FSReqPromise<AliasedFloat64Array>::New(env, use_bigint);
762762
}
763763
}
764764
return nullptr;

src/node_file.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,9 @@ constexpr uint64_t ToNative(uv_timespec_t ts) {
192192
#undef constexpr // end N3652 bug workaround
193193

194194
template <typename NativeT, typename V8T>
195-
constexpr void FillStatsArray(AliasedBuffer<NativeT, V8T>* fields,
196-
const uv_stat_t* s, const size_t offset = 0) {
195+
constexpr void FillStatsArray(AliasedBufferBase<NativeT, V8T>* fields,
196+
const uv_stat_t* s,
197+
const size_t offset = 0) {
197198
fields->SetValue(offset + 0, static_cast<NativeT>(s->st_dev));
198199
fields->SetValue(offset + 1, static_cast<NativeT>(s->st_mode));
199200
fields->SetValue(offset + 2, static_cast<NativeT>(s->st_nlink));
@@ -227,7 +228,7 @@ inline Local<Value> FillGlobalStatsArray(Environment* env,
227228
}
228229
}
229230

230-
template <typename NativeT = double, typename V8T = v8::Float64Array>
231+
template <typename AliasedBufferT>
231232
class FSReqPromise : public FSReqBase {
232233
public:
233234
static FSReqPromise* New(Environment* env, bool use_bigint) {
@@ -304,7 +305,7 @@ class FSReqPromise : public FSReqBase {
304305
stats_field_array_(env->isolate(), kFsStatsFieldsNumber) {}
305306

306307
bool finished_ = false;
307-
AliasedBuffer<NativeT, V8T> stats_field_array_;
308+
AliasedBufferT stats_field_array_;
308309
};
309310

310311
class FSReqAfterScope {

0 commit comments

Comments
 (0)