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: 89 90 98.9 %
Date: 2019-08-17 22:35:23 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
7
namespace node {
8
9
using v8::Context;
10
using v8::HandleScope;
11
using v8::Isolate;
12
using v8::Local;
13
using v8::Locker;
14
using v8::SealHandleScope;
15
16
1
NodeMainInstance::NodeMainInstance(Isolate* isolate,
17
                                   uv_loop_t* event_loop,
18
                                   MultiIsolatePlatform* platform,
19
                                   const std::vector<std::string>& args,
20
                                   const std::vector<std::string>& exec_args)
21
    : args_(args),
22
      exec_args_(exec_args),
23
      array_buffer_allocator_(nullptr),
24
      isolate_(isolate),
25
      platform_(platform),
26
      isolate_data_(nullptr),
27
      owns_isolate_(false),
28
1
      deserialize_mode_(false) {
29
1
  isolate_data_.reset(new IsolateData(isolate_, event_loop, platform, nullptr));
30
1
  SetIsolateUpForNode(isolate_, IsolateSettingCategories::kMisc);
31
1
}
32
33
1
std::unique_ptr<NodeMainInstance> NodeMainInstance::Create(
34
    Isolate* isolate,
35
    uv_loop_t* event_loop,
36
    MultiIsolatePlatform* platform,
37
    const std::vector<std::string>& args,
38
    const std::vector<std::string>& exec_args) {
39
  return std::unique_ptr<NodeMainInstance>(
40
1
      new NodeMainInstance(isolate, event_loop, platform, args, exec_args));
41
}
42
43
4956
NodeMainInstance::NodeMainInstance(
44
    Isolate::CreateParams* params,
45
    uv_loop_t* event_loop,
46
    MultiIsolatePlatform* platform,
47
    const std::vector<std::string>& args,
48
    const std::vector<std::string>& exec_args,
49
    const std::vector<size_t>* per_isolate_data_indexes)
50
    : args_(args),
51
      exec_args_(exec_args),
52
      array_buffer_allocator_(ArrayBufferAllocator::Create()),
53
      isolate_(nullptr),
54
      platform_(platform),
55
      isolate_data_(nullptr),
56
4956
      owns_isolate_(true) {
57
4956
  params->array_buffer_allocator = array_buffer_allocator_.get();
58
4956
  isolate_ = Isolate::Allocate();
59
4956
  CHECK_NOT_NULL(isolate_);
60
  // Register the isolate on the platform before the isolate gets initialized,
61
  // so that the isolate can access the platform during initialization.
62
4956
  platform->RegisterIsolate(isolate_, event_loop);
63
4956
  SetIsolateCreateParamsForNode(params);
64
4956
  Isolate::Initialize(isolate_, *params);
65
66
4956
  deserialize_mode_ = per_isolate_data_indexes != nullptr;
67
  // If the indexes are not nullptr, we are not deserializing
68

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


9108
NodeMainInstance::~NodeMainInstance() {
88
4554
  if (!owns_isolate_) {
89
1
    return;
90
  }
91
4553
  isolate_->Dispose();
92
4553
  platform_->UnregisterIsolate(isolate_);
93
4553
}
94
95
4956
int NodeMainInstance::Run() {
96
4956
  Locker locker(isolate_);
97
9509
  Isolate::Scope isolate_scope(isolate_);
98
9509
  HandleScope handle_scope(isolate_);
99
100
4956
  int exit_code = 0;
101
9509
  std::unique_ptr<Environment> env = CreateMainEnvironment(&exit_code);
102
103
4956
  CHECK_NOT_NULL(env);
104
4956
  Context::Scope context_scope(env->context());
105
106
4956
  if (exit_code == 0) {
107
    {
108
4955
      AsyncCallbackScope callback_scope(env.get());
109
4955
      env->async_hooks()->push_async_ids(1, 0);
110
4955
      LoadEnvironment(env.get());
111
4704
      env->async_hooks()->pop_async_id(1);
112
    }
113
114
4703
    env->set_trace_sync_io(env->options()->trace_sync_io);
115
116
    {
117
4703
      SealHandleScope seal(isolate_);
118
      bool more;
119
      env->performance_state()->Mark(
120
4703
          node::performance::NODE_PERFORMANCE_MILESTONE_LOOP_START);
121
4571
      do {
122
4717
        uv_run(env->event_loop(), UV_RUN_DEFAULT);
123
124
4572
        per_process::v8_platform.DrainVMTasks(isolate_);
125
126
4572
        more = uv_loop_alive(env->event_loop());
127

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

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