summaryrefslogtreecommitdiff
path: root/src/env.cc
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2016-06-01 10:54:42 +0200
committerBen Noordhuis <info@bnoordhuis.nl>2016-06-02 19:38:12 +0200
commit58cec4e85b24cc322b2a60954dfaaad20ee68823 (patch)
treeb4345dbe794343c2cba03910e662b55e21936e07 /src/env.cc
parent138c7af42a8f8dd0b8f9b69ddc406eba16c71874 (diff)
downloadandroid-node-v8-58cec4e85b24cc322b2a60954dfaaad20ee68823.tar.gz
android-node-v8-58cec4e85b24cc322b2a60954dfaaad20ee68823.tar.bz2
android-node-v8-58cec4e85b24cc322b2a60954dfaaad20ee68823.zip
src: move env init logic into Environment class
PR-URL: https://github.com/nodejs/node/pull/7090 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Diffstat (limited to 'src/env.cc')
-rw-r--r--src/env.cc90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/env.cc b/src/env.cc
index 12be4866aa..2598e775e8 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -1,6 +1,8 @@
#include "env.h"
#include "env-inl.h"
+#include "async-wrap.h"
#include "v8.h"
+#include "v8-profiler.h"
#if defined(_MSC_VER)
#define getpid GetCurrentProcessId
@@ -12,6 +14,8 @@
namespace node {
+using v8::Context;
+using v8::FunctionTemplate;
using v8::HandleScope;
using v8::Local;
using v8::Message;
@@ -19,6 +23,92 @@ using v8::StackFrame;
using v8::StackTrace;
using v8::Value;
+void Environment::Start(int argc,
+ const char* const* argv,
+ int exec_argc,
+ const char* const* exec_argv,
+ bool start_profiler_idle_notifier) {
+ HandleScope handle_scope(isolate());
+ Context::Scope context_scope(context());
+
+ isolate()->SetAutorunMicrotasks(false);
+
+ uv_check_init(event_loop(), immediate_check_handle());
+ uv_unref(reinterpret_cast<uv_handle_t*>(immediate_check_handle()));
+
+ uv_idle_init(event_loop(), immediate_idle_handle());
+
+ // Inform V8's CPU profiler when we're idle. The profiler is sampling-based
+ // but not all samples are created equal; mark the wall clock time spent in
+ // epoll_wait() and friends so profiling tools can filter it out. The samples
+ // still end up in v8.log but with state=IDLE rather than state=EXTERNAL.
+ // TODO(bnoordhuis) Depends on a libuv implementation detail that we should
+ // probably fortify in the API contract, namely that the last started prepare
+ // or check watcher runs first. It's not 100% foolproof; if an add-on starts
+ // a prepare or check watcher after us, any samples attributed to its callback
+ // will be recorded with state=IDLE.
+ uv_prepare_init(event_loop(), &idle_prepare_handle_);
+ uv_check_init(event_loop(), &idle_check_handle_);
+ uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_));
+ uv_unref(reinterpret_cast<uv_handle_t*>(&idle_check_handle_));
+
+ auto close_and_finish = [](Environment* env, uv_handle_t* handle, void* arg) {
+ handle->data = env;
+
+ uv_close(handle, [](uv_handle_t* handle) {
+ static_cast<Environment*>(handle->data)->FinishHandleCleanup(handle);
+ });
+ };
+
+ RegisterHandleCleanup(
+ reinterpret_cast<uv_handle_t*>(immediate_check_handle()),
+ close_and_finish,
+ nullptr);
+ RegisterHandleCleanup(
+ reinterpret_cast<uv_handle_t*>(immediate_idle_handle()),
+ close_and_finish,
+ nullptr);
+ RegisterHandleCleanup(
+ reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_),
+ close_and_finish,
+ nullptr);
+ RegisterHandleCleanup(
+ reinterpret_cast<uv_handle_t*>(&idle_check_handle_),
+ close_and_finish,
+ nullptr);
+
+ if (start_profiler_idle_notifier) {
+ StartProfilerIdleNotifier();
+ }
+
+ auto process_template = FunctionTemplate::New(isolate());
+ process_template->SetClassName(FIXED_ONE_BYTE_STRING(isolate(), "process"));
+
+ auto process_object =
+ process_template->GetFunction()->NewInstance(context()).ToLocalChecked();
+ set_process_object(process_object);
+
+ SetupProcessObject(this, argc, argv, exec_argc, exec_argv);
+ LoadAsyncWrapperInfo(this);
+}
+
+void Environment::StartProfilerIdleNotifier() {
+ uv_prepare_start(&idle_prepare_handle_, [](uv_prepare_t* handle) {
+ Environment* env = ContainerOf(&Environment::idle_prepare_handle_, handle);
+ env->isolate()->GetCpuProfiler()->SetIdle(true);
+ });
+
+ uv_check_start(&idle_check_handle_, [](uv_check_t* handle) {
+ Environment* env = ContainerOf(&Environment::idle_check_handle_, handle);
+ env->isolate()->GetCpuProfiler()->SetIdle(false);
+ });
+}
+
+void Environment::StopProfilerIdleNotifier() {
+ uv_prepare_stop(&idle_prepare_handle_);
+ uv_check_stop(&idle_check_handle_);
+}
+
void Environment::PrintSyncTrace() const {
if (!trace_sync_io_)
return;