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: 86 88 97.7 %
Date: 2020-06-24 22:13:30 Branches: 46 58 79.3 %

Line Branch Exec Source
1
#include <memory>
2
3
#include "node_main_instance.h"
4
#include "node_internals.h"
5
#include "node_options-inl.h"
6
#include "node_v8_platform-inl.h"
7
#include "util-inl.h"
8
#if defined(LEAK_SANITIZER)
9
#include <sanitizer/lsan_interface.h>
10
#endif
11
12
#if HAVE_INSPECTOR
13
#include "inspector/worker_inspector.h"  // ParentInspectorHandle
14
#endif
15
16
namespace node {
17
18
using v8::Context;
19
using v8::HandleScope;
20
using v8::Isolate;
21
using v8::Local;
22
using v8::Locker;
23
using v8::SealHandleScope;
24
25
1
NodeMainInstance::NodeMainInstance(Isolate* isolate,
26
                                   uv_loop_t* event_loop,
27
                                   MultiIsolatePlatform* platform,
28
                                   const std::vector<std::string>& args,
29
1
                                   const std::vector<std::string>& exec_args)
30
    : args_(args),
31
      exec_args_(exec_args),
32
      array_buffer_allocator_(nullptr),
33
      isolate_(isolate),
34
      platform_(platform),
35
      isolate_data_(nullptr),
36
      owns_isolate_(false),
37
1
      deserialize_mode_(false) {
38
  isolate_data_ =
39
1
      std::make_unique<IsolateData>(isolate_, event_loop, platform, nullptr);
40
41
1
  SetIsolateMiscHandlers(isolate_, {});
42
1
}
43
44
1
std::unique_ptr<NodeMainInstance> NodeMainInstance::Create(
45
    Isolate* isolate,
46
    uv_loop_t* event_loop,
47
    MultiIsolatePlatform* platform,
48
    const std::vector<std::string>& args,
49
    const std::vector<std::string>& exec_args) {
50
  return std::unique_ptr<NodeMainInstance>(
51
1
      new NodeMainInstance(isolate, event_loop, platform, args, exec_args));
52
}
53
54
4331
NodeMainInstance::NodeMainInstance(
55
    Isolate::CreateParams* params,
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
4331
    const std::vector<size_t>* per_isolate_data_indexes)
61
    : args_(args),
62
      exec_args_(exec_args),
63
      array_buffer_allocator_(ArrayBufferAllocator::Create()),
64
      isolate_(nullptr),
65
      platform_(platform),
66
      isolate_data_(nullptr),
67
4331
      owns_isolate_(true) {
68
4331
  params->array_buffer_allocator = array_buffer_allocator_.get();
69
4331
  isolate_ = Isolate::Allocate();
70
4331
  CHECK_NOT_NULL(isolate_);
71
  // Register the isolate on the platform before the isolate gets initialized,
72
  // so that the isolate can access the platform during initialization.
73
4331
  platform->RegisterIsolate(isolate_, event_loop);
74
4331
  SetIsolateCreateParamsForNode(params);
75
4331
  Isolate::Initialize(isolate_, *params);
76
77
4331
  deserialize_mode_ = per_isolate_data_indexes != nullptr;
78
  // If the indexes are not nullptr, we are not deserializing
79

4331
  CHECK_IMPLIES(deserialize_mode_, params->external_references != nullptr);
80
8662
  isolate_data_ = std::make_unique<IsolateData>(isolate_,
81
                                                event_loop,
82
                                                platform,
83
8662
                                                array_buffer_allocator_.get(),
84
4331
                                                per_isolate_data_indexes);
85
4331
  IsolateSettings s;
86
4331
  SetIsolateMiscHandlers(isolate_, s);
87
4331
  if (!deserialize_mode_) {
88
    // If in deserialize mode, delay until after the deserialization is
89
    // complete.
90
1
    SetIsolateErrorHandlers(isolate_, s);
91
  }
92
4331
}
93
94
1
void NodeMainInstance::Dispose() {
95
1
  CHECK(!owns_isolate_);
96
1
  platform_->DrainTasks(isolate_);
97
1
}
98
99


7728
NodeMainInstance::~NodeMainInstance() {
100
3864
  if (!owns_isolate_) {
101
1
    return;
102
  }
103
3863
  platform_->UnregisterIsolate(isolate_);
104
3863
  isolate_->Dispose();
105
3864
}
106
107
4331
int NodeMainInstance::Run() {
108
8194
  Locker locker(isolate_);
109
8194
  Isolate::Scope isolate_scope(isolate_);
110
8194
  HandleScope handle_scope(isolate_);
111
112
4331
  int exit_code = 0;
113
  DeleteFnPtr<Environment, FreeEnvironment> env =
114
8194
      CreateMainEnvironment(&exit_code);
115
116
4331
  CHECK_NOT_NULL(env);
117
4331
  Context::Scope context_scope(env->context());
118
119
4331
  if (exit_code == 0) {
120
4331
    LoadEnvironment(env.get());
121
122
4019
    env->set_trace_sync_io(env->options()->trace_sync_io);
123
124
    {
125
7891
      SealHandleScope seal(isolate_);
126
      bool more;
127
4019
      env->performance_state()->Mark(
128
4019
          node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START);
129
3888
      do {
130
4035
        uv_run(env->event_loop(), UV_RUN_DEFAULT);
131
132
3890
        per_process::v8_platform.DrainVMTasks(isolate_);
133
134
3889
        more = uv_loop_alive(env->event_loop());
135

3889
        if (more && !env->is_stopping()) continue;
136
137
3887
        if (!uv_loop_alive(env->event_loop())) {
138
3887
          EmitBeforeExit(env.get());
139
        }
140
141
        // Emit `beforeExit` if the loop became alive either after emitting
142
        // event, or after running some callbacks.
143
3886
        more = uv_loop_alive(env->event_loop());
144

3888
      } while (more == true && !env->is_stopping());
145
3872
      env->performance_state()->Mark(
146
3872
          node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT);
147
    }
148
149
3872
    env->set_trace_sync_io(false);
150
3872
    exit_code = EmitExit(env.get());
151
  }
152
153
3863
  ResetStdio();
154
155
  // TODO(addaleax): Neither NODE_SHARED_MODE nor HAVE_INSPECTOR really
156
  // make sense here.
157
#if HAVE_INSPECTOR && defined(__POSIX__) && !defined(NODE_SHARED_MODE)
158
  struct sigaction act;
159
3863
  memset(&act, 0, sizeof(act));
160
123616
  for (unsigned nr = 1; nr < kMaxSignal; nr += 1) {
161

119753
    if (nr == SIGKILL || nr == SIGSTOP || nr == SIGPROF)
162
11589
      continue;
163
108164
    act.sa_handler = (nr == SIGPIPE) ? SIG_IGN : SIG_DFL;
164
108164
    CHECK_EQ(0, sigaction(nr, &act, nullptr));
165
  }
166
#endif
167
168
#if defined(LEAK_SANITIZER)
169
  __lsan_do_leak_check();
170
#endif
171
172
7726
  return exit_code;
173
}
174
175
DeleteFnPtr<Environment, FreeEnvironment>
176
4331
NodeMainInstance::CreateMainEnvironment(int* exit_code) {
177
4331
  *exit_code = 0;  // Reset the exit code to 0
178
179
8662
  HandleScope handle_scope(isolate_);
180
181
  // TODO(addaleax): This should load a real per-Isolate option, currently
182
  // this is still effectively per-process.
183
4331
  if (isolate_data_->options()->track_heap_objects) {
184
1
    isolate_->GetHeapProfiler()->StartTrackingHeapObjects(true);
185
  }
186
187
  Local<Context> context;
188
  if (deserialize_mode_) {
189
    context =
190
8660
        Context::FromSnapshot(isolate_, kNodeContextIndex).ToLocalChecked();
191
4330
    InitializeContextRuntime(context);
192
4330
    SetIsolateErrorHandlers(isolate_, {});
193
  } else {
194
1
    context = NewContext(isolate_);
195
  }
196
197
4331
  CHECK(!context.IsEmpty());
198
  Context::Scope context_scope(context);
199
200
  DeleteFnPtr<Environment, FreeEnvironment> env { CreateEnvironment(
201
      isolate_data_.get(),
202
      context,
203
      args_,
204
      exec_args_,
205
4331
      EnvironmentFlags::kDefaultFlags) };
206
207
4331
  if (*exit_code != 0) {
208
    return env;
209
  }
210
211
4331
  if (env == nullptr) {
212
    *exit_code = 1;
213
  }
214
215
4331
  return env;
216
}
217
218
}  // namespace node