GeezerVison is showing github.com — src: migrate from deprecated SnapshotCreator constructor · nodejs/node@fded233
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/buffer.js +18-10Lines changed: 18 additions & 10 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -39,6 +39,13 @@ const { | 39 | 39 | }, | 40 | 40 | } = internalBinding('util'); | 41 | 41 |
| | 42 | +const { | | 43 | + namespace: { | | 44 | + isBuildingSnapshot, | | 45 | + }, | | 46 | + addAfterUserSerializeCallback, | | 47 | +} = require('internal/v8/startup_snapshot'); | | 48 | + | 42 | 49 | // Temporary buffers to convert numbers. | 43 | 50 | const float32Array = new Float32Array(1); | 44 | 51 | const uInt8Float32Array = new Uint8Array(float32Array.buffer); | @@ -1090,8 +1097,18 @@ function isMarkedAsUntransferable(obj) { | 1090 | 1097 | // in C++. | 1091 | 1098 | // |zeroFill| can be undefined when running inside an isolate where we | 1092 | 1099 | // do not own the ArrayBuffer allocator. Zero fill is always on in that case. | 1093 | | -let zeroFill = getZeroFillToggle(); | | 1100 | +let zeroFill; | 1094 | 1101 | function createUnsafeBuffer(size) { | | 1102 | + if (!zeroFill) { | | 1103 | + zeroFill = getZeroFillToggle(); | | 1104 | + if (isBuildingSnapshot()) { | | 1105 | + // Reset the toggle so that after serialization, we'll re-create a real | | 1106 | + // toggle connected to the C++ one via getZeroFillToggle(). | | 1107 | + addAfterUserSerializeCallback(() => { | | 1108 | + zeroFill = undefined; | | 1109 | + }); | | 1110 | + } | | 1111 | + } | 1095 | 1112 | zeroFill[0] = 0; | 1096 | 1113 | try { | 1097 | 1114 | return new FastBuffer(size); | @@ -1100,14 +1117,6 @@ function createUnsafeBuffer(size) { | 1100 | 1117 | } | 1101 | 1118 | } | 1102 | 1119 |
| 1103 | | -// The connection between the JS land zero fill toggle and the | 1104 | | -// C++ one in the NodeArrayBufferAllocator gets lost if the toggle | 1105 | | -// is deserialized from the snapshot, because V8 owns the underlying | 1106 | | -// memory of this toggle. This resets the connection. | 1107 | | -function reconnectZeroFillToggle() { | 1108 | | - zeroFill = getZeroFillToggle(); | 1109 | | -} | 1110 | | - | 1111 | 1120 | module.exports = { | 1112 | 1121 | FastBuffer, | 1113 | 1122 | addBufferPrototypeMethods, | @@ -1116,5 +1125,4 @@ module.exports = { | 1116 | 1125 | createUnsafeBuffer, | 1117 | 1126 | readUInt16BE, | 1118 | 1127 | readUInt32BE, | 1119 | | - reconnectZeroFillToggle, | 1120 | 1128 | }; |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/process/pre_execution.js -2Lines changed: 0 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -21,7 +21,6 @@ const { | 21 | 21 | refreshOptions, | 22 | 22 | getEmbedderOptions, | 23 | 23 | } = require('internal/options'); | 24 | | -const { reconnectZeroFillToggle } = require('internal/buffer'); | 25 | 24 | const { | 26 | 25 | exposeLazyInterfaces, | 27 | 26 | defineReplaceableLazyAttribute, | @@ -91,7 +90,6 @@ function prepareExecution(options) { | 91 | 90 | const { expandArgv1, initializeModules, isMainThread } = options; | 92 | 91 |
| 93 | 92 | refreshRuntimeOptions(); | 94 | | - reconnectZeroFillToggle(); | 95 | 93 |
| 96 | 94 | // Patch the process object and get the resolved main entry point. | 97 | 95 | const mainEntry = patchProcessObject(expandArgv1); | |
Collapse file Copy file name to clipboardExpand all lines: src/api/embed_helpers.cc +29-11Lines changed: 29 additions & 11 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -110,22 +110,40 @@ CommonEnvironmentSetup::CommonEnvironmentSetup( | 110 | 110 | } | 111 | 111 | loop->data = this; | 112 | 112 |
| | 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(); | | 119 | + params.external_references = external_references.data(); | | 120 | + params.cpp_heap = | | 121 | + v8::CppHeap::Create(platform, v8::CppHeapCreateParams{{}}).release(); | | 122 | + | 113 | 123 | Isolate* isolate; | | 124 | + | | 125 | + // Isolates created for snapshotting should be set up differently since | | 126 | + // it will be owned by the snapshot creator and needs to be cleaned up | | 127 | + // before serialization. | 114 | 128 | if (flags & Flags::kIsForSnapshotting) { | 115 | | - const std::vector<intptr_t>& external_references = | 116 | | - SnapshotBuilder::CollectExternalReferences(); | | 129 | + // The isolate must be registered before the SnapshotCreator initializes the | | 130 | + // isolate, so that the memory reducer can be initialized. | 117 | 131 | isolate = impl_->isolate = Isolate::Allocate(); | 118 | | - // Must be done before the SnapshotCreator creation so that the | 119 | | - // memory reducer can be initialized. | 120 | 132 | platform->RegisterIsolate(isolate, loop); | 121 | | - impl_->snapshot_creator.emplace(isolate, external_references.data()); | | 133 | + | | 134 | + impl_->snapshot_creator.emplace(isolate, params); | 122 | 135 | isolate->SetCaptureStackTraceForUncaughtExceptions( | 123 | | - true, 10, v8::StackTrace::StackTraceOptions::kDetailed); | | 136 | + true, | | 137 | + static_cast<int>( | | 138 | + per_process::cli_options->per_isolate->stack_trace_limit), | | 139 | + v8::StackTrace::StackTraceOptions::kDetailed); | 124 | 140 | SetIsolateMiscHandlers(isolate, {}); | 125 | 141 | } else { | 126 | | - impl_->allocator = ArrayBufferAllocator::Create(); | 127 | 142 | isolate = impl_->isolate = | 128 | | - NewIsolate(impl_->allocator, &impl_->loop, platform, snapshot_data); | | 143 | + NewIsolate(¶ms, | | 144 | + &impl_->loop, | | 145 | + platform, | | 146 | + SnapshotData::FromEmbedderWrapper(snapshot_data)); | 129 | 147 | } | 130 | 148 |
| 131 | 149 | { | @@ -220,10 +238,10 @@ CommonEnvironmentSetup::~CommonEnvironmentSetup() { | 220 | 238 | *static_cast<bool*>(data) = true; | 221 | 239 | }, &platform_finished); | 222 | 240 | impl_->platform->UnregisterIsolate(isolate); | 223 | | - if (impl_->snapshot_creator.has_value()) | | 241 | + if (impl_->snapshot_creator.has_value()) { | 224 | 242 | impl_->snapshot_creator.reset(); | 225 | | - else | 226 | | - isolate->Dispose(); | | 243 | + } | | 244 | + isolate->Dispose(); | 227 | 245 |
| 228 | 246 | // Wait until the platform has cleaned up all relevant resources. | 229 | 247 | while (!platform_finished) | |
Collapse file Copy file name to clipboardExpand all lines: src/node_buffer.cc +9-1Lines changed: 9 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -1222,12 +1222,20 @@ void GetZeroFillToggle(const FunctionCallbackInfo<Value>& args) { | 1222 | 1222 | Local<ArrayBuffer> ab; | 1223 | 1223 | // It can be a nullptr when running inside an isolate where we | 1224 | 1224 | // do not own the ArrayBuffer allocator. | 1225 | | - if (allocator == nullptr) { | | 1225 | + if (allocator == nullptr || env->isolate_data()->is_building_snapshot()) { | 1226 | 1226 | // Create a dummy Uint32Array - the JS land can only toggle the C++ land | 1227 | 1227 | // setting when the allocator uses our toggle. With this the toggle in JS | 1228 | 1228 | // land results in no-ops. | | 1229 | + // When building a snapshot, just use a dummy toggle as well to avoid | | 1230 | + // introducing the dynamic external reference. We'll re-initialize the | | 1231 | + // toggle with a real one connected to the C++ allocator after snapshot | | 1232 | + // deserialization. | | 1233 | + | 1229 | 1234 | ab = ArrayBuffer::New(env->isolate(), sizeof(uint32_t)); | 1230 | 1235 | } else { | | 1236 | + // TODO(joyeecheung): save ab->GetBackingStore()->Data() in the Node.js | | 1237 | + // array buffer allocator and include it into the C++ toggle while the | | 1238 | + // Environment is still alive. | 1231 | 1239 | uint32_t* zero_fill_field = allocator->zero_fill_field(); | 1232 | 1240 | std::unique_ptr<BackingStore> backing = | 1233 | 1241 | ArrayBuffer::NewBackingStore(zero_fill_field, | |
Collapse file Copy file name to clipboardExpand all lines: src/node_snapshotable.cc +3-2Lines changed: 3 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -863,9 +863,10 @@ const std::vector<intptr_t>& SnapshotBuilder::CollectExternalReferences() { | 863 | 863 |
| 864 | 864 | void SnapshotBuilder::InitializeIsolateParams(const SnapshotData* data, | 865 | 865 | Isolate::CreateParams* params) { | 866 | | - CHECK_NULL(params->external_references); | 867 | 866 | CHECK_NULL(params->snapshot_blob); | 868 | | - params->external_references = CollectExternalReferences().data(); | | 867 | + if (params->external_references == nullptr) { | | 868 | + params->external_references = CollectExternalReferences().data(); | | 869 | + } | 869 | 870 | params->snapshot_blob = | 870 | 871 | const_cast<v8::StartupData*>(&(data->v8_snapshot_blob_data)); | 871 | 872 | } | |
|