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: 55 60 91.7 %
Date: 2020-07-19 22:14:24 Branches: 15 28 53.6 %

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_external_reference.h"
7
#include "node_internals.h"
8
#include "node_main_instance.h"
9
#include "node_v8_platform-inl.h"
10
11
namespace node {
12
13
using v8::Context;
14
using v8::HandleScope;
15
using v8::Isolate;
16
using v8::Local;
17
using v8::Object;
18
using v8::SnapshotCreator;
19
using v8::StartupData;
20
21
template <typename T>
22
2
void WriteVector(std::stringstream* ss, const T* vec, size_t size) {
23

358984
  for (size_t i = 0; i < size; i++) {
24

358982
    *ss << std::to_string(vec[i]) << (i == size - 1 ? '\n' : ',');
25
  }
26
2
}
27
28
1
std::string FormatBlob(v8::StartupData* blob,
29
                       const std::vector<size_t>& isolate_data_indexes,
30
                       const EnvSerializeInfo& env_info) {
31
2
  std::stringstream ss;
32
33
  ss << R"(#include <cstddef>
34
#include "env.h"
35
#include "node_main_instance.h"
36
#include "v8.h"
37
38
// This file is generated by tools/snapshot. Do not edit.
39
40
namespace node {
41
42
static const char blob_data[] = {
43
1
)";
44
1
  WriteVector(&ss, blob->data, blob->raw_size);
45
1
  ss << R"(};
46
47
static const int blob_size = )"
48
2
     << blob->raw_size << R"(;
49
static v8::StartupData blob = { blob_data, blob_size };
50
1
)";
51
52
  ss << R"(v8::StartupData* NodeMainInstance::GetEmbeddedSnapshotBlob() {
53
  return &blob;
54
}
55
56
static const std::vector<size_t> isolate_data_indexes {
57
1
)";
58
1
  WriteVector(&ss, isolate_data_indexes.data(), isolate_data_indexes.size());
59
1
  ss << R"(};
60
61
const std::vector<size_t>* NodeMainInstance::GetIsolateDataIndexes() {
62
  return &isolate_data_indexes;
63
}
64
65
static const EnvSerializeInfo env_info )"
66
1
     << env_info << R"(;
67
68
const EnvSerializeInfo* NodeMainInstance::GetEnvSerializeInfo() {
69
  return &env_info;
70
}
71
72
}  // namespace node
73
1
)";
74
75
2
  return ss.str();
76
}
77
78
74
static v8::StartupData SerializeNodeContextInternalFields(Local<Object> holder,
79
                                                          int index,
80
                                                          void* env) {
81
148
  void* ptr = holder->GetAlignedPointerFromInternalField(index);
82

74
  if (ptr == nullptr || ptr == env) {
83
74
    return StartupData{nullptr, 0};
84
  }
85
  if (ptr == env && index == ContextEmbedderIndex::kEnvironment) {
86
    return StartupData{nullptr, 0};
87
  }
88
89
  // No embedder objects in the builtin snapshot yet.
90
  UNREACHABLE();
91
  return StartupData{nullptr, 0};
92
}
93
94
1
std::string SnapshotBuilder::Generate(
95
    const std::vector<std::string> args,
96
    const std::vector<std::string> exec_args) {
97
1
  Isolate* isolate = Isolate::Allocate();
98
2
  per_process::v8_platform.Platform()->RegisterIsolate(isolate,
99
2
                                                       uv_default_loop());
100
2
  std::unique_ptr<NodeMainInstance> main_instance;
101
1
  std::string result;
102
103
  {
104
2
    std::vector<size_t> isolate_data_indexes;
105
2
    EnvSerializeInfo env_info;
106
107
    const std::vector<intptr_t>& external_references =
108
1
        NodeMainInstance::CollectExternalReferences();
109
2
    SnapshotCreator creator(isolate, external_references.data());
110
    Environment* env;
111
    {
112
      main_instance =
113
2
          NodeMainInstance::Create(isolate,
114
                                   uv_default_loop(),
115
1
                                   per_process::v8_platform.Platform(),
116
                                   args,
117
1
                                   exec_args);
118
119
2
      HandleScope scope(isolate);
120
2
      creator.SetDefaultContext(Context::New(isolate));
121
1
      isolate_data_indexes = main_instance->isolate_data()->Serialize(&creator);
122
123
1
      Local<Context> context = NewContext(isolate);
124
      Context::Scope context_scope(context);
125
126
2
      env = new Environment(main_instance->isolate_data(),
127
                            context,
128
                            args,
129
                            exec_args,
130
                            nullptr,
131
                            node::EnvironmentFlags::kDefaultFlags,
132
2
                            {});
133
2
      env->RunBootstrapping().ToLocalChecked();
134
1
      if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) {
135
        env->PrintAllBaseObjects();
136
        printf("Environment = %p\n", env);
137
      }
138
1
      env_info = env->Serialize(&creator);
139
2
      size_t index = creator.AddContext(
140
1
          context, {SerializeNodeContextInternalFields, env});
141
1
      CHECK_EQ(index, NodeMainInstance::kNodeContextIndex);
142
    }
143
144
    // Must be out of HandleScope
145
    StartupData blob =
146
1
        creator.CreateBlob(SnapshotCreator::FunctionCodeHandling::kClear);
147
1
    CHECK(blob.CanBeRehashed());
148
    // Must be done while the snapshot creator isolate is entered i.e. the
149
    // creator is still alive.
150
1
    FreeEnvironment(env);
151
1
    main_instance->Dispose();
152
1
    result = FormatBlob(&blob, isolate_data_indexes, env_info);
153
1
    delete[] blob.data;
154
  }
155
156
1
  per_process::v8_platform.Platform()->UnregisterIsolate(isolate);
157
2
  return result;
158
}
159

3
}  // namespace node