Skip to content

Commit 494669b

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 95b0f9d commit 494669b

File tree

5 files changed

+47
-14
lines changed

5 files changed

+47
-14
lines changed

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
@@ -21,7 +21,6 @@ const {
2121
refreshOptions,
2222
getEmbedderOptions,
2323
} = require('internal/options');
24-
const { reconnectZeroFillToggle } = require('internal/buffer');
2524
const {
2625
exposeLazyInterfaces,
2726
defineReplaceableLazyAttribute,
@@ -91,7 +90,6 @@ function prepareExecution(options) {
9190
const { expandArgv1, initializeModules, isMainThread } = options;
9291

9392
refreshRuntimeOptions();
94-
reconnectZeroFillToggle();
9593

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

src/api/embed_helpers.cc

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,22 +110,36 @@ CommonEnvironmentSetup::CommonEnvironmentSetup(
110110
}
111111
loop->data = this;
112112

113+
impl_->allocator = ArrayBufferAllocator::Create();
114+
const std::vector<intptr_t>& external_references =
115+
SnapshotBuilder::CollectExternalReferences();
116+
Isolate::CreateParams params;
117+
params.array_buffer_allocator = impl_->allocator.get();
118+
params.external_references = external_references.data();
113119
Isolate* isolate;
120+
121+
// Isolates created for snapshotting should be set up differently since
122+
// it will be owned by the snapshot creator and needs to be cleaned up
123+
// before serialization.
114124
if (flags & Flags::kIsForSnapshotting) {
115-
const std::vector<intptr_t>& external_references =
116-
SnapshotBuilder::CollectExternalReferences();
125+
// The isolate must be registered before the SnapshotCreator initializes the
126+
// isolate, so that the memory reducer can be initialized.
117127
isolate = impl_->isolate = Isolate::Allocate();
118-
// Must be done before the SnapshotCreator creation so that the
119-
// memory reducer can be initialized.
120128
platform->RegisterIsolate(isolate, loop);
121-
impl_->snapshot_creator.emplace(isolate, external_references.data());
129+
130+
impl_->snapshot_creator.emplace(isolate, params);
122131
isolate->SetCaptureStackTraceForUncaughtExceptions(
123-
true, 10, v8::StackTrace::StackTraceOptions::kDetailed);
132+
true,
133+
static_cast<int>(
134+
per_process::cli_options->per_isolate->stack_trace_limit),
135+
v8::StackTrace::StackTraceOptions::kDetailed);
124136
SetIsolateMiscHandlers(isolate, {});
125137
} else {
126-
impl_->allocator = ArrayBufferAllocator::Create();
127138
isolate = impl_->isolate =
128-
NewIsolate(impl_->allocator, &impl_->loop, platform, snapshot_data);
139+
NewIsolate(&params,
140+
&impl_->loop,
141+
platform,
142+
SnapshotData::FromEmbedderWrapper(snapshot_data));
129143
}
130144

131145
{

src/node_buffer.cc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,7 +1226,13 @@ void GetZeroFillToggle(const FunctionCallbackInfo<Value>& args) {
12261226
// Create a dummy Uint32Array - the JS land can only toggle the C++ land
12271227
// setting when the allocator uses our toggle. With this the toggle in JS
12281228
// land results in no-ops.
1229+
1230+
ab = ArrayBuffer::New(env->isolate(), sizeof(uint32_t));
1231+
} else if (env->isolate_data()->is_building_snapshot()) {
12291232
ab = ArrayBuffer::New(env->isolate(), sizeof(uint32_t));
1233+
// TODO(joyeecheung): save ab->GetBackingStore()->Data() in the Node.js
1234+
// array buffer allocator and include it into the C++ toggle while the
1235+
// Environment is still alive.
12301236
} else {
12311237
uint32_t* zero_fill_field = allocator->zero_fill_field();
12321238
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)