From e780bb8e5ee9f33873ec50c5954f8ed6a7c0c34f Mon Sep 17 00:00:00 2001 From: Stephen Belanger Date: Sun, 15 Dec 2019 10:35:07 -0800 Subject: [PATCH] store resource on AsyncHooks object --- src/async_wrap.cc | 18 ++++++++---------- src/env-inl.h | 15 ++++++++++++++- src/env.h | 7 +++++++ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/async_wrap.cc b/src/async_wrap.cc index 693b6179f3bc3a..242c5440869e6b 100644 --- a/src/async_wrap.cc +++ b/src/async_wrap.cc @@ -28,10 +28,6 @@ #include "v8.h" -// TODO(mcollina): should this be moved in a more public space? -// embedders will not be able to use this field -#define EXECUTION_RESOURCE_FIELD 10 - using v8::Context; using v8::DontDelete; using v8::EscapableHandleScope; @@ -152,7 +148,7 @@ void AsyncWrap::EmitTraceEventBefore() { void AsyncWrap::EmitBefore(Environment* env, double async_id, v8::Local resource) { v8::Local context = env->isolate()->GetCurrentContext(); - context->SetEmbedderData(EXECUTION_RESOURCE_FIELD, resource); + env->async_hooks()->set_execution_async_resource(resource); Emit(env, async_id, AsyncHooks::kBefore, env->async_hooks_before_function()); @@ -184,7 +180,7 @@ void AsyncWrap::EmitAfter(Environment* env, double async_id) { Emit(env, async_id, AsyncHooks::kAfter, env->async_hooks_after_function()); - context->SetEmbedderData(EXECUTION_RESOURCE_FIELD, v8::Null(isolate)); + env->async_hooks()->clear_execution_async_resource(); } class PromiseWrap : public AsyncWrap { @@ -270,7 +266,7 @@ static void PromiseHook(PromiseHookType type, Local promise, // needed for async functions :/ // the top level will not emit before and after - env->context()->SetEmbedderData(EXECUTION_RESOURCE_FIELD, wrap->object()); + env->async_hooks()->set_execution_async_resource(wrap->object()); } } @@ -401,14 +397,16 @@ static void RegisterDestroyHook(const FunctionCallbackInfo& args) { static void GetExecutionAsyncResource(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); + Environment* env = Environment::GetCurrent(args); v8::Local context = isolate->GetCurrentContext(); - args.GetReturnValue().Set(context->GetEmbedderData(EXECUTION_RESOURCE_FIELD)); + args.GetReturnValue().Set(env->async_hooks()->get_execution_async_resource()); } static void SetExecutionAsyncResource(const FunctionCallbackInfo& args) { Isolate* isolate = args.GetIsolate(); + Environment* env = Environment::GetCurrent(args); v8::Local context = isolate->GetCurrentContext(); - context->SetEmbedderData(EXECUTION_RESOURCE_FIELD, args[0]); + env->async_hooks()->set_execution_async_resource(args[0]); } void AsyncWrap::GetAsyncId(const FunctionCallbackInfo& args) { @@ -502,7 +500,7 @@ void AsyncWrap::Initialize(Local target, env->SetMethod(target, "setExecutionAsyncResource", SetExecutionAsyncResource); - context->SetEmbedderData(EXECUTION_RESOURCE_FIELD, v8::Null(isolate)); + env->async_hooks()->clear_execution_async_resource(); PropertyAttribute ReadOnlyDontDelete = static_cast(ReadOnly | DontDelete); diff --git a/src/env-inl.h b/src/env-inl.h index cd111bc2641890..6591add4ca060c 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -67,7 +67,8 @@ inline MultiIsolatePlatform* IsolateData::platform() const { inline AsyncHooks::AsyncHooks() : async_ids_stack_(env()->isolate(), 16 * 2), fields_(env()->isolate(), kFieldsCount), - async_id_fields_(env()->isolate(), kUidFieldsCount) { + async_id_fields_(env()->isolate(), kUidFieldsCount), + execution_async_resource_(env()->isolate(), v8::Null(env()->isolate())) { v8::HandleScope handle_scope(env()->isolate()); // Always perform async_hooks checks, not just when async_hooks is enabled. @@ -206,6 +207,18 @@ inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() { old_default_trigger_async_id_; } +inline void AsyncHooks::set_execution_async_resource( + v8::Local execution_async_resource) { + execution_async_resource_.Reset(env()->isolate(), execution_async_resource); +} + +inline v8::Local AsyncHooks::get_execution_async_resource() { + return execution_async_resource_.Get(env()->isolate()); +} + +inline void AsyncHooks::clear_execution_async_resource() { + execution_async_resource_.Reset(); +} Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) { return ContainerOf(&Environment::async_hooks_, hooks); diff --git a/src/env.h b/src/env.h index c86f0f7de7bda0..8dd75f9f910c20 100644 --- a/src/env.h +++ b/src/env.h @@ -684,6 +684,11 @@ class AsyncHooks : public MemoryRetainer { inline bool pop_async_id(double async_id); inline void clear_async_id_stack(); // Used in fatal exceptions. + inline void set_execution_async_resource( + v8::Local execution_async_resource_); + inline v8::Local get_execution_async_resource(); + inline void clear_execution_async_resource(); + AsyncHooks(const AsyncHooks&) = delete; AsyncHooks& operator=(const AsyncHooks&) = delete; AsyncHooks(AsyncHooks&&) = delete; @@ -726,6 +731,8 @@ class AsyncHooks : public MemoryRetainer { AliasedFloat64Array async_id_fields_; void grow_async_ids_stack(); + + v8::Persistent execution_async_resource_; }; class ImmediateInfo : public MemoryRetainer {