Skip to content

Commit d06efaf

Browse files
addaleaxGabriel Schulhof
authored and
Gabriel Schulhof
committed
src: explicitly allocate backing stores for v8 stat buffers
This fixes flaky tests that crashed because the allocations ended up at positions of previously allocated `ArrayBuffer`s that were still in the backing store table. In particular, there was a race condition window between destroying a Worker thread’s `Environment` and destroying its `Isolate` in which the underlying memory was already released but the `ArrayBuffer` was still existent, meaning that new memory could be allocated at the address of the previous `ArrayBuffer`. Refs: #30782 PR-URL: #30946 Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
1 parent d502b83 commit d06efaf

File tree

4 files changed

+34
-62
lines changed

4 files changed

+34
-62
lines changed

src/env-inl.h

+17-14
Original file line numberDiff line numberDiff line change
@@ -543,32 +543,35 @@ inline double Environment::get_default_trigger_async_id() {
543543

544544
inline double* Environment::heap_statistics_buffer() const {
545545
CHECK_NOT_NULL(heap_statistics_buffer_);
546-
return heap_statistics_buffer_;
546+
return static_cast<double*>(heap_statistics_buffer_->Data());
547547
}
548548

549-
inline void Environment::set_heap_statistics_buffer(double* pointer) {
550-
CHECK_NULL(heap_statistics_buffer_); // Should be set only once.
551-
heap_statistics_buffer_ = pointer;
549+
inline void Environment::set_heap_statistics_buffer(
550+
std::shared_ptr<v8::BackingStore> backing_store) {
551+
CHECK(!heap_statistics_buffer_); // Should be set only once.
552+
heap_statistics_buffer_ = std::move(backing_store);
552553
}
553554

554555
inline double* Environment::heap_space_statistics_buffer() const {
555-
CHECK_NOT_NULL(heap_space_statistics_buffer_);
556-
return heap_space_statistics_buffer_;
556+
CHECK(heap_space_statistics_buffer_);
557+
return static_cast<double*>(heap_space_statistics_buffer_->Data());
557558
}
558559

559-
inline void Environment::set_heap_space_statistics_buffer(double* pointer) {
560-
CHECK_NULL(heap_space_statistics_buffer_); // Should be set only once.
561-
heap_space_statistics_buffer_ = pointer;
560+
inline void Environment::set_heap_space_statistics_buffer(
561+
std::shared_ptr<v8::BackingStore> backing_store) {
562+
CHECK(!heap_space_statistics_buffer_); // Should be set only once.
563+
heap_space_statistics_buffer_ = std::move(backing_store);
562564
}
563565

564566
inline double* Environment::heap_code_statistics_buffer() const {
565-
CHECK_NOT_NULL(heap_code_statistics_buffer_);
566-
return heap_code_statistics_buffer_;
567+
CHECK(heap_code_statistics_buffer_);
568+
return static_cast<double*>(heap_code_statistics_buffer_->Data());
567569
}
568570

569-
inline void Environment::set_heap_code_statistics_buffer(double* pointer) {
570-
CHECK_NULL(heap_code_statistics_buffer_); // Should be set only once.
571-
heap_code_statistics_buffer_ = pointer;
571+
inline void Environment::set_heap_code_statistics_buffer(
572+
std::shared_ptr<v8::BackingStore> backing_store) {
573+
CHECK(!heap_code_statistics_buffer_); // Should be set only once.
574+
heap_code_statistics_buffer_ = std::move(backing_store);
572575
}
573576

574577
inline char* Environment::http_parser_buffer() const {

src/env.cc

-3
Original file line numberDiff line numberDiff line change
@@ -413,10 +413,7 @@ Environment::~Environment() {
413413
tracing_controller->RemoveTraceStateObserver(trace_state_observer_.get());
414414
}
415415

416-
delete[] heap_statistics_buffer_;
417-
delete[] heap_space_statistics_buffer_;
418416
delete[] http_parser_buffer_;
419-
delete[] heap_code_statistics_buffer_;
420417

421418
TRACE_EVENT_NESTABLE_ASYNC_END0(
422419
TRACING_CATEGORY_NODE1(environment), "Environment", this);

src/env.h

+9-6
Original file line numberDiff line numberDiff line change
@@ -1020,13 +1020,16 @@ class Environment : public MemoryRetainer {
10201020
package_json_cache;
10211021

10221022
inline double* heap_statistics_buffer() const;
1023-
inline void set_heap_statistics_buffer(double* pointer);
1023+
inline void set_heap_statistics_buffer(
1024+
std::shared_ptr<v8::BackingStore> backing_store);
10241025

10251026
inline double* heap_space_statistics_buffer() const;
1026-
inline void set_heap_space_statistics_buffer(double* pointer);
1027+
inline void set_heap_space_statistics_buffer(
1028+
std::shared_ptr<v8::BackingStore> backing_store);
10271029

10281030
inline double* heap_code_statistics_buffer() const;
1029-
inline void set_heap_code_statistics_buffer(double* pointer);
1031+
inline void set_heap_code_statistics_buffer(
1032+
std::shared_ptr<v8::BackingStore> backing_store);
10301033

10311034
inline char* http_parser_buffer() const;
10321035
inline void set_http_parser_buffer(char* buffer);
@@ -1365,9 +1368,9 @@ class Environment : public MemoryRetainer {
13651368
int handle_cleanup_waiting_ = 0;
13661369
int request_waiting_ = 0;
13671370

1368-
double* heap_statistics_buffer_ = nullptr;
1369-
double* heap_space_statistics_buffer_ = nullptr;
1370-
double* heap_code_statistics_buffer_ = nullptr;
1371+
std::shared_ptr<v8::BackingStore> heap_statistics_buffer_;
1372+
std::shared_ptr<v8::BackingStore> heap_space_statistics_buffer_;
1373+
std::shared_ptr<v8::BackingStore> heap_code_statistics_buffer_;
13711374

13721375
char* http_parser_buffer_ = nullptr;
13731376
bool http_parser_buffer_in_use_ = false;

src/node_v8.cc

+8-39
Original file line numberDiff line numberDiff line change
@@ -158,23 +158,12 @@ void Initialize(Local<Object> target,
158158
"updateHeapStatisticsArrayBuffer",
159159
UpdateHeapStatisticsArrayBuffer);
160160

161-
env->set_heap_statistics_buffer(new double[kHeapStatisticsPropertiesCount]);
162-
163161
const size_t heap_statistics_buffer_byte_length =
164162
sizeof(*env->heap_statistics_buffer()) * kHeapStatisticsPropertiesCount;
165163

166-
std::unique_ptr<BackingStore> heap_statistics_backing =
167-
ArrayBuffer::NewBackingStore(env->heap_statistics_buffer(),
168-
heap_statistics_buffer_byte_length,
169-
[](void*, size_t, void*){},
170-
nullptr);
171164
Local<ArrayBuffer> heap_statistics_ab =
172-
ArrayBuffer::New(env->isolate(),
173-
std::move(heap_statistics_backing));
174-
// TODO(thangktran): drop this check when V8 is pumped to 8.0 .
175-
if (!heap_statistics_ab->IsExternal())
176-
heap_statistics_ab->Externalize(
177-
heap_statistics_ab->GetBackingStore());
165+
ArrayBuffer::New(env->isolate(), heap_statistics_buffer_byte_length);
166+
env->set_heap_statistics_buffer(heap_statistics_ab->GetBackingStore());
178167
target->Set(env->context(),
179168
FIXED_ONE_BYTE_STRING(env->isolate(),
180169
"heapStatisticsArrayBuffer"),
@@ -193,25 +182,15 @@ void Initialize(Local<Object> target,
193182
"updateHeapCodeStatisticsArrayBuffer",
194183
UpdateHeapCodeStatisticsArrayBuffer);
195184

196-
env->set_heap_code_statistics_buffer(
197-
new double[kHeapCodeStatisticsPropertiesCount]);
198-
199185
const size_t heap_code_statistics_buffer_byte_length =
200186
sizeof(*env->heap_code_statistics_buffer())
201187
* kHeapCodeStatisticsPropertiesCount;
202188

203-
std::unique_ptr<BackingStore> heap_code_statistics_backing =
204-
ArrayBuffer::NewBackingStore(env->heap_code_statistics_buffer(),
205-
heap_code_statistics_buffer_byte_length,
206-
[](void*, size_t, void*){},
207-
nullptr);
208189
Local<ArrayBuffer> heap_code_statistics_ab =
209190
ArrayBuffer::New(env->isolate(),
210-
std::move(heap_code_statistics_backing));
211-
// TODO(thangktran): drop this check when V8 is pumped to 8.0 .
212-
if (!heap_code_statistics_ab->IsExternal())
213-
heap_code_statistics_ab->Externalize(
214-
heap_code_statistics_ab->GetBackingStore());
191+
heap_code_statistics_buffer_byte_length);
192+
env->set_heap_code_statistics_buffer(
193+
heap_code_statistics_ab->GetBackingStore());
215194
target->Set(env->context(),
216195
FIXED_ONE_BYTE_STRING(env->isolate(),
217196
"heapCodeStatisticsArrayBuffer"),
@@ -257,26 +236,16 @@ void Initialize(Local<Object> target,
257236
"updateHeapSpaceStatisticsArrayBuffer",
258237
UpdateHeapSpaceStatisticsBuffer);
259238

260-
env->set_heap_space_statistics_buffer(
261-
new double[kHeapSpaceStatisticsPropertiesCount * number_of_heap_spaces]);
262-
263239
const size_t heap_space_statistics_buffer_byte_length =
264240
sizeof(*env->heap_space_statistics_buffer()) *
265241
kHeapSpaceStatisticsPropertiesCount *
266242
number_of_heap_spaces;
267243

268-
std::unique_ptr<BackingStore> heap_space_statistics_backing =
269-
ArrayBuffer::NewBackingStore(env->heap_space_statistics_buffer(),
270-
heap_space_statistics_buffer_byte_length,
271-
[](void*, size_t, void*){},
272-
nullptr);
273244
Local<ArrayBuffer> heap_space_statistics_ab =
274245
ArrayBuffer::New(env->isolate(),
275-
std::move(heap_space_statistics_backing));
276-
// TODO(thangktran): drop this check when V8 is pumped to 8.0 .
277-
if (!heap_space_statistics_ab->IsExternal())
278-
heap_space_statistics_ab->Externalize(
279-
heap_space_statistics_ab->GetBackingStore());
246+
heap_space_statistics_buffer_byte_length);
247+
env->set_heap_space_statistics_buffer(
248+
heap_space_statistics_ab->GetBackingStore());
280249
target->Set(env->context(),
281250
FIXED_ONE_BYTE_STRING(env->isolate(),
282251
"heapSpaceStatisticsArrayBuffer"),

0 commit comments

Comments
 (0)