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: 87 89 97.8 %
Date: 2020-05-27 22:15:15 Branches: 48 60 80.0 %

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::Object;
24
using v8::SealHandleScope;
25
26
1
NodeMainInstance::NodeMainInstance(Isolate* isolate,
27
                                   uv_loop_t* event_loop,
28
                                   MultiIsolatePlatform* platform,
29
                                   const std::vector<std::string>& args,
30
1
                                   const std::vector<std::string>& exec_args)
31
    : args_(args),
32
      exec_args_(exec_args),
33
      array_buffer_allocator_(nullptr),
34
      isolate_(isolate),
35
      platform_(platform),
36
      isolate_data_(nullptr),
37
      owns_isolate_(false),
38
1
      deserialize_mode_(false) {
39
  isolate_data_ =
40
1
      std::make_unique<IsolateData>(isolate_, event_loop, platform, nullptr);
41
42
1
  SetIsolateMiscHandlers(isolate_, {});
43
1
}
44
45
1
std::unique_ptr<NodeMainInstance> NodeMainInstance::Create(
46
    Isolate* isolate,
47
    uv_loop_t* event_loop,
48
    MultiIsolatePlatform* platform,
49
    const std::vector<std::string>& args,
50
    const std::vector<std::string>& exec_args) {
51
  return std::unique_ptr<NodeMainInstance>(
52
1
      new NodeMainInstance(isolate, event_loop, platform, args, exec_args));
53
}
54
55
4258
NodeMainInstance::NodeMainInstance(
56
    Isolate::CreateParams* params,
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
4258
    const std::vector<size_t>* per_isolate_data_indexes)
62
    : args_(args),
63
      exec_args_(exec_args),
64
      array_buffer_allocator_(ArrayBufferAllocator::Create()),
65
      isolate_(nullptr),
66
      platform_(platform),
67
      isolate_data_(nullptr),
68
4258
      owns_isolate_(true) {
69
4258
  params->array_buffer_allocator = array_buffer_allocator_.get();
70
4258
  isolate_ = Isolate::Allocate();
71
4258
  CHECK_NOT_NULL(isolate_);
72
  // Register the isolate on the platform before the isolate gets initialized,
73
  // so that the isolate can access the platform during initialization.
74
4258
  platform->RegisterIsolate(isolate_, event_loop);
75
4258
  SetIsolateCreateParamsForNode(params);
76
4258
  Isolate::Initialize(isolate_, *params);
77
78
4258
  deserialize_mode_ = per_isolate_data_indexes != nullptr;
79
  // If the indexes are not nullptr, we are not deserializing
80

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


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

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

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

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