Skip to content

Commit

Permalink
build: add --write-snapshot-as-array-literals to configure.py
Browse files Browse the repository at this point in the history
This makes it easier to locate indeterminism in the snapshot, with
the following command:

$ ./configure --write-snapshot-as-array-literals
$ make V=
$ mv out/Release/obj/gen/node_snapshot.cc ./node_snapshot.cc
$ make V=
$ diff out/Release/obj/gen/node_snapshot.cc ./node_snapshot.cc

PR-URL: #49312
Refs: nodejs/build#3043
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
  • Loading branch information
joyeecheung authored and ruyadorno committed Sep 28, 2023
1 parent 8480280 commit 31db0b8
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 14 deletions.
13 changes: 13 additions & 0 deletions configure.py
Expand Up @@ -609,6 +609,14 @@
default=None,
help='Use Link Time Code Generation. This feature is only available on Windows.')

parser.add_argument('--write-snapshot-as-array-literals',
action='store_true',
dest='write_snapshot_as_array_literals',
default=None,
help='Write the snapshot data as array literals for readability.'
'By default the snapshot data may be written as string literals on some '
'platforms to speed up compilation.')

parser.add_argument('--without-node-snapshot',
action='store_true',
dest='without_node_snapshot',
Expand Down Expand Up @@ -1290,6 +1298,11 @@ def configure_node(o):
o['variables']['node_use_node_code_cache'] = b(
not cross_compiling and not options.shared)

if options.write_snapshot_as_array_literals is not None:
o['variables']['node_write_snapshot_as_array_literals'] = b(options.write_snapshot_as_array_literals)
else:
o['variables']['node_write_snapshot_as_array_literals'] = b(flavor != 'mac' and flavor != 'linux')

if target_arch == 'arm':
configure_arm(o)
elif target_arch in ('mips', 'mipsel', 'mips64el'):
Expand Down
5 changes: 3 additions & 2 deletions node.gyp
Expand Up @@ -10,6 +10,7 @@
'node_use_v8_platform%': 'true',
'node_use_bundled_v8%': 'true',
'node_shared%': 'false',
'node_write_snapshot_as_string_literals': 'true',
'force_dynamic_crt%': 0,
'ossfuzz' : 'false',
'node_module_version%': '',
Expand Down Expand Up @@ -1247,8 +1248,8 @@
],

'conditions': [
['OS in "linux mac"', {
'defines': [ 'NODE_MKSNAPSHOT_USE_STRING_LITERALS=1' ],
['node_write_snapshot_as_array_literals=="true"', {
'defines': [ 'NODE_MKSNAPSHOT_USE_ARRAY_LITERALS=1' ],
}],
[ 'node_use_openssl=="true"', {
'defines': [
Expand Down
2 changes: 1 addition & 1 deletion src/node_snapshot_builder.h
Expand Up @@ -23,7 +23,7 @@ class NODE_EXTERN_PRIVATE SnapshotBuilder {
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args,
std::optional<std::string_view> main_script_path = std::nullopt,
bool use_string_literals = true);
bool use_array_literals = false);

// Generate the snapshot into out.
static ExitCode Generate(SnapshotData* out,
Expand Down
14 changes: 7 additions & 7 deletions src/node_snapshotable.cc
Expand Up @@ -773,11 +773,11 @@ void WriteByteVectorLiteral(std::ostream* ss,
const T* vec,
size_t size,
const char* var_name,
bool use_string_literals) {
bool use_array_literals) {
constexpr bool is_uint8_t = std::is_same_v<T, uint8_t>;
static_assert(is_uint8_t || std::is_same_v<T, char>);
constexpr const char* type_name = is_uint8_t ? "uint8_t" : "char";
if (use_string_literals) {
if (!use_array_literals) {
const uint8_t* data = reinterpret_cast<const uint8_t*>(vec);
*ss << "static const " << type_name << " *" << var_name << " = ";
*ss << (is_uint8_t ? R"(reinterpret_cast<const uint8_t *>(")" : "\"");
Expand Down Expand Up @@ -818,7 +818,7 @@ static void WriteCodeCacheInitializer(std::ostream* ss,

void FormatBlob(std::ostream& ss,
const SnapshotData* data,
bool use_string_literals) {
bool use_array_literals) {
ss << R"(#include <cstddef>
#include "env.h"
#include "node_snapshot_builder.h"
Expand All @@ -833,7 +833,7 @@ namespace node {
data->v8_snapshot_blob_data.data,
data->v8_snapshot_blob_data.raw_size,
"v8_snapshot_blob_data",
use_string_literals);
use_array_literals);

ss << R"(static const int v8_snapshot_blob_size = )"
<< data->v8_snapshot_blob_data.raw_size << ";\n";
Expand All @@ -846,7 +846,7 @@ namespace node {
item.data.data,
item.data.length,
var_name.c_str(),
use_string_literals);
use_array_literals);
}

ss << R"(const SnapshotData snapshot_data {
Expand Down Expand Up @@ -1132,7 +1132,7 @@ ExitCode SnapshotBuilder::GenerateAsSource(
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args,
std::optional<std::string_view> main_script_path,
bool use_string_literals) {
bool use_array_literals) {
std::string main_script_content;
std::optional<std::string_view> main_script_optional;
if (main_script_path.has_value()) {
Expand All @@ -1159,7 +1159,7 @@ ExitCode SnapshotBuilder::GenerateAsSource(
if (exit_code != ExitCode::kNoFailure) {
return exit_code;
}
FormatBlob(out, &data, use_string_literals);
FormatBlob(out, &data, use_array_literals);

if (!out) {
std::cerr << "Failed to write to " << out_path << "\n";
Expand Down
8 changes: 4 additions & 4 deletions tools/snapshot/node_mksnapshot.cc
Expand Up @@ -79,18 +79,18 @@ int BuildSnapshot(int argc, char* argv[]) {
out_path = result->args()[1];
}

#ifdef NODE_MKSNAPSHOT_USE_STRING_LITERALS
bool use_string_literals = true;
#ifdef NODE_MKSNAPSHOT_USE_ARRAY_LITERALS
bool use_array_literals = true;
#else
bool use_string_literals = false;
bool use_array_literals = false;
#endif

node::ExitCode exit_code =
node::SnapshotBuilder::GenerateAsSource(out_path.c_str(),
result->args(),
result->exec_args(),
main_script_path,
use_string_literals);
use_array_literals);

node::TearDownOncePerProcess();
return static_cast<int>(exit_code);
Expand Down

0 comments on commit 31db0b8

Please sign in to comment.