-
-
Notifications
You must be signed in to change notification settings - Fork 35.4k
src: implement minimal v8 snapshot integration #27321
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
Closed
Closed
Changes from 1 commit
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
076c31f
src: allow creating NodeMainInstance that does not own the isolate
joyeecheung e354795
src: implement IsolateData serialization and deserialization
joyeecheung de02be6
tools: implement node_mksnapshot
joyeecheung 52c5c05
src: enable snapshot with per-isolate data
joyeecheung 8248be6
src: enable context snapshot after running per-context scripts
joyeecheung 3055cb1
fixup! tools: implement node_mksnapshot
joyeecheung 2ac1d81
src: use std::vector<size_t> instead of IndexArray
joyeecheung 1e0210b
fixup! src: enable context snapshot after running per-context scripts
joyeecheung 0324fe3
fixup! src: allow creating NodeMainInstance that does not own the iso…
joyeecheung 90b5d8d
fixup! tools: implement node_mksnapshot
joyeecheung File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
tools: implement node_mksnapshot
Implements a node_mksnapshot target that generates a snapshot blob from a Node.js main instance's isolate, and serializes the data blob with other additional data into a C++ file that can be embedded into the Node.js binary.
- Loading branch information
commit de02be6b15a1219ae28f75bf44466608afe6d916
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| #include <cstdio> | ||
| #include <fstream> | ||
| #include <iostream> | ||
| #include <sstream> | ||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| #include "libplatform/libplatform.h" | ||
| #include "node_internals.h" | ||
| #include "snapshot_builder.h" | ||
| #include "v8.h" | ||
|
|
||
| #ifdef _WIN32 | ||
| #include <VersionHelpers.h> | ||
| #include <WinError.h> | ||
|
joyeecheung marked this conversation as resolved.
Outdated
|
||
| #include <windows.h> | ||
|
|
||
| int wmain(int argc, wchar_t* argv[]) { | ||
| #else // UNIX | ||
| int main(int argc, char* argv[]) { | ||
| #endif // _WIN32 | ||
|
|
||
| if (argc < 2) { | ||
| std::cerr << "Usage: " << argv[0] << " <path/to/output.cc>\n"; | ||
| return 1; | ||
| } | ||
|
|
||
| std::ofstream out; | ||
| out.open(argv[1], std::ios::out | std::ios::binary); | ||
| if (!out.is_open()) { | ||
| std::cerr << "Cannot open " << argv[1] << "\n"; | ||
| return 1; | ||
| } | ||
|
|
||
| int node_argc = 1; | ||
| char argv0[5] = "node"; | ||
|
joyeecheung marked this conversation as resolved.
Outdated
|
||
| char* node_argv[] = {argv0}; | ||
|
|
||
| node::InitializationResult result = | ||
| node::InitializeOncePerProcess(node_argc, node_argv); | ||
|
joyeecheung marked this conversation as resolved.
|
||
| CHECK(!result.early_return); | ||
| CHECK_EQ(result.exit_code, 0); | ||
|
|
||
| { | ||
| std::string snapshot = | ||
| node::SnapshotBuilder::Generate(result.args, result.exec_args); | ||
| out << snapshot; | ||
| out.close(); | ||
| } | ||
|
|
||
| node::TearDownOncePerProcess(); | ||
| return 0; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| #include "snapshot_builder.h" | ||
| #include <iostream> | ||
| #include <sstream> | ||
| #include "env-inl.h" | ||
| #include "node_internals.h" | ||
| #include "node_main_instance.h" | ||
| #include "node_v8_platform-inl.h" | ||
|
|
||
| namespace node { | ||
|
|
||
| using v8::Context; | ||
| using v8::HandleScope; | ||
| using v8::Isolate; | ||
| using v8::Local; | ||
| using v8::Locker; | ||
| using v8::SnapshotCreator; | ||
| using v8::StartupData; | ||
|
|
||
| std::string FormatBlob(v8::StartupData* blob, | ||
| const std::vector<size_t>& isolate_data_indexes) { | ||
| std::stringstream ss; | ||
| size_t isolate_data_indexes_size = isolate_data_indexes.size(); | ||
|
|
||
| ss << R"(#include <cinttypes> | ||
|
joyeecheung marked this conversation as resolved.
Outdated
|
||
| #include <array> | ||
| #include "node_main_instance.h" | ||
| #include "v8.h" | ||
|
|
||
| // This file is generated by tools/snapshot. Do not edit. | ||
|
|
||
| namespace node { | ||
|
|
||
| static const uint8_t blob_data[] = { | ||
| )"; | ||
|
|
||
| for (int i = 0; i < blob->raw_size; i++) { | ||
| uint8_t ch = blob->data[i]; | ||
| ss << std::to_string(ch) << ((i == blob->raw_size - 1) ? '\n' : ','); | ||
| } | ||
|
|
||
| ss << R"(}; | ||
|
|
||
| static const int blob_size = )" | ||
| << blob->raw_size << R"(; | ||
| static v8::StartupData blob = { | ||
| reinterpret_cast<const char*>(blob_data), | ||
| blob_size | ||
| }; | ||
| )"; | ||
|
|
||
| ss << R"(v8::StartupData* | ||
| NodeMainInstance::GetEmbeddedSnapshotBlob() { | ||
| return &blob; | ||
| } | ||
|
|
||
| static const size_t isolate_data_indexes_raw[] = { | ||
| )"; | ||
| for (size_t i = 0; i < isolate_data_indexes_size; i++) { | ||
| ss << std::to_string(isolate_data_indexes[i]) | ||
| << ((i == isolate_data_indexes_size - 1) ? '\n' : ','); | ||
| } | ||
| ss << "};\n\n"; | ||
|
|
||
| ss << "static const size_t isolate_data_indexes_size = " | ||
| << isolate_data_indexes_size << R"(; | ||
|
|
||
| NodeMainInstance::IndexArray isolate_data_indexes { | ||
| isolate_data_indexes_raw, | ||
| isolate_data_indexes_size | ||
| }; | ||
|
|
||
| const NodeMainInstance::IndexArray* | ||
| NodeMainInstance::GetIsolateDataIndexes() { | ||
| return &isolate_data_indexes; | ||
| } | ||
| } // namespace node | ||
| )"; | ||
|
|
||
| return ss.str(); | ||
| } | ||
|
|
||
| std::string SnapshotBuilder::Generate( | ||
| const std::vector<std::string> args, | ||
| const std::vector<std::string> exec_args) { | ||
| // TODO(joyeecheung): collect external references and set it in | ||
| // params.external_references. | ||
| std::vector<intptr_t> external_references = { | ||
| reinterpret_cast<intptr_t>(nullptr)}; | ||
| Isolate* isolate = Isolate::Allocate(); | ||
| per_process::v8_platform.Platform()->RegisterIsolate(isolate, | ||
| uv_default_loop()); | ||
| NodeMainInstance* main_instance = nullptr; | ||
| std::string result; | ||
|
|
||
| { | ||
| std::vector<size_t> isolate_data_indexes; | ||
| SnapshotCreator creator(isolate, external_references.data()); | ||
| { | ||
| main_instance = | ||
| NodeMainInstance::Create(isolate, | ||
| uv_default_loop(), | ||
| per_process::v8_platform.Platform(), | ||
| args, | ||
| exec_args); | ||
| HandleScope scope(isolate); | ||
| creator.SetDefaultContext(Context::New(isolate)); | ||
| isolate_data_indexes = main_instance->isolate_data()->Serialize(&creator); | ||
| } | ||
|
|
||
| // Must be out of HandleScope | ||
| StartupData blob = | ||
| creator.CreateBlob(SnapshotCreator::FunctionCodeHandling::kClear); | ||
| // Must be done while the snapshot creator isolate is entered i.e. the | ||
| // creator is still alive. | ||
| main_instance->Dispose(); | ||
| result = FormatBlob(&blob, isolate_data_indexes); | ||
| } | ||
|
|
||
| per_process::v8_platform.Platform()->UnregisterIsolate(isolate); | ||
| return result; | ||
| } | ||
| } // namespace node | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| #ifndef TOOLS_SNAPSHOT_SNAPSHOT_BUILDER_H_ | ||
| #define TOOLS_SNAPSHOT_SNAPSHOT_BUILDER_H_ | ||
|
|
||
| #include <string> | ||
| #include <vector> | ||
|
|
||
| namespace node { | ||
| class SnapshotBuilder { | ||
| public: | ||
| static std::string Generate(const std::vector<std::string> args, | ||
| const std::vector<std::string> exec_args); | ||
| }; | ||
| } // namespace node | ||
|
|
||
| #endif // TOOLS_SNAPSHOT_SNAPSHOT_BUILDER_H_ |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.