File 1052-erts-Optimize-the-normal-case-where-ErtsTracer-is-a-.patch of Package erlang
From 41421193d7e3c9093368bab040a1a4ca1cf2f3dc Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Wed, 10 Jul 2024 19:53:26 +0200
Subject: [PATCH 2/6] erts: Optimize the normal case where ErtsTracer is a
local pid
Instead of [erl_tracer | pid] just store the pid.
---
erts/emulator/beam/erl_ptab.h | 4 ++--
erts/emulator/beam/erl_trace.c | 24 ++++++++++++++++++------
erts/emulator/beam/erl_trace.h | 1 +
erts/emulator/beam/sys.h | 5 +++--
4 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/erts/emulator/beam/erl_ptab.h b/erts/emulator/beam/erl_ptab.h
index d5e5da8181..8753ae9365 100644
--- a/erts/emulator/beam/erl_ptab.h
+++ b/erts/emulator/beam/erl_ptab.h
@@ -49,8 +49,8 @@ typedef struct ErtsTracee_ {
ErtsTracerRef *first_ref;
} ErtsTracee;
-#define ERTS_TRACER_MODULE(T) (CAR(list_val(T)))
-#define ERTS_TRACER_STATE(T) (CDR(list_val(T)))
+#define ERTS_TRACER_MODULE(T) (is_internal_pid(T) ? am_erl_tracer : CAR(list_val(T)))
+#define ERTS_TRACER_STATE(T) (is_internal_pid(T) ? T : CDR(list_val(T)))
#define ERTS_P_LINKS(P) ((P)->common.u.alive.links)
#define ERTS_P_MONITORS(P) ((P)->common.u.alive.monitors)
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 649fe15ffb..4680c5d516 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -2810,7 +2810,11 @@ erts_term_to_tracer(Eterm prefix, Eterm t)
{
ErtsTracer tracer = erts_tracer_nil;
ASSERT(is_atom(prefix) || prefix == THE_NON_VALUE);
- if (!is_nil(t)) {
+
+ if (is_internal_pid(t)) {
+ tracer = t;
+ }
+ else if (!is_nil(t)) {
Eterm module = am_erl_tracer, state = THE_NON_VALUE;
Eterm hp[2];
if (is_tuple(t)) {
@@ -3152,7 +3156,7 @@ static void free_tracer(void *p)
}
/*
- * ErtsTracer is either NIL, 'true' or [Mod | State]
+ * ErtsTracer is either NIL, 'true', local pid or [Mod | State]
*
* - If State is immediate then the memory for
* the cons cell is just two words + sizeof(ErtsThrPrgrLaterOp) large.
@@ -3177,15 +3181,15 @@ static void free_tracer(void *p)
* the refc when *tracer is NIL.
*/
void
-erts_tracer_update_impl(ErtsTracer *tracer, const ErtsTracer new_tracer)
+erts_tracer_update_impl(ErtsTracer *tracer, ErtsTracer new_tracer)
{
ErlHeapFragment *hf;
- if (is_not_nil(*tracer)) {
+ if (is_list(*tracer)) {
Uint offs = 2;
UWord size = 2 * sizeof(Eterm) + sizeof(ErtsThrPrgrLaterOp);
ErtsThrPrgrLaterOp *lop;
- ASSERT(is_list(*tracer));
+
if (is_not_immed(ERTS_TRACER_STATE(*tracer))) {
hf = ErtsContainerStruct_(ptr_val(*tracer), ErlHeapFragment, mem);
offs = hf->used_size;
@@ -3212,7 +3216,15 @@ erts_tracer_update_impl(ErtsTracer *tracer, const ErtsTracer new_tracer)
free_tracer, (void*)(*tracer), lop, size);
}
- if (is_nil(new_tracer)) {
+ if (is_list(new_tracer)) {
+ const Eterm module = ERTS_TRACER_MODULE(new_tracer);
+ const Eterm state = ERTS_TRACER_STATE(new_tracer);
+ if (module == am_erl_tracer && is_internal_pid(state)) {
+ new_tracer = state;
+ }
+ }
+ if (is_immed(new_tracer)) {
+ ASSERT(is_nil(new_tracer) || is_internal_pid(new_tracer));
*tracer = new_tracer;
} else if (is_immed(ERTS_TRACER_STATE(new_tracer))) {
/* If tracer state is an immediate we only allocate a 2 Eterm heap.
diff --git a/erts/emulator/beam/erl_trace.h b/erts/emulator/beam/erl_trace.h
index 90a5d2b5e7..0d261b0013 100644
--- a/erts/emulator/beam/erl_trace.h
+++ b/erts/emulator/beam/erl_trace.h
@@ -293,6 +293,7 @@ ERTS_DECLARE_DUMMY(erts_tracer_nil) = NIL;
#define IS_TRACER_VALID(tracer) \
(ERTS_TRACER_COMPARE(tracer,erts_tracer_true) \
|| ERTS_TRACER_IS_NIL(tracer) \
+ || is_internal_pid(tracer) \
|| (is_list(tracer) && is_atom(CAR(list_val(tracer)))))
#define ERTS_TRACER_FROM_ETERM(termp) \
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index f90b9bfe66..45aebd7e68 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -701,12 +701,13 @@ typedef struct preload {
} Preload;
/*
- * ErtsTracer is either NIL, 'true' or [Mod | State]
+ * ErtsTracer is either NIL, 'true', LocalPid or [Mod | State]
*
* If set to NIL, it means no tracer.
* If set to 'true' it means the current process' tracer.
* If set to [Mod | State], there is a tracer.
- * See erts_tracer_update for more details
+ * LocalPid is the optimized form of the common case [erl_tracer | LocalPid].
+ * See erts_tracer_update_impl for more details
*/
typedef Eterm ErtsTracer;
--
2.43.0