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: 93 99 93.9 %
Date: 2020-11-20 19:51:53 Branches: 49 66 74.2 %

Line Branch Exec Source
1
#include "node_main_instance.h"
2
#include <iostream>
3
#include <memory>
4
#include "debug_utils-inl.h"
5
#include "node_external_reference.h"
6
#include "node_internals.h"
7
#include "node_options-inl.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
using v8::Object;
26
27
4678
std::unique_ptr<ExternalReferenceRegistry> NodeMainInstance::registry_ =
28
    nullptr;
29
8
NodeMainInstance::NodeMainInstance(Isolate* isolate,
30
                                   uv_loop_t* event_loop,
31
                                   MultiIsolatePlatform* platform,
32
                                   const std::vector<std::string>& args,
33
8
                                   const std::vector<std::string>& exec_args)
34
    : args_(args),
35
      exec_args_(exec_args),
36
      array_buffer_allocator_(nullptr),
37
      isolate_(isolate),
38
      platform_(platform),
39
      isolate_data_(nullptr),
40
      owns_isolate_(false),
41
8
      deserialize_mode_(false) {
42
  isolate_data_ =
43
8
      std::make_unique<IsolateData>(isolate_, event_loop, platform, nullptr);
44
45
8
  SetIsolateMiscHandlers(isolate_, {});
46
8
}
47
48
4601
const std::vector<intptr_t>& NodeMainInstance::CollectExternalReferences() {
49
  // Cannot be called more than once.
50
4601
  CHECK_NULL(registry_);
51
4601
  registry_.reset(new ExternalReferenceRegistry());
52
4601
  return registry_->external_references();
53
}
54
55
8
std::unique_ptr<NodeMainInstance> NodeMainInstance::Create(
56
    Isolate* isolate,
57
    uv_loop_t* event_loop,
58
    MultiIsolatePlatform* platform,
59
    const std::vector<std::string>& args,
60
    const std::vector<std::string>& exec_args) {
61
  return std::unique_ptr<NodeMainInstance>(
62
8
      new NodeMainInstance(isolate, event_loop, platform, args, exec_args));
63
}
64
65
4594
NodeMainInstance::NodeMainInstance(
66
    Isolate::CreateParams* params,
67
    uv_loop_t* event_loop,
68
    MultiIsolatePlatform* platform,
69
    const std::vector<std::string>& args,
70
    const std::vector<std::string>& exec_args,
71
4594
    const std::vector<size_t>* per_isolate_data_indexes)
72
    : args_(args),
73
      exec_args_(exec_args),
74
      array_buffer_allocator_(ArrayBufferAllocator::Create()),
75
      isolate_(nullptr),
76
      platform_(platform),
77
      isolate_data_(nullptr),
78
4594
      owns_isolate_(true) {
79
4594
  params->array_buffer_allocator = array_buffer_allocator_.get();
80
4594
  deserialize_mode_ = per_isolate_data_indexes != nullptr;
81
4594
  if (deserialize_mode_) {
82
    // TODO(joyeecheung): collect external references and set it in
83
    // params.external_references.
84
    const std::vector<intptr_t>& external_references =
85
4593
        CollectExternalReferences();
86
4593
    params->external_references = external_references.data();
87
  }
88
89
4594
  isolate_ = Isolate::Allocate();
90
4594
  CHECK_NOT_NULL(isolate_);
91
  // Register the isolate on the platform before the isolate gets initialized,
92
  // so that the isolate can access the platform during initialization.
93
4594
  platform->RegisterIsolate(isolate_, event_loop);
94
4594
  SetIsolateCreateParamsForNode(params);
95
4594
  Isolate::Initialize(isolate_, *params);
96
97
  // If the indexes are not nullptr, we are not deserializing
98

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


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

125147
    if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
156
12111
      continue;
157
113036
    act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
158
113036
    CHECK_EQ(0, sigaction(nr, &act, nullptr));
159
  }
160
#endif
161
162
#if defined(LEAK_SANITIZER)
163
  __lsan_do_leak_check();
164
#endif
165
  }
166
167
8074
  return exit_code;
168
}
169
170
void DeserializeNodeInternalFields(Local<Object> holder,
171
                                   int index,
172
                                   v8::StartupData payload,
173
                                   void* env) {
174
  if (payload.raw_size == 0) {
175
    holder->SetAlignedPointerInInternalField(index, nullptr);
176
    return;
177
  }
178
  // No embedder object in the builtin snapshot yet.
179
  UNREACHABLE();
180
}
181
182
DeleteFnPtr<Environment, FreeEnvironment>
183
4594
NodeMainInstance::CreateMainEnvironment(int* exit_code,
184
                                        const EnvSerializeInfo* env_info) {
185
4594
  *exit_code = 0;  // Reset the exit code to 0
186
187
9188
  HandleScope handle_scope(isolate_);
188
189
  // TODO(addaleax): This should load a real per-Isolate option, currently
190
  // this is still effectively per-process.
191
4594
  if (isolate_data_->options()->track_heap_objects) {
192
1
    isolate_->GetHeapProfiler()->StartTrackingHeapObjects(true);
193
  }
194
195

4594
  CHECK_IMPLIES(deserialize_mode_, env_info != nullptr);
196
  Local<Context> context;
197
4594
  DeleteFnPtr<Environment, FreeEnvironment> env;
198
199
4594
  if (deserialize_mode_) {
200
9186
    env.reset(new Environment(isolate_data_.get(),
201
                              isolate_,
202
                              args_,
203
                              exec_args_,
204
                              env_info,
205
                              EnvironmentFlags::kDefaultFlags,
206
4593
                              {}));
207
9186
    context = Context::FromSnapshot(isolate_,
208
                                    kNodeContextIndex,
209
9186
                                    {DeserializeNodeInternalFields, env.get()})
210
4593
                  .ToLocalChecked();
211
212
4593
    InitializeContextRuntime(context);
213
4593
    SetIsolateErrorHandlers(isolate_, {});
214
  } else {
215
1
    context = NewContext(isolate_);
216
    Context::Scope context_scope(context);
217
2
    env.reset(new Environment(isolate_data_.get(),
218
                              context,
219
                              args_,
220
                              exec_args_,
221
                              nullptr,
222
                              EnvironmentFlags::kDefaultFlags,
223
1
                              {}));
224
  }
225
226
4594
  CHECK(!context.IsEmpty());
227
  Context::Scope context_scope(context);
228
229
4594
  env->InitializeMainContext(context, env_info);
230
231
#if HAVE_INSPECTOR
232
4594
  env->InitializeInspector({});
233
#endif
234
235

4595
  if (!deserialize_mode_ && env->RunBootstrapping().IsEmpty()) {
236
    return nullptr;
237
  }
238
239
4594
  CHECK(env->req_wrap_queue()->IsEmpty());
240
4594
  CHECK(env->handle_wrap_queue()->IsEmpty());
241
4594
  env->set_has_run_bootstrapping_code(true);
242
4594
  return env;
243
}
244
245

14034
}  // namespace node