GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_main_instance.cc Lines: 96 97 99.0 %
Date: 2021-06-09 04:12:02 Branches: 47 62 75.8 %

Line Branch Exec Source
1
#include "node_main_instance.h"
2
#include <memory>
3
#include "debug_utils-inl.h"
4
#include "node_external_reference.h"
5
#include "node_internals.h"
6
#include "node_options-inl.h"
7
#include "node_snapshotable.h"
8
#include "node_v8_platform-inl.h"
9
#include "util-inl.h"
10
#if defined(LEAK_SANITIZER)
11
#include <sanitizer/lsan_interface.h>
12
#endif
13
14
#if HAVE_INSPECTOR
15
#include "inspector/worker_inspector.h"  // ParentInspectorHandle
16
#endif
17
18
namespace node {
19
20
using v8::Context;
21
using v8::HandleScope;
22
using v8::Isolate;
23
using v8::Local;
24
using v8::Locker;
25
26
4846
std::unique_ptr<ExternalReferenceRegistry> NodeMainInstance::registry_ =
27
    nullptr;
28
8
NodeMainInstance::NodeMainInstance(Isolate* isolate,
29
                                   uv_loop_t* event_loop,
30
                                   MultiIsolatePlatform* platform,
31
                                   const std::vector<std::string>& args,
32
8
                                   const std::vector<std::string>& exec_args)
33
    : args_(args),
34
      exec_args_(exec_args),
35
      array_buffer_allocator_(nullptr),
36
      isolate_(isolate),
37
      platform_(platform),
38
      isolate_data_(nullptr),
39
      owns_isolate_(false),
40
8
      deserialize_mode_(false) {
41
  isolate_data_ =
42
8
      std::make_unique<IsolateData>(isolate_, event_loop, platform, nullptr);
43
44
8
  SetIsolateMiscHandlers(isolate_, {});
45
8
}
46
47
4767
const std::vector<intptr_t>& NodeMainInstance::CollectExternalReferences() {
48
  // Cannot be called more than once.
49
4767
  CHECK_NULL(registry_);
50
4767
  registry_.reset(new ExternalReferenceRegistry());
51
4767
  return registry_->external_references();
52
}
53
54
8
std::unique_ptr<NodeMainInstance> NodeMainInstance::Create(
55
    Isolate* isolate,
56
    uv_loop_t* event_loop,
57
    MultiIsolatePlatform* platform,
58
    const std::vector<std::string>& args,
59
    const std::vector<std::string>& exec_args) {
60
  return std::unique_ptr<NodeMainInstance>(
61
8
      new NodeMainInstance(isolate, event_loop, platform, args, exec_args));
62
}
63
64
4760
NodeMainInstance::NodeMainInstance(
65
    Isolate::CreateParams* params,
66
    uv_loop_t* event_loop,
67
    MultiIsolatePlatform* platform,
68
    const std::vector<std::string>& args,
69
    const std::vector<std::string>& exec_args,
70
4760
    const std::vector<size_t>* per_isolate_data_indexes)
71
    : args_(args),
72
      exec_args_(exec_args),
73
      array_buffer_allocator_(ArrayBufferAllocator::Create()),
74
      isolate_(nullptr),
75
      platform_(platform),
76
      isolate_data_(nullptr),
77
4760
      owns_isolate_(true) {
78
4760
  params->array_buffer_allocator = array_buffer_allocator_.get();
79
4760
  deserialize_mode_ = per_isolate_data_indexes != nullptr;
80
4760
  if (deserialize_mode_) {
81
    // TODO(joyeecheung): collect external references and set it in
82
    // params.external_references.
83
    const std::vector<intptr_t>& external_references =
84
4759
        CollectExternalReferences();
85
4759
    params->external_references = external_references.data();
86
  }
87
88
4760
  isolate_ = Isolate::Allocate();
89
4760
  CHECK_NOT_NULL(isolate_);
90
  // Register the isolate on the platform before the isolate gets initialized,
91
  // so that the isolate can access the platform during initialization.
92
4760
  platform->RegisterIsolate(isolate_, event_loop);
93
4760
  SetIsolateCreateParamsForNode(params);
94
4760
  Isolate::Initialize(isolate_, *params);
95
96
  // If the indexes are not nullptr, we are not deserializing
97

4760
  CHECK_IMPLIES(deserialize_mode_, params->external_references != nullptr);
98
9520
  isolate_data_ = std::make_unique<IsolateData>(isolate_,
99
                                                event_loop,
100
                                                platform,
101
9520
                                                array_buffer_allocator_.get(),
102
4760
                                                per_isolate_data_indexes);
103
4760
  IsolateSettings s;
104
4760
  SetIsolateMiscHandlers(isolate_, s);
105
4760
  if (!deserialize_mode_) {
106
    // If in deserialize mode, delay until after the deserialization is
107
    // complete.
108
1
    SetIsolateErrorHandlers(isolate_, s);
109
  }
110
9520
  isolate_data_->max_young_gen_size =
111
4760
      params->constraints.max_young_generation_size_in_bytes();
112
4760
}
113
114
8
void NodeMainInstance::Dispose() {
115
8
  CHECK(!owns_isolate_);
116
8
  platform_->DrainTasks(isolate_);
117
8
}
118
119


8594
NodeMainInstance::~NodeMainInstance() {
120
4297
  if (!owns_isolate_) {
121
8
    return;
122
  }
123
4289
  platform_->UnregisterIsolate(isolate_);
124
4289
  isolate_->Dispose();
125
4297
}
126
127
4760
int NodeMainInstance::Run(const EnvSerializeInfo* env_info) {
128
9049
  Locker locker(isolate_);
129
9049
  Isolate::Scope isolate_scope(isolate_);
130
9049
  HandleScope handle_scope(isolate_);
131
132
4760
  int exit_code = 0;
133
  DeleteFnPtr<Environment, FreeEnvironment> env =
134
9049
      CreateMainEnvironment(&exit_code, env_info);
135
136
4760
  CHECK_NOT_NULL(env);
137
  {
138
4760
    Context::Scope context_scope(env->context());
139
140
4760
    if (exit_code == 0) {
141
4760
      LoadEnvironment(env.get(), StartExecutionCallback{});
142
143
8771
      exit_code = SpinEventLoop(env.get()).FromMaybe(1);
144
    }
145
146
4289
    ResetStdio();
147
148
    // TODO(addaleax): Neither NODE_SHARED_MODE nor HAVE_INSPECTOR really
149
    // make sense here.
150
#if HAVE_INSPECTOR && defined(__POSIX__) && !defined(NODE_SHARED_MODE)
151
  struct sigaction act;
152
4289
  memset(&act, 0, sizeof(act));
153
137248
  for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
154

132959
    if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
155
12867
      continue;
156
120092
    act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
157
120092
    CHECK_EQ(0, sigaction(nr, &act, nullptr));
158
  }
159
#endif
160
161
#if defined(LEAK_SANITIZER)
162
  __lsan_do_leak_check();
163
#endif
164
  }
165
166
8578
  return exit_code;
167
}
168
169
DeleteFnPtr<Environment, FreeEnvironment>
170
4760
NodeMainInstance::CreateMainEnvironment(int* exit_code,
171
                                        const EnvSerializeInfo* env_info) {
172
4760
  *exit_code = 0;  // Reset the exit code to 0
173
174
9520
  HandleScope handle_scope(isolate_);
175
176
  // TODO(addaleax): This should load a real per-Isolate option, currently
177
  // this is still effectively per-process.
178
4760
  if (isolate_data_->options()->track_heap_objects) {
179
1
    isolate_->GetHeapProfiler()->StartTrackingHeapObjects(true);
180
  }
181
182

4760
  CHECK_IMPLIES(deserialize_mode_, env_info != nullptr);
183
  Local<Context> context;
184
9520
  DeleteFnPtr<Environment, FreeEnvironment> env;
185
186
4760
  if (deserialize_mode_) {
187
9518
    env.reset(new Environment(isolate_data_.get(),
188
                              isolate_,
189
                              args_,
190
                              exec_args_,
191
                              env_info,
192
                              EnvironmentFlags::kDefaultFlags,
193
4759
                              {}));
194
9518
    context = Context::FromSnapshot(isolate_,
195
                                    kNodeContextIndex,
196
9518
                                    {DeserializeNodeInternalFields, env.get()})
197
4759
                  .ToLocalChecked();
198
199
4759
    CHECK(!context.IsEmpty());
200
    Context::Scope context_scope(context);
201
4759
    InitializeContextRuntime(context);
202
4759
    SetIsolateErrorHandlers(isolate_, {});
203
4759
    env->InitializeMainContext(context, env_info);
204
#if HAVE_INSPECTOR
205
4759
    env->InitializeInspector({});
206
#endif
207
4759
    env->DoneBootstrapping();
208
  } else {
209
1
    context = NewContext(isolate_);
210
1
    CHECK(!context.IsEmpty());
211
1
    Context::Scope context_scope(context);
212
2
    env.reset(new Environment(isolate_data_.get(),
213
                              context,
214
                              args_,
215
                              exec_args_,
216
                              nullptr,
217
                              EnvironmentFlags::kDefaultFlags,
218
1
                              {}));
219
#if HAVE_INSPECTOR
220
1
    env->InitializeInspector({});
221
#endif
222
2
    if (env->RunBootstrapping().IsEmpty()) {
223
      return nullptr;
224
    }
225
  }
226
227
4760
  CHECK(env->req_wrap_queue()->IsEmpty());
228
4760
  CHECK(env->handle_wrap_queue()->IsEmpty());
229
4760
  return env;
230
}
231
232

14538
}  // namespace node