GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/api/environment.cc Lines: 88 107 82.2 %
Date: 2019-02-23 22:23:05 Branches: 35 53 66.0 %

Line Branch Exec Source
1
#include "env.h"
2
#include "node.h"
3
#include "node_context_data.h"
4
#include "node_errors.h"
5
#include "node_internals.h"
6
#include "node_native_module.h"
7
#include "node_platform.h"
8
#include "node_process.h"
9
#include "node_v8_platform-inl.h"
10
#include "uv.h"
11
12
#ifdef NODE_ENABLE_VTUNE_PROFILING
13
#include "../deps/v8/src/third_party/vtune/v8-vtune.h"
14
#endif
15
16
namespace node {
17
using v8::Context;
18
using v8::Function;
19
using v8::HandleScope;
20
using v8::Isolate;
21
using v8::Local;
22
using v8::MaybeLocal;
23
using v8::Message;
24
using v8::MicrotasksPolicy;
25
using v8::ObjectTemplate;
26
using v8::String;
27
using v8::Value;
28
29
33
static bool AllowWasmCodeGenerationCallback(Local<Context> context,
30
                                            Local<String>) {
31
  Local<Value> wasm_code_gen =
32
66
      context->GetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration);
33

99
  return wasm_code_gen->IsUndefined() || wasm_code_gen->IsTrue();
34
}
35
36
32
static bool ShouldAbortOnUncaughtException(Isolate* isolate) {
37
32
  HandleScope scope(isolate);
38
32
  Environment* env = Environment::GetCurrent(isolate);
39
32
  return env != nullptr &&
40

95
         (env->is_main_thread() || !env->is_stopping_worker()) &&
41

158
         env->should_abort_on_uncaught_toggle()[0] &&
42
66
         !env->inside_should_not_abort_on_uncaught_scope();
43
}
44
45
1316
static void OnMessage(Local<Message> message, Local<Value> error) {
46
1316
  Isolate* isolate = message->GetIsolate();
47
1316
  switch (message->ErrorLevel()) {
48
    case Isolate::MessageErrorLevel::kMessageWarning: {
49
1
      Environment* env = Environment::GetCurrent(isolate);
50
1
      if (!env) {
51
        break;
52
      }
53
2
      Utf8Value filename(isolate, message->GetScriptOrigin().ResourceName());
54
      // (filename):(line) (message)
55
2
      std::stringstream warning;
56
1
      warning << *filename;
57
1
      warning << ":";
58
3
      warning << message->GetLineNumber(env->context()).FromMaybe(-1);
59
1
      warning << " ";
60
3
      v8::String::Utf8Value msg(isolate, message->Get());
61
1
      warning << *msg;
62
1
      USE(ProcessEmitWarningGeneric(env, warning.str().c_str(), "V8"));
63
2
      break;
64
    }
65
    case Isolate::MessageErrorLevel::kMessageError:
66
1315
      FatalException(isolate, error, message);
67
1174
      break;
68
  }
69
1175
}
70
71
931907
void* ArrayBufferAllocator::Allocate(size_t size) {
72

931907
  if (zero_fill_field_ || per_process::cli_options->zero_fill_all_buffers)
73
90298
    return UncheckedCalloc(size);
74
  else
75
841609
    return UncheckedMalloc(size);
76
}
77
78
4413
ArrayBufferAllocator* CreateArrayBufferAllocator() {
79
4413
  return new ArrayBufferAllocator();
80
}
81
82
4042
void FreeArrayBufferAllocator(ArrayBufferAllocator* allocator) {
83
4042
  delete allocator;
84
4042
}
85
86
4413
Isolate* NewIsolate(ArrayBufferAllocator* allocator, uv_loop_t* event_loop) {
87
4413
  Isolate::CreateParams params;
88
4413
  params.array_buffer_allocator = allocator;
89
90
4413
  double total_memory = uv_get_total_memory();
91
4413
  if (total_memory > 0) {
92
    // V8 defaults to 700MB or 1.4GB on 32 and 64 bit platforms respectively.
93
    // This default is based on browser use-cases. Tell V8 to configure the
94
    // heap based on the actual physical memory.
95
4413
    params.constraints.ConfigureDefaults(total_memory, 0);
96
  }
97
98
#ifdef NODE_ENABLE_VTUNE_PROFILING
99
  params.code_event_handler = vTune::GetVtuneCodeEventHandler();
100
#endif
101
102
4413
  Isolate* isolate = Isolate::Allocate();
103
4413
  if (isolate == nullptr) return nullptr;
104
105
  // Register the isolate on the platform before the isolate gets initialized,
106
  // so that the isolate can access the platform during initialization.
107
4413
  per_process::v8_platform.Platform()->RegisterIsolate(isolate, event_loop);
108
4413
  Isolate::Initialize(isolate, params);
109
110
  isolate->AddMessageListenerWithErrorLevel(
111
      OnMessage,
112
      Isolate::MessageErrorLevel::kMessageError |
113
4413
          Isolate::MessageErrorLevel::kMessageWarning);
114
4413
  isolate->SetAbortOnUncaughtExceptionCallback(ShouldAbortOnUncaughtException);
115
4413
  isolate->SetMicrotasksPolicy(MicrotasksPolicy::kExplicit);
116
4413
  isolate->SetFatalErrorHandler(OnFatalError);
117
4413
  isolate->SetAllowWasmCodeGenerationCallback(AllowWasmCodeGenerationCallback);
118
4413
  v8::CpuProfiler::UseDetailedSourcePositionsForProfiling(isolate);
119
120
4413
  return isolate;
121
}
122
123
4410
IsolateData* CreateIsolateData(Isolate* isolate,
124
                               uv_loop_t* loop,
125
                               MultiIsolatePlatform* platform,
126
                               ArrayBufferAllocator* allocator) {
127
  return new IsolateData(
128
      isolate,
129
      loop,
130
      platform,
131
4410
      allocator != nullptr ? allocator->zero_fill_field() : nullptr);
132
}
133
134
4040
void FreeIsolateData(IsolateData* isolate_data) {
135
4040
  delete isolate_data;
136
4040
}
137
138
Environment* CreateEnvironment(IsolateData* isolate_data,
139
                               Local<Context> context,
140
                               int argc,
141
                               const char* const* argv,
142
                               int exec_argc,
143
                               const char* const* exec_argv) {
144
  Isolate* isolate = context->GetIsolate();
145
  HandleScope handle_scope(isolate);
146
  Context::Scope context_scope(context);
147
  // TODO(addaleax): This is a much better place for parsing per-Environment
148
  // options than the global parse call.
149
  std::vector<std::string> args(argv, argv + argc);
150
  std::vector<std::string> exec_args(exec_argv, exec_argv + exec_argc);
151
  // TODO(addaleax): Provide more sensible flags, in an embedder-accessible way.
152
  Environment* env = new Environment(
153
      isolate_data,
154
      context,
155
      static_cast<Environment::Flags>(Environment::kIsMainThread |
156
                                      Environment::kOwnsProcessState |
157
                                      Environment::kOwnsInspector));
158
  env->Start(per_process::v8_is_profiling);
159
  env->ProcessCliArgs(args, exec_args);
160
  return env;
161
}
162
163
165
void FreeEnvironment(Environment* env) {
164
165
  env->RunCleanup();
165
165
  delete env;
166
165
}
167
168
Environment* GetCurrentEnvironment(Local<Context> context) {
169
  return Environment::GetCurrent(context);
170
}
171
172
MultiIsolatePlatform* GetMainThreadMultiIsolatePlatform() {
173
  return per_process::v8_platform.Platform();
174
}
175
176
MultiIsolatePlatform* CreatePlatform(
177
    int thread_pool_size,
178
    node::tracing::TracingController* tracing_controller) {
179
  return new NodePlatform(thread_pool_size, tracing_controller);
180
}
181
182
4244
MultiIsolatePlatform* InitializeV8Platform(int thread_pool_size) {
183
4244
  per_process::v8_platform.Initialize(thread_pool_size);
184
4244
  return per_process::v8_platform.Platform();
185
}
186
187
void FreePlatform(MultiIsolatePlatform* platform) {
188
  delete platform;
189
}
190
191
8958
Local<Context> NewContext(Isolate* isolate,
192
                          Local<ObjectTemplate> object_template) {
193
17916
  auto context = Context::New(isolate, nullptr, object_template);
194
8957
  if (context.IsEmpty()) return context;
195
8957
  HandleScope handle_scope(isolate);
196
197
  context->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration,
198
8956
                           True(isolate));
