Skip to content

Commit 33e7f6e

Browse files
refackrvagg
authored andcommitted
src: add AliasedBuffer::reserve
refactor grow_async_ids_stack PR-URL: #23808 Reviewed-By: Joyee Cheung <[email protected]> Reviewed-By: Matheus Marchini <[email protected]>
1 parent 74c0a97 commit 33e7f6e

File tree

2 files changed

+44
-13
lines changed

2 files changed

+44
-13
lines changed

src/aliased_buffer.h

+43-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
55

66
#include "v8.h"
7-
#include "util-inl.h"
7+
#include "util.h"
88

99
namespace node {
1010

@@ -22,7 +22,9 @@ namespace node {
2222
* The encapsulation herein provides a placeholder where such writes can be
2323
* observed. Any notification APIs will be left as a future exercise.
2424
*/
25-
template <class NativeT, class V8T>
25+
template <class NativeT, class V8T,
26+
// SFINAE NativeT to be scalar
27+
typename = std::enable_if_t<std::is_scalar<NativeT>::value>>
2628
class AliasedBuffer {
2729
public:
2830
AliasedBuffer(v8::Isolate* isolate, const size_t count)
@@ -33,14 +35,14 @@ class AliasedBuffer {
3335
CHECK_GT(count, 0);
3436
const v8::HandleScope handle_scope(isolate_);
3537

36-
const size_t sizeInBytes = sizeof(NativeT) * count;
38+
const size_t size_in_bytes = sizeof(NativeT) * count;
3739

3840
// allocate native buffer
3941
buffer_ = Calloc<NativeT>(count);
4042

4143
// allocate v8 ArrayBuffer
4244
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(
43-
isolate_, buffer_, sizeInBytes);
45+
isolate_, buffer_, size_in_bytes);
4446

4547
// allocate v8 TypedArray
4648
v8::Local<V8T> js_array = V8T::New(ab, byte_offset_, count);
@@ -55,6 +57,7 @@ class AliasedBuffer {
5557
*
5658
* Note that byte_offset must by aligned by sizeof(NativeT).
5759
*/
60+
// TODO(refack): refactor into a non-owning `AliasedBufferView`
5861
AliasedBuffer(v8::Isolate* isolate,
5962
const size_t byte_offset,
6063
const size_t count,
@@ -96,7 +99,7 @@ class AliasedBuffer {
9699
js_array_.Reset();
97100
}
98101

99-
AliasedBuffer& operator=(AliasedBuffer&& that) {
102+
AliasedBuffer& operator=(AliasedBuffer&& that) noexcept {
100103
this->~AliasedBuffer();
101104
isolate_ = that.isolate_;
102105
count_ = that.count_;
@@ -226,6 +229,41 @@ class AliasedBuffer {
226229
return count_;
227230
}
228231

232+
// Should only be used to extend the array.
233+
// Should only be used on an owning array, not one created as a sub array of
234+
// an owning `AliasedBuffer`.
235+
void reserve(size_t new_capacity) {
236+
#if defined(DEBUG) && DEBUG
237+
CHECK_GE(new_capacity, count_);
238+
CHECK_EQ(byte_offset_, 0);
239+
CHECK(free_buffer_);
240+
#endif
241+
const v8::HandleScope handle_scope(isolate_);
242+
243+
const size_t old_size_in_bytes = sizeof(NativeT) * count_;
244+
const size_t new_size_in_bytes = sizeof(NativeT) * new_capacity;
245+
246+
// allocate new native buffer
247+
NativeT* new_buffer = Calloc<NativeT>(new_capacity);
248+
// copy old content
249+
memcpy(new_buffer, buffer_, old_size_in_bytes);
250+
251+
// allocate v8 new ArrayBuffer
252+
v8::Local<v8::ArrayBuffer> ab = v8::ArrayBuffer::New(
253+
isolate_, new_buffer, new_size_in_bytes);
254+
255+
// allocate v8 TypedArray
256+
v8::Local<V8T> js_array = V8T::New(ab, byte_offset_, new_capacity);
257+
258+
// move over old v8 TypedArray
259+
js_array_ = std::move(v8::Global<V8T>(isolate_, js_array));
260+
261+
// Free old buffer and set new values
262+
free(buffer_);
263+
buffer_ = new_buffer;
264+
count_ = new_capacity;
265+
}
266+
229267
private:
230268
v8::Isolate* isolate_;
231269
size_t count_;

src/env.cc

+1-8
Original file line numberDiff line numberDiff line change
@@ -828,14 +828,7 @@ void Environment::CollectUVExceptionInfo(v8::Local<v8::Value> object,
828828

829829

830830
void Environment::AsyncHooks::grow_async_ids_stack() {
831-
const uint32_t old_capacity = async_ids_stack_.Length() / 2;
832-
const uint32_t new_capacity = old_capacity * 1.5;
833-
AliasedBuffer<double, v8::Float64Array> new_buffer(
834-
env()->isolate(), new_capacity * 2);
835-
836-
for (uint32_t i = 0; i < old_capacity * 2; ++i)
837-
new_buffer[i] = async_ids_stack_[i];
838-
async_ids_stack_ = std::move(new_buffer);
831+
async_ids_stack_.reserve(async_ids_stack_.Length() * 3);
839832

840833
env()->async_hooks_binding()->Set(
841834
env()->context(),

0 commit comments

Comments
 (0)