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: 91 92 98.9 %
Date: 2019-10-08 22:34:21 Branches: 37 50 74.0 %

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

4924
  CHECK_IMPLIES(deserialize_mode_, params->external_references != nullptr);
72
  isolate_data_.reset(new IsolateData(isolate_,
73
                                      event_loop,
74
                                      platform,
75
4924
                                      array_buffer_allocator_.get(),
76
4924
                                      per_isolate_data_indexes));
77
4924
  SetIsolateUpForNode(isolate_, IsolateSettingCategories::kMisc);
78
4924
  if (!deserialize_mode_) {
79
    // If in deserialize mode, delay until after the deserialization is
80
    // complete.
81
1
    SetIsolateUpForNode(isolate_, IsolateSettingCategories::kErrorHandlers);
82
  }
83
4924
}
84
85
1
void NodeMainInstance::Dispose() {
86
1
  CHECK(!owns_isolate_);
87
1
  platform_->DrainTasks(isolate_);
88
1
}
89
90


9018
NodeMainInstance::~NodeMainInstance() {
91
4509
  if (!owns_isolate_) {
92
1
    return;
93
  }
94
4508
  isolate_->Dispose();
95
4508
  platform_->UnregisterIsolate(isolate_);
96
4508
}
97
98
4924
int NodeMainInstance::Run() {
99
4924
  Locker locker(isolate_);
100
9432
  Isolate::Scope isolate_scope(isolate_);
101
9432
  HandleScope handle_scope(isolate_);
102
103
4924
  int exit_code = 0;
104
9432
  std::unique_ptr<Environment> env = CreateMainEnvironment(&exit_code);
105
106
4924
  CHECK_NOT_NULL(env);
107
4924
  Context::Scope context_scope(env->context());
108
109
4924
  if (exit_code == 0) {
110
    {
111
4923
      AsyncCallbackScope callback_scope(env.get());
112
4923
      env->async_hooks()->push_async_ids(1, 0);
113
4923
      LoadEnvironment(env.get());
114
4665
      env->async_hooks()->pop_async_id(1);
115
    }
116
117
4664
    env->set_trace_sync_io(env->options()->trace_sync_io);
118
119
    {
120
4664
      SealHandleScope seal(isolate_);
121
      bool more;
122
      env->performance_state()->Mark(
123
4664
          node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START);
124
4526
      do {
125
4678
        uv_run(env->event_loop(), UV_RUN_DEFAULT);
126
127
4527
        per_process::v8_platform.DrainVMTasks(isolate_);
128
129
4527
        more = uv_loop_alive(env->event_loop());
130

4527
        if (more && !env->is_stopping()) continue;
131
132
4527
        env->RunBeforeExitCallbacks();
133
134
4527
        if (!uv_loop_alive(env->event_loop())) {
135
4527
          EmitBeforeExit(env.get());
136
        }
137
138
        // Emit `beforeExit` if the loop became alive either after emitting
139
        // event, or after running some callbacks.
140
4526
        more = uv_loop_alive(env->event_loop());
141

4526
      } while (more == true && !env->is_stopping());
142
      env->performance_state()->Mark(
143
4512
          node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_EXIT);
144
    }
145
146
4512
    env->set_trace_sync_io(false);
147
4512
    exit_code = EmitExit(env.get());
148
4507
    WaitForInspectorDisconnect(env.get());
149
  }
150
151
4508
  env->set_can_call_into_js(false);
152
4508
  env->stop_sub_worker_contexts();
153
4508
  ResetStdio();
154
4508
  env->RunCleanup();
155
4508
  RunAtExit(env.get());
156
157
4508
  per_process::v8_platform.DrainVMTasks(isolate_);
158
4508
  per_process::v8_platform.CancelVMTasks(isolate_);
159
160
#if defined(LEAK_SANITIZER)
161
  __lsan_do_leak_check();
162
#endif
163
164
9016
  return exit_code;
165
}
166
167
// TODO(joyeecheung): align this with the CreateEnvironment exposed in node.h
168
// and the environment creation routine in workers somehow.
169
4924
std::unique_ptr<Environment> NodeMainInstance::CreateMainEnvironment(
170
    int* exit_code) {
171
4924
  *exit_code = 0;  // Reset the exit code to 0
172
173
4924
  HandleScope handle_scope(isolate_);
174
175
  // TODO(addaleax): This should load a real per-Isolate option, currently
176
  // this is still effectively per-process.
177
4924
  if (isolate_data_->options()->track_heap_objects) {
178
1
    isolate_->GetHeapProfiler()->StartTrackingHeapObjects(true);
179
  }
180
181
  Local<Context> context;
182
4924
  if (deserialize_mode_) {
183
    context =
184
9846
        Context::FromSnapshot(isolate_, kNodeContextIndex).ToLocalChecked();
185
4923
    InitializeContextRuntime(context);
186
4923
    SetIsolateUpForNode(isolate_, IsolateSettingCategories::kErrorHandlers);
187
  } else {
188
1
    context = NewContext(isolate_);
189
  }
190
191
4924
  CHECK(!context.IsEmpty());
192
  Context::Scope context_scope(context);
193
194
  std::unique_ptr<Environment> env = std::make_unique<Environment>(
195
4924
      isolate_data_.get(),
196
      context,
197
      args_,
198
      exec_args_,
199
      static_cast<Environment::Flags>(Environment::kIsMainThread |
200
                                      Environment::kOwnsProcessState |
201
9848
                                      Environment::kOwnsInspector));
202
4924
  env->InitializeLibuv(per_process::v8_is_profiling);
203
4924
  env->InitializeDiagnostics();
204
205
  // TODO(joyeecheung): when we snapshot the bootstrapped context,
206
  // the inspector and diagnostics setup should after after deserialization.
207
#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
208
4924
  *exit_code = env->InitializeInspector(nullptr);
209
#endif
210
4924
  if (*exit_code != 0) {
211
1
    return env;
212
  }
213
214
9846
  if (env->RunBootstrapping().IsEmpty()) {
215
    *exit_code = 1;
216
  }
217
218
9847
  return env;
219
}
220
221
}  // namespace node