199
200
  {
201
    // Run lib/internal/bootstrap/context.js
202
    Context::Scope context_scope(context);
203
204
    std::vector<Local<String>> parameters = {
205
17912
        FIXED_ONE_BYTE_STRING(isolate, "global")};
206
26874
    Local<Value> arguments[] = {context->Global()};
207
    MaybeLocal<Function> maybe_fn =
208
        per_process::native_module_loader.LookupAndCompile(
209
8958
            context, "internal/bootstrap/context", &parameters, nullptr);
210
8958
    if (maybe_fn.IsEmpty()) {
211
      return Local<Context>();
212
    }
213
8958
    Local<Function> fn = maybe_fn.ToLocalChecked();
214
    MaybeLocal<Value> result =
215
17916
        fn->Call(context, Undefined(isolate), arraysize(arguments), arguments);
216
    // Execution failed during context creation.
217
    // TODO(joyeecheung): deprecate this signature and return a MaybeLocal.
218
8958
    if (result.IsEmpty()) {
219
4
      return Local<Context>();
220
8954
    }
221
  }
222
223
8954
  return context;
224
}
225
226
8
uv_loop_t* GetCurrentEventLoop(Isolate* isolate) {
227
8
  HandleScope handle_scope(isolate);
228
8
  Local<Context> context = isolate->GetCurrentContext();
229
8
  if (context.IsEmpty()) return nullptr;
230
8
  Environment* env = Environment::GetCurrent(context);
231
8
  if (env == nullptr) return nullptr;
232
8
  return env->event_loop();
233
}
234
235
}  // namespace node