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: 107 113 94.7 %
Date: 2020-08-22 22:13:06 Branches: 60 80 75.0 %

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

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


7870
NodeMainInstance::~NodeMainInstance() {
120
3935
  if (!owns_isolate_) {
121
1
    return;
122
  }
123
3934
  platform_->UnregisterIsolate(isolate_);
124
3934
  isolate_->Dispose();
125
3935
}
126
127
4395
int NodeMainInstance::Run(const EnvSerializeInfo* env_info) {
128
8329
  Locker locker(isolate_);
129
8329
  Isolate::Scope isolate_scope(isolate_);
130
8329
  HandleScope handle_scope(isolate_);
131
132
4395
  int exit_code = 0;
133
  DeleteFnPtr<Environment, FreeEnvironment> env =
134
8329
      CreateMainEnvironment(&exit_code, env_info);
135
136
4395
  CHECK_NOT_NULL(env);
137
  {
138
4395
    Context::Scope context_scope(env->context());
139
140
4395
    if (exit_code == 0) {
141
4395
      LoadEnvironment(env.get());
142
143
4085
      env->set_trace_sync_io(env->options()->trace_sync_io);
144
145
      {
146
8028
        SealHandleScope seal(isolate_);
147
        bool more;
148
4085
        env->performance_state()->Mark(
149
4085
            node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START);
150
3958
        do {
151
4100
          uv_run(env->event_loop(), UV_RUN_DEFAULT);
152
153
3960
          per_process::v8_platform.DrainVMTasks(isolate_);
154
155
3959
          more = uv_loop_alive(env->event_loop());
156

3959
          if (more && !env->is_stopping()) continue;
157
158
3958
          if (!uv_loop_alive(env->event_loop())) {
159
3958
            EmitBeforeExit(env.get());
160
          }
161
162
          // Emit `beforeExit` if the loop became alive either after emitting
163
          // event, or after running some callbacks.
164
3957
          more = uv_loop_alive(env->event_loop());
165

3958
        } while (more == true && !env->is_stopping());
166
3943
        env->performance_state()->Mark(
167
3943
            node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT);
168
      }
169
170
3943
      env->set_trace_sync_io(false);
171
3943
      exit_code = EmitExit(env.get());
172
    }
173
174
3934
    ResetStdio();
175
176
    // TODO(addaleax): Neither NODE_SHARED_MODE nor HAVE_INSPECTOR really
177
    // make sense here.
178
#if HAVE_INSPECTOR && defined(__POSIX__) && !defined(NODE_SHARED_MODE)
179
  struct sigaction act;
180
3934
  memset(&act, 0, sizeof(act));
181
125888
  for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
182

121954
    if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
183
11802
      continue;
184
110152
    act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
185
110152
    CHECK_EQ(0, sigaction(nr, &act, nullptr));
186
  }
187
#endif
188
189
#if defined(LEAK_SANITIZER)
190
  __lsan_do_leak_check();
191
#endif
192
  }
193
194
7868
  return exit_code;
195
}
196
197
void DeserializeNodeInternalFields(Local<Object> holder,
198
                                   int index,
199
                                   v8::StartupData payload,
200
                                   void* env) {
201
  if (payload.raw_size == 0) {
202
    holder->SetAlignedPointerInInternalField(index, nullptr);
203
    return;
204
  }
205
  // No embedder object in the builtin snapshot yet.
206
  UNREACHABLE();
207
}
208
209
DeleteFnPtr<Environment, FreeEnvironment>
210
4395
NodeMainInstance::CreateMainEnvironment(int* exit_code,
211
                                        const EnvSerializeInfo* env_info) {
212
4395
  *exit_code = 0;  // Reset the exit code to 0
213
214
8790
  HandleScope handle_scope(isolate_);
215
216
  // TODO(addaleax): This should load a real per-Isolate option, currently
217
  // this is still effectively per-process.
218
4395
  if (isolate_data_->options()->track_heap_objects) {
219
1
    isolate_->GetHeapProfiler()->StartTrackingHeapObjects(true);
220
  }
221
222

4395
  CHECK_IMPLIES(deserialize_mode_, env_info != nullptr);
223
  Local<Context> context;
224
8790
  DeleteFnPtr<Environment, FreeEnvironment> env;
225
226
4395
  if (deserialize_mode_) {
227
8788
    env.reset(new Environment(isolate_data_.get(),
228
                              isolate_,
229
                              args_,
230
                              exec_args_,
231
                              env_info,
232
                              EnvironmentFlags::kDefaultFlags,
233
4394
                              {}));
234
8788
    context = Context::FromSnapshot(isolate_,
235
                                    kNodeContextIndex,
236
8788
                                    {DeserializeNodeInternalFields, env.get()})
237
4394
                  .ToLocalChecked();
238
239
4394
    InitializeContextRuntime(context);
240
4394
    SetIsolateErrorHandlers(isolate_, {});
241
  } else {
242
1
    context = NewContext(isolate_);
243
    Context::Scope context_scope(context);
244
2
    env.reset(new Environment(isolate_data_.get(),
245
                              context,
246
                              args_,
247
                              exec_args_,
248
                              nullptr,
249
                              EnvironmentFlags::kDefaultFlags,
250
1
                              {}));
251
  }
252
253
4395
  CHECK(!context.IsEmpty());
254
  Context::Scope context_scope(context);
255
256
4395
  env->InitializeMainContext(context, env_info);
257
258
#if HAVE_INSPECTOR
259
4395
  env->InitializeInspector({});
260
#endif
261
262

4396
  if (!deserialize_mode_ && env->RunBootstrapping().IsEmpty()) {
263
    return nullptr;
264
  }
265
266
4395
  CHECK(env->req_wrap_queue()->IsEmpty());
267
4395
  CHECK(env->handle_wrap_queue()->IsEmpty());
268
4395
  env->set_has_run_bootstrapping_code(true);
269
4395
  return env;
270
}
271
272

13395
}  // namespace node