Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: remove heap allocation for startup snapshot where possible MONGOSH-1771 #60

Merged
merged 3 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .evergreen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ functions:
set -e
set -x

export NODE_VERSION=20.5.0
export NODE_VERSION=20.13.0
bash .evergreen/install-node.sh
install:
- command: shell.exec
Expand Down Expand Up @@ -106,7 +106,7 @@ tasks:
- func: install
- func: test
vars:
node_version: "20.5.0"
node_version: "20.13.0"
- name: check
commands:
- func: checkout
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
node-version: [14.x, 16.x, 18.x, 19.x]
node-version: [14.x, 16.x, 18.x, 20.x]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
Expand Down
25 changes: 21 additions & 4 deletions resources/main-template.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <openssl/rand.h>
#endif
#include <type_traits> // injected code may refer to std::underlying_type
#include <optional>

using namespace node;
using namespace v8;
Expand All @@ -34,6 +35,12 @@ using namespace v8;
#define NODE_VERSION_SUPPORTS_EMBEDDER_SNAPSHOT 1
#endif

// 20.13.0 has https://github.com/nodejs/node/pull/52595 for better startup snapshot
// initialization performance.
#if NODE_VERSION_AT_LEAST(20, 13, 0)
#define NODE_VERSION_SUPPORTS_STRING_VIEW_SNAPSHOT 1
#endif

// Snapshot config is supported since https://github.com/nodejs/node/pull/50453
#if NODE_VERSION_AT_LEAST(20, 12, 0) && !defined(BOXEDNODE_SNAPSHOT_CONFIG_FLAGS)
#define BOXEDNODE_SNAPSHOT_CONFIG_FLAGS (SnapshotFlags::kWithoutCodeCache)
Expand Down Expand Up @@ -81,6 +88,9 @@ void MarkTime(const char* category, const char* label) {
Local<String> GetBoxednodeMainScriptSource(Isolate* isolate);
Local<Uint8Array> GetBoxednodeCodeCacheBuffer(Isolate* isolate);
std::vector<char> GetBoxednodeSnapshotBlobVector();
#ifdef NODE_VERSION_SUPPORTS_STRING_VIEW_SNAPSHOT
std::optional<std::string_view> GetBoxednodeSnapshotBlobSV();
#endif

void GetTimingData(const FunctionCallbackInfo<Value>& info) {
Isolate* isolate = info.GetIsolate();
Expand Down Expand Up @@ -230,11 +240,18 @@ static int RunNodeInstance(MultiIsolatePlatform* platform,
ArrayBufferAllocator::Create();

#ifdef BOXEDNODE_CONSUME_SNAPSHOT
std::vector<char> snapshot_blob_vec = boxednode::GetBoxednodeSnapshotBlobVector();
boxednode::MarkTime("Node.js Instance", "Decoded snapshot");
assert(EmbedderSnapshotData::CanUseCustomSnapshotPerIsolate());
node::EmbedderSnapshotData::Pointer snapshot_blob =
EmbedderSnapshotData::FromBlob(snapshot_blob_vec);
node::EmbedderSnapshotData::Pointer snapshot_blob;
#ifdef NODE_VERSION_SUPPORTS_STRING_VIEW_SNAPSHOT
if (const auto snapshot_blob_sv = boxednode::GetBoxednodeSnapshotBlobSV()) {
snapshot_blob = EmbedderSnapshotData::FromBlob(snapshot_blob_sv.value());
}
#endif
if (!snapshot_blob) {
std::vector<char> snapshot_blob_vec = boxednode::GetBoxednodeSnapshotBlobVector();
boxednode::MarkTime("Node.js Instance", "Decoded snapshot");
snapshot_blob = EmbedderSnapshotData::FromBlob(snapshot_blob_vec);
}
boxednode::MarkTime("Node.js Instance", "Read snapshot");
Isolate* isolate = NewIsolate(allocator, loop, platform, snapshot_blob.get());
#elif NODE_VERSION_AT_LEAST(14, 0, 0)
Expand Down
17 changes: 17 additions & 0 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,17 @@ export async function createUncompressedBlobDefinition (fnName: string, source:
${Uint8Array.prototype.toString.call(source) || '0'}
};

#ifdef NODE_VERSION_SUPPORTS_STRING_VIEW_SNAPSHOT
std::optional<std::string_view> ${fnName}SV() {
return {
{
reinterpret_cast<const char*>(&${fnName}_source_[0]),
${source.length}
}
};
}
#endif

std::vector<char> ${fnName}Vector() {
return std::vector<char>(
reinterpret_cast<const char*>(&${fnName}_source_[0]),
Expand Down Expand Up @@ -155,6 +166,12 @@ export async function createCompressedBlobDefinition (fnName: string, source: Ui
return dst;`}
}

#ifdef NODE_VERSION_SUPPORTS_STRING_VIEW_SNAPSHOT
std::optional<std::string_view> ${fnName}SV() {
return {};
}
#endif

${blobTypedArrayAccessors(fnName, source.length)}
`;
}
Expand Down
2 changes: 1 addition & 1 deletion test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ describe('basic functionality', () => {
it(`works with snapshot support (compressBlobs = ${compressBlobs})`, async function () {
this.timeout(2 * 60 * 60 * 1000); // 2 hours
await compileJSFileAsBinary({
nodeVersionRange: '^21.6.2',
nodeVersionRange: '^20.13.0',
sourceFile: path.resolve(__dirname, 'resources/snapshot-echo-args.js'),
targetFile: path.resolve(__dirname, `resources/snapshot-echo-args${exeSuffix}`),
useNodeSnapshot: true,
Expand Down
Loading