From 337ebfcd537dc1400da7bfa1d132c134bd4d4ea0 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sun, 26 Dec 2021 20:51:42 +0100 Subject: [PATCH] src: split out async stack corruption detection from inline fn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is fairly expensive code that unnecessarily bloats the contents of the inline function. PR-URL: https://github.com/nodejs/node/pull/41331 Reviewed-By: Gerhard Stöbich Reviewed-By: Tobias Nießen Reviewed-By: Darshan Sen --- src/env-inl.h | 18 ++++-------------- src/env.cc | 15 +++++++++++++++ src/env.h | 2 ++ 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/env-inl.h b/src/env-inl.h index 9b2c536af96980..e679780900abc9 100644 --- a/src/env-inl.h +++ b/src/env-inl.h @@ -166,25 +166,15 @@ inline void AsyncHooks::push_async_context(double async_id, inline bool AsyncHooks::pop_async_context(double async_id) { // In case of an exception then this may have already been reset, if the // stack was multiple MakeCallback()'s deep. - if (fields_[kStackLength] == 0) return false; + if (UNLIKELY(fields_[kStackLength] == 0)) return false; // Ask for the async_id to be restored as a check that the stack // hasn't been corrupted. // Since async_hooks is experimental, do only perform the check // when async_hooks is enabled. - if (fields_[kCheck] > 0 && async_id_fields_[kExecutionAsyncId] != async_id) { - fprintf(stderr, - "Error: async hook stack has become corrupted (" - "actual: %.f, expected: %.f)\n", - async_id_fields_.GetValue(kExecutionAsyncId), - async_id); - DumpBacktrace(stderr); - fflush(stderr); - if (!env()->abort_on_uncaught_exception()) - exit(1); - fprintf(stderr, "\n"); - fflush(stderr); - ABORT_NO_BACKTRACE(); + if (UNLIKELY(fields_[kCheck] > 0 && + async_id_fields_[kExecutionAsyncId] != async_id)) { + FailWithCorruptedAsyncStack(async_id); } uint32_t offset = fields_[kStackLength] - 1; diff --git a/src/env.cc b/src/env.cc index 3f76c4bb770648..e3e06598a57529 100644 --- a/src/env.cc +++ b/src/env.cc @@ -1196,6 +1196,21 @@ void AsyncHooks::grow_async_ids_stack() { async_ids_stack_.GetJSArray()).Check(); } +void AsyncHooks::FailWithCorruptedAsyncStack(double expected_async_id) { + fprintf(stderr, + "Error: async hook stack has become corrupted (" + "actual: %.f, expected: %.f)\n", + async_id_fields_.GetValue(kExecutionAsyncId), + expected_async_id); + DumpBacktrace(stderr); + fflush(stderr); + if (!env()->abort_on_uncaught_exception()) + exit(1); + fprintf(stderr, "\n"); + fflush(stderr); + ABORT_NO_BACKTRACE(); +} + void Environment::Exit(int exit_code) { if (options()->trace_exit) { HandleScope handle_scope(isolate()); diff --git a/src/env.h b/src/env.h index 63724b07a6b3a9..5af2eaa6669f0b 100644 --- a/src/env.h +++ b/src/env.h @@ -774,6 +774,8 @@ class AsyncHooks : public MemoryRetainer { friend class Environment; // So we can call the constructor. explicit AsyncHooks(v8::Isolate* isolate, const SerializeInfo* info); + [[noreturn]] void FailWithCorruptedAsyncStack(double expected_async_id); + // Stores the ids of the current execution context stack. AliasedFloat64Array async_ids_stack_; // Attached to a Uint32Array that tracks the number of active hooks for