diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2016-06-01 10:54:42 +0200 |
---|---|---|
committer | Ben Noordhuis <info@bnoordhuis.nl> | 2016-06-02 19:38:12 +0200 |
commit | 58cec4e85b24cc322b2a60954dfaaad20ee68823 (patch) | |
tree | b4345dbe794343c2cba03910e662b55e21936e07 /src/env.cc | |
parent | 138c7af42a8f8dd0b8f9b69ddc406eba16c71874 (diff) | |
download | android-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.cc | 90 |
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; |