Skip to content

Commit 4968db1

Browse files
committed
src: migrate from deprecated SnapshotCreator constructor
Previously we have been using the variant of SnapshotCreator that only passes the external references instead of v8::Isolate::CreateParams and it's about to be deprecated. Switch to using the new constructor that takes a fully CreateParams instead. This also makes sure that the snapshot building script is using the Node.js array buffer allocator instead of a separate default one that was previously used by the old constructor. The zero fill toggle in the Node.js array buffer allocator would still be ignored during snapshot building, however, until we fixes the array buffer allocator and let V8 own the toggle backing store instead, because otherwise the snapshot would contain the external toggle address and become unreproducible.
1 parent 54b5ec9 commit 4968db1

5 files changed

Lines changed: 47 additions & 14 deletions

File tree

lib/internal/buffer.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@ const {
3939
},
4040
} = internalBinding('util');
4141

42+
const {
43+
namespace: {
44+
isBuildingSnapshot,
45+
},
46+
addAfterUserSerializeCallback,
47+
} = require('internal/v8/startup_snapshot');
48+
4249
// Temporary buffers to convert numbers.
4350
const float32Array = new Float32Array(1);
4451
const uInt8Float32Array = new Uint8Array(float32Array.buffer);
@@ -1090,8 +1097,16 @@ function isMarkedAsUntransferable(obj) {
10901097
// in C++.
10911098
// |zeroFill| can be undefined when running inside an isolate where we
10921099
// do not own the ArrayBuffer allocator. Zero fill is always on in that case.
1093-
let zeroFill = getZeroFillToggle();
1100+
let zeroFill;
10941101
function createUnsafeBuffer(size) {
1102+
if (!zeroFill) {
1103+
zeroFill = getZeroFillToggle();
1104+
if (isBuildingSnapshot()) {
1105+
addAfterUserSerializeCallback(() => {
1106+
zeroFill = undefined;
1107+
});
1108+
}
1109+
}
10951110
zeroFill[0] = 0;
10961111
try {
10971112
return new FastBuffer(size);
@@ -1116,5 +1131,4 @@ module.exports = {
11161131
createUnsafeBuffer,
11171132
readUInt16BE,
11181133
readUInt32BE,
1119-
reconnectZeroFillToggle,
11201134
};

lib/internal/process/pre_execution.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ const {
2222
refreshOptions,
2323
getEmbedderOptions,
2424
} = require('internal/options');
25-
const { reconnectZeroFillToggle } = require('internal/buffer');
2625
const {
2726
exposeLazyInterfaces,
2827
defineReplaceableLazyAttribute,
@@ -92,7 +91,6 @@ function prepareExecution(options) {
9291
const { expandArgv1, initializeModules, isMainThread } = options;
9392

9493
refreshRuntimeOptions();
95-
reconnectZeroFillToggle();
9694

9795
// Patch the process object and get the resolved main entry point.
9896
const mainEntry = patchProcessObject(expandArgv1);

src/api/embed_helpers.cc

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,22 +123,36 @@ CommonEnvironmentSetup::CommonEnvironmentSetup(
123123
}
124124
loop->data = this;
125125

126+
impl_->allocator = ArrayBufferAllocator::Create();
127+
const std::vector<intptr_t>& external_references =
128+
SnapshotBuilder::CollectExternalReferences();
129+
Isolate::CreateParams params;
130+
params.array_buffer_allocator = impl_->allocator.get();
131+
params.external_references = external_references.data();
126132
Isolate* isolate;
133+
134+
// Isolates created for snapshotting should be set up differently since
135+
// it will be owned by the snapshot creator and needs to be cleaned up
136+
// before serialization.
127137
if (flags & Flags::kIsForSnapshotting) {
128-
const std::vector<intptr_t>& external_references =
129-
SnapshotBuilder::CollectExternalReferences();
138+
// The isolate must be registered before the SnapshotCreator initializes the
139+
// isolate, so that the memory reducer can be initialized.
130140
isolate = impl_->isolate = Isolate::Allocate();
131-
// Must be done before the SnapshotCreator creation so that the
132-
// memory reducer can be initialized.
133141
platform->RegisterIsolate(isolate, loop);
134-
impl_->snapshot_creator.emplace(isolate, external_references.data());
142+
143+
impl_->snapshot_creator.emplace(isolate, params);
135144
isolate->SetCaptureStackTraceForUncaughtExceptions(
136-
true, 10, v8::StackTrace::StackTraceOptions::kDetailed);
145+
true,
146+
static_cast<int>(
147+
per_process::cli_options->per_isolate->stack_trace_limit),
148+
v8::StackTrace::StackTraceOptions::kDetailed);
137149
SetIsolateMiscHandlers(isolate, {});
138150
} else {
139-
impl_->allocator = ArrayBufferAllocator::Create();
140151
isolate = impl_->isolate =
141-
NewIsolate(impl_->allocator, &impl_->loop, platform, snapshot_data);
152+
NewIsolate(&params,
153+
&impl_->loop,
154+
platform,
155+
SnapshotData::FromEmbedderWrapper(snapshot_data));
142156
}
143157

144158
{

src/node_buffer.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,7 +1231,13 @@ void GetZeroFillToggle(const FunctionCallbackInfo<Value>& args) {
12311231
// Create a dummy Uint32Array - the JS land can only toggle the C++ land
12321232
// setting when the allocator uses our toggle. With this the toggle in JS
12331233
// land results in no-ops.
1234+
1235+
ab = ArrayBuffer::New(env->isolate(), sizeof(uint32_t));
1236+
} else if (env->isolate_data()->is_building_snapshot()) {
12341237
ab = ArrayBuffer::New(env->isolate(), sizeof(uint32_t));
1238+
// TODO(joyeecheung): save ab->GetBackingStore()->Data() in the Node.js
1239+
// array buffer allocator and include it into the C++ toggle while the
1240+
// Environment is still alive.
12351241
} else {
12361242
uint32_t* zero_fill_field = allocator->zero_fill_field();
12371243
std::unique_ptr<BackingStore> backing =

src/node_snapshotable.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -863,9 +863,10 @@ const std::vector<intptr_t>& SnapshotBuilder::CollectExternalReferences() {
863863

864864
void SnapshotBuilder::InitializeIsolateParams(const SnapshotData* data,
865865
Isolate::CreateParams* params) {
866-
CHECK_NULL(params->external_references);
867866
CHECK_NULL(params->snapshot_blob);
868-
params->external_references = CollectExternalReferences().data();
867+
if (params->external_references == nullptr) {
868+
params->external_references = CollectExternalReferences().data();
869+
}
869870
params->snapshot_blob =
870871
const_cast<v8::StartupData*>(&(data->v8_snapshot_blob_data));
871872
}

0 commit comments

Comments
 (0)