GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../tools/snapshot/snapshot_builder.cc Lines: 56 61 91.8 %
Date: 2021-06-09 04:12:02 Branches: 16 24 66.7 %

Line Branch Exec Source
1
#include "snapshot_builder.h"
2
#include <iostream>
3
#include <sstream>
4
#include "debug_utils-inl.h"
5
#include "env-inl.h"
6
#include "node_errors.h"
7
#include "node_external_reference.h"
8
#include "node_internals.h"
9
#include "node_main_instance.h"
10
#include "node_snapshotable.h"
11
#include "node_v8_platform-inl.h"
12
13
namespace node {
14
15
using v8::Context;
16
using v8::HandleScope;
17
using v8::Isolate;
18
using v8::Local;
19
using v8::SnapshotCreator;
20
using v8::StartupData;
21
using v8::TryCatch;
22
using v8::Value;
23
24
template <typename T>
25
16
void WriteVector(std::stringstream* ss, const T* vec, size_t size) {
26

4062509
  for (size_t i = 0; i < size; i++) {
27

4062493
    *ss << std::to_string(vec[i]) << (i == size - 1 ? '\n' : ',');
28
  }
29
16
}
30
31
8
std::string FormatBlob(StartupData* blob,
32
                       const std::vector<size_t>& isolate_data_indexes,
33
                       const EnvSerializeInfo& env_info) {
34
16
  std::stringstream ss;
35
36
  ss << R"(#include <cstddef>
37
#include "env.h"
38
#include "node_main_instance.h"
39
#include "v8.h"
40
41
// This file is generated by tools/snapshot. Do not edit.
42
43
namespace node {
44
45
static const char blob_data[] = {
46
8
)";
47
8
  WriteVector(&ss, blob->data, blob->raw_size);
48
8
  ss << R"(};
49
50
static const int blob_size = )"
51
16
     << blob->raw_size << R"(;
52
static v8::StartupData blob = { blob_data, blob_size };
53
8
)";
54
55
  ss << R"(v8::StartupData* NodeMainInstance::GetEmbeddedSnapshotBlob() {
56
  return &blob;
57
}
58
59
static const std::vector<size_t> isolate_data_indexes {
60
8
)";
61
8
  WriteVector(&ss, isolate_data_indexes.data(), isolate_data_indexes.size());
62
8
  ss << R"(};
63
64
const std::vector<size_t>* NodeMainInstance::GetIsolateDataIndexes() {
65
  return &isolate_data_indexes;
66
}
67
68
static const EnvSerializeInfo env_info )"
69
8
     << env_info << R"(;
70
71
const EnvSerializeInfo* NodeMainInstance::GetEnvSerializeInfo() {
72
  return &env_info;
73
}
74
75
}  // namespace node
76
8
)";
77
78
16
  return ss.str();
79
}
80
81
8
std::string SnapshotBuilder::Generate(
82
    const std::vector<std::string> args,
83
    const std::vector<std::string> exec_args) {
84
8
  Isolate* isolate = Isolate::Allocate();
85
  isolate->SetCaptureStackTraceForUncaughtExceptions(
86
    true,
87
    10,
88
8
    v8::StackTrace::StackTraceOptions::kDetailed);
89
16
  per_process::v8_platform.Platform()->RegisterIsolate(isolate,
90
16
                                                       uv_default_loop());
91
16
  std::unique_ptr<NodeMainInstance> main_instance;
92
8
  std::string result;
93
94
  {
95
16
    std::vector<size_t> isolate_data_indexes;
96
16
    EnvSerializeInfo env_info;
97
98
    const std::vector<intptr_t>& external_references =
99
8
        NodeMainInstance::CollectExternalReferences();
100
16
    SnapshotCreator creator(isolate, external_references.data());
101
    Environment* env;
102
    {
103
      main_instance =
104
16
          NodeMainInstance::Create(isolate,
105
                                   uv_default_loop(),
106
8
                                   per_process::v8_platform.Platform(),
107
                                   args,
108
8
                                   exec_args);
109
110
16
      HandleScope scope(isolate);
111
16
      creator.SetDefaultContext(Context::New(isolate));
112
8
      isolate_data_indexes = main_instance->isolate_data()->Serialize(&creator);
113
114
      // Run the per-context scripts
115
      Local<Context> context;
116
      {
117
16
        TryCatch bootstrapCatch(isolate);
118
8
        context = NewContext(isolate);
119
8
        if (bootstrapCatch.HasCaught()) {
120
          PrintCaughtException(isolate, context, bootstrapCatch);
121
          abort();
122
        }
123
      }
124
      Context::Scope context_scope(context);
125
126
      // Create the environment
127
16
      env = new Environment(main_instance->isolate_data(),
128
                            context,
129
                            args,
130
                            exec_args,
131
                            nullptr,
132
                            node::EnvironmentFlags::kDefaultFlags,
133
16
                            {});
134
      // Run scripts in lib/internal/bootstrap/
135
      {
136
16
        TryCatch bootstrapCatch(isolate);
137
8
        v8::MaybeLocal<Value> result = env->RunBootstrapping();
138
8
        if (bootstrapCatch.HasCaught()) {
139
          PrintCaughtException(isolate, context, bootstrapCatch);
140
        }
141
        result.ToLocalChecked();
142
      }
143
144
8
      if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) {
145
        env->PrintAllBaseObjects();
146
        printf("Environment = %p\n", env);
147
      }
148
149
      // Serialize the native states
150
8
      env_info = env->Serialize(&creator);
151
      // Serialize the context
152
16
      size_t index = creator.AddContext(
153
8
          context, {SerializeNodeContextInternalFields, env});
154
8
      CHECK_EQ(index, NodeMainInstance::kNodeContextIndex);
155
    }
156
157
    // Must be out of HandleScope
158
    StartupData blob =
159
8
        creator.CreateBlob(SnapshotCreator::FunctionCodeHandling::kClear);
160
8
    CHECK(blob.CanBeRehashed());
161
    // Must be done while the snapshot creator isolate is entered i.e. the
162
    // creator is still alive.
163
8
    FreeEnvironment(env);
164
8
    main_instance->Dispose();
165
8
    result = FormatBlob(&blob, isolate_data_indexes, env_info);
166
8
    delete[] blob.data;
167
  }
168
169
8
  per_process::v8_platform.Platform()->UnregisterIsolate(isolate);
170
16
  return result;
171
}
172

24
}  // namespace node