5 #include "v8-profiler.h" 8 #define getpid GetCurrentProcessId 19 using v8::FunctionTemplate;
20 using v8::HandleScope;
27 const char*
const* argv,
29 const char*
const* exec_argv,
30 bool start_profiler_idle_notifier) {
31 HandleScope handle_scope(isolate());
32 Context::Scope context_scope(context());
34 uv_check_init(event_loop(), immediate_check_handle());
35 uv_unref(reinterpret_cast<uv_handle_t*>(immediate_check_handle()));
37 uv_idle_init(event_loop(), immediate_idle_handle());
48 uv_prepare_init(event_loop(), &idle_prepare_handle_);
49 uv_check_init(event_loop(), &idle_check_handle_);
50 uv_unref(reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_));
51 uv_unref(reinterpret_cast<uv_handle_t*>(&idle_check_handle_));
53 uv_timer_init(event_loop(), destroy_ids_timer_handle());
55 auto close_and_finish = [](Environment* env, uv_handle_t* handle,
void* arg) {
58 uv_close(handle, [](uv_handle_t* handle) {
59 static_cast<Environment*
>(handle->data)->FinishHandleCleanup(handle);
63 RegisterHandleCleanup(
64 reinterpret_cast<uv_handle_t*>(immediate_check_handle()),
67 RegisterHandleCleanup(
68 reinterpret_cast<uv_handle_t*>(immediate_idle_handle()),
71 RegisterHandleCleanup(
72 reinterpret_cast<uv_handle_t*>(&idle_prepare_handle_),
75 RegisterHandleCleanup(
76 reinterpret_cast<uv_handle_t*>(&idle_check_handle_),
79 RegisterHandleCleanup(
80 reinterpret_cast<uv_handle_t*>(&destroy_ids_timer_handle_),
84 if (start_profiler_idle_notifier) {
85 StartProfilerIdleNotifier();
89 process_template->SetClassName(FIXED_ONE_BYTE_STRING(isolate(),
"process"));
92 process_template->GetFunction()->NewInstance(context()).ToLocalChecked();
93 set_process_object(process_object);
99 void Environment::CleanupHandles() {
100 while (HandleCleanup* hc = handle_cleanup_queue_.PopFront()) {
101 handle_cleanup_waiting_++;
102 hc->cb_(
this, hc->handle_, hc->arg_);
106 while (handle_cleanup_waiting_ != 0)
107 uv_run(event_loop(), UV_RUN_ONCE);
110 void Environment::StartProfilerIdleNotifier() {
111 uv_prepare_start(&idle_prepare_handle_, [](uv_prepare_t* handle) {
112 Environment* env = ContainerOf(&Environment::idle_prepare_handle_, handle);
113 env->isolate()->GetCpuProfiler()->SetIdle(
true);
116 uv_check_start(&idle_check_handle_, [](uv_check_t* handle) {
117 Environment* env = ContainerOf(&Environment::idle_check_handle_, handle);
118 env->isolate()->GetCpuProfiler()->SetIdle(
false);
122 void Environment::StopProfilerIdleNotifier() {
123 uv_prepare_stop(&idle_prepare_handle_);
124 uv_check_stop(&idle_check_handle_);
127 void Environment::PrintSyncTrace()
const {
131 HandleScope handle_scope(isolate());
132 Local<v8::StackTrace> stack =
133 StackTrace::CurrentStackTrace(isolate(), 10, StackTrace::kDetailed);
135 fprintf(stderr,
"(node:%d) WARNING: Detected use of sync API\n", getpid());
137 for (
int i = 0; i < stack->GetFrameCount() - 1; i++) {
138 Local<StackFrame> stack_frame = stack->GetFrame(i);
139 node::Utf8Value fn_name_s(isolate(), stack_frame->GetFunctionName());
140 node::Utf8Value script_name(isolate(), stack_frame->GetScriptName());
141 const int line_number = stack_frame->GetLineNumber();
142 const int column = stack_frame->GetColumn();
144 if (stack_frame->IsEval()) {
145 if (stack_frame->GetScriptId() == Message::kNoScriptIdInfo) {
146 fprintf(stderr,
" at [eval]:%i:%i\n", line_number, column);
149 " at [eval] (%s:%i:%i)\n",
157 if (fn_name_s.length() == 0) {
158 fprintf(stderr,
" at %s:%i:%i\n", *script_name, line_number, column);
161 " at %s (%s:%i:%i)\n",
171 void Environment::RunAtExitCallbacks() {
172 for (AtExitCallback at_exit : at_exit_functions_) {
173 at_exit.cb_(at_exit.arg_);
175 at_exit_functions_.clear();
179 at_exit_functions_.push_back(AtExitCallback{cb, arg});
183 auto it = std::find_if(
184 promise_hooks_.begin(), promise_hooks_.end(),
185 [&](
const PromiseHookCallback& hook) {
186 return hook.cb_ == fn && hook.arg_ == arg;
188 if (it != promise_hooks_.end()) {
192 promise_hooks_.push_back(PromiseHookCallback{fn, arg, 1});
194 if (promise_hooks_.size() == 1) {
195 isolate_->SetPromiseHook(EnvPromiseHook);
200 auto it = std::find_if(
201 promise_hooks_.begin(), promise_hooks_.end(),
202 [&](
const PromiseHookCallback& hook) {
203 return hook.cb_ == fn && hook.arg_ == arg;
206 if (it == promise_hooks_.end())
return false;
208 if (--it->enable_count_ > 0)
return true;
210 promise_hooks_.erase(it);
211 if (promise_hooks_.empty()) {
212 isolate_->SetPromiseHook(
nullptr);
218 void Environment::EnvPromiseHook(v8::PromiseHookType type,
219 v8::Local<v8::Promise> promise,
220 v8::Local<v8::Value> parent) {
221 Environment* env = Environment::GetCurrent(promise->CreationContext());
222 for (
const PromiseHookCallback& hook : env->promise_hooks_) {
223 hook.cb_(type, promise, parent, hook.arg_);
void AtExit(void(*cb)(void *arg), void *arg)
void AddPromiseHook(v8::Isolate *isolate, promise_hook_func fn, void *arg)
MaybeLocal< Object > New(Isolate *isolate, Local< String > string, enum encoding enc)
void(* promise_hook_func)(v8::PromiseHookType type, v8::Local< v8::Promise > promise, v8::Local< v8::Value > parent, void *arg)
void SetupProcessObject(Environment *env, int argc, const char *const *argv, int exec_argc, const char *const *exec_argv)
void LoadAsyncWrapperInfo(Environment *env)
int Start(Isolate *isolate, IsolateData *isolate_data, int argc, const char *const *argv, int exec_argc, const char *const *exec_argv)