File 1136-Reduce-size-of-exception-raising-BEAM-instructions.patch of Package erlang

From 3e40c8af421e6c78a46e136850a4133042846508 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Sat, 16 Sep 2023 08:39:42 +0200
Subject: [PATCH 16/25] Reduce size of exception-raising BEAM instructions

---
 .../emulator/beam/jit/arm/beam_asm_global.cpp | 17 ++++++++-----
 .../beam/jit/arm/beam_asm_global.hpp.pl       |  2 ++
 erts/emulator/beam/jit/arm/instr_common.cpp   | 25 +++++++++++++------
 .../emulator/beam/jit/x86/beam_asm_global.cpp | 11 +++++++-
 .../beam/jit/x86/beam_asm_global.hpp.pl       |  2 ++
 erts/emulator/beam/jit/x86/instr_common.cpp   | 21 +++++++++++-----
 6 files changed, 57 insertions(+), 21 deletions(-)

diff --git a/erts/emulator/beam/jit/arm/beam_asm_global.cpp b/erts/emulator/beam/jit/arm/beam_asm_global.cpp
index 1ec8ffa51a..84cbf0a515 100644
--- a/erts/emulator/beam/jit/arm/beam_asm_global.cpp
+++ b/erts/emulator/beam/jit/arm/beam_asm_global.cpp
@@ -242,12 +242,11 @@ void BeamModuleAssembler::emit_raise_exception() {
 void BeamModuleAssembler::emit_raise_exception(const ErtsCodeMFA *exp) {
     if (exp) {
         a.ldr(ARG4, embed_constant(exp, disp32K));
+        fragment_call(ga->get_raise_exception());
     } else {
-        a.mov(ARG4, ZERO);
+        fragment_call(ga->get_raise_exception_null_exp());
     }
 
-    fragment_call(ga->get_raise_exception());
-
     /* `line` instructions need to know the latest offset that may throw an
      * exception. See the `line` instruction for details. */
     last_error_offset = a.offset();
@@ -259,11 +258,10 @@ void BeamModuleAssembler::emit_raise_exception(Label I,
 
     if (exp) {
         a.ldr(ARG4, embed_constant(exp, disp32K));
+        a.b(resolve_fragment(ga->get_raise_exception_shared(), disp128MB));
     } else {
-        a.mov(ARG4, ZERO);
+        a.b(resolve_fragment(ga->get_raise_exception_null_exp(), disp128MB));
     }
-
-    a.b(resolve_fragment(ga->get_raise_exception_shared(), disp128MB));
 }
 
 void BeamGlobalAssembler::emit_process_exit() {
@@ -281,6 +279,13 @@ void BeamGlobalAssembler::emit_process_exit() {
     a.udf(0xdead);
 }
 
+/* You must have already done emit_leave_runtime_frame()! */
+void BeamGlobalAssembler::emit_raise_exception_null_exp() {
+    a.mov(ARG4, ZERO);
+    a.mov(ARG2, a64::x30);
+    a.b(labels[raise_exception_shared]);
+}
+
 /* You must have already done emit_leave_runtime_frame()! */
 void BeamGlobalAssembler::emit_raise_exception() {
     a.mov(ARG2, a64::x30);
diff --git a/erts/emulator/beam/jit/arm/beam_asm_global.hpp.pl b/erts/emulator/beam/jit/arm/beam_asm_global.hpp.pl
index 0cb95c5ce3..1b8fb7ddf1 100644
--- a/erts/emulator/beam/jit/arm/beam_asm_global.hpp.pl
+++ b/erts/emulator/beam/jit/arm/beam_asm_global.hpp.pl
@@ -107,7 +107,9 @@ my @beam_global_funcs = qw(
     process_exit
     process_main
     raise_exception
+    raise_exception_null_exp
     raise_exception_shared
+    raise_shared
     store_unaligned
     unloaded_fun
     unary_minus_body_shared
diff --git a/erts/emulator/beam/jit/arm/instr_common.cpp b/erts/emulator/beam/jit/arm/instr_common.cpp
index 1963263a19..63214821db 100644
--- a/erts/emulator/beam/jit/arm/instr_common.cpp
+++ b/erts/emulator/beam/jit/arm/instr_common.cpp
@@ -2555,13 +2555,8 @@ void BeamModuleAssembler::emit_try_case_end(const ArgSource &Src) {
     emit_error(EXC_TRY_CLAUSE, Src);
 }
 
-void BeamModuleAssembler::emit_raise(const ArgSource &Trace,
-                                     const ArgSource &Value) {
-    auto value = load_source(Value, TMP1);
-    mov_arg(ARG2, Trace);
-
-    /* This is an error, attach a stacktrace to the reason. */
-    a.str(value.reg, arm::Mem(c_p, offsetof(Process, fvalue)));
+void BeamGlobalAssembler::emit_raise_shared() {
+    a.str(ARG1, arm::Mem(c_p, offsetof(Process, fvalue)));
     a.str(ARG2, arm::Mem(c_p, offsetof(Process, ftrace)));
 
     emit_enter_runtime(0);
@@ -2571,7 +2566,21 @@ void BeamModuleAssembler::emit_raise(const ArgSource &Trace,
 
     emit_leave_runtime(0);
 
-    emit_raise_exception();
+    a.mov(ARG4, ZERO);
+    a.mov(ARG2, a64::x30);
+    a.b(labels[raise_exception_shared]);
+}
+
+void BeamModuleAssembler::emit_raise(const ArgSource &Trace,
+                                     const ArgSource &Value) {
+    auto [value, trace] = load_sources(Value, ARG1, Trace, ARG2);
+    mov_var(ARG1, value);
+    mov_var(ARG2, trace);
+    fragment_call(ga->get_raise_shared());
+
+    /* `line` instructions need to know the latest offset that may throw an
+     * exception. See the `line` instruction for details. */
+    last_error_offset = a.offset();
 }
 
 void BeamModuleAssembler::emit_build_stacktrace() {
diff --git a/erts/emulator/beam/jit/x86/beam_asm_global.cpp b/erts/emulator/beam/jit/x86/beam_asm_global.cpp
index 3c689639e0..bb62938b99 100644
--- a/erts/emulator/beam/jit/x86/beam_asm_global.cpp
+++ b/erts/emulator/beam/jit/x86/beam_asm_global.cpp
@@ -234,7 +234,11 @@ void BeamGlobalAssembler::emit_export_trampoline() {
  * the return address as the error address.
  */
 void BeamModuleAssembler::emit_raise_exception() {
-    emit_raise_exception(nullptr);
+    safe_fragment_call(ga->get_raise_exception_null_exp());
+
+    /* `line` instructions need to know the latest offset that may throw an
+     * exception. See the `line` instruction for details. */
+    last_error_offset = a.offset();
 }
 
 void BeamModuleAssembler::emit_raise_exception(const ErtsCodeMFA *exp) {
@@ -294,6 +298,11 @@ void BeamGlobalAssembler::emit_process_exit() {
     a.ud2();
 }
 
+void BeamGlobalAssembler::emit_raise_exception_null_exp() {
+    mov_imm(ARG4, 0);
+    a.jmp(labels[raise_exception]);
+}
+
 /* Helper function for throwing exceptions from global fragments.
  *
  * Assumes that the next item on the _machine stack_ is a return address: we
diff --git a/erts/emulator/beam/jit/x86/beam_asm_global.hpp.pl b/erts/emulator/beam/jit/x86/beam_asm_global.hpp.pl
index e6f8a53219..a77c05ea46 100755
--- a/erts/emulator/beam/jit/x86/beam_asm_global.hpp.pl
+++ b/erts/emulator/beam/jit/x86/beam_asm_global.hpp.pl
@@ -100,7 +100,9 @@ my @beam_global_funcs = qw(
     process_exit
     process_main
     raise_exception
+    raise_exception_null_exp
     raise_exception_shared
+    raise_shared
     store_unaligned
     unary_minus_body_shared
     unary_minus_guard_shared
diff --git a/erts/emulator/beam/jit/x86/instr_common.cpp b/erts/emulator/beam/jit/x86/instr_common.cpp
index bbf05396f1..4c555e326c 100644
--- a/erts/emulator/beam/jit/x86/instr_common.cpp
+++ b/erts/emulator/beam/jit/x86/instr_common.cpp
@@ -2525,11 +2525,7 @@ void BeamModuleAssembler::emit_try_case_end(const ArgSource &Src) {
     emit_error(EXC_TRY_CLAUSE);
 }
 
-void BeamModuleAssembler::emit_raise(const ArgSource &Trace,
-                                     const ArgSource &Value) {
-    mov_arg(ARG3, Value);
-    mov_arg(ARG2, Trace);
-
+void BeamGlobalAssembler::emit_raise_shared() {
     /* This is an error, attach a stacktrace to the reason. */
     a.mov(x86::qword_ptr(c_p, offsetof(Process, fvalue)), ARG3);
     a.mov(x86::qword_ptr(c_p, offsetof(Process, ftrace)), ARG2);
@@ -2541,7 +2537,20 @@ void BeamModuleAssembler::emit_raise(const ArgSource &Trace,
 
     emit_leave_runtime();
 
-    emit_raise_exception();
+    mov_imm(ARG4, 0);
+    a.jmp(labels[raise_exception]);
+}
+
+void BeamModuleAssembler::emit_raise(const ArgSource &Trace,
+                                     const ArgSource &Value) {
+    mov_arg(ARG3, Value);
+    mov_arg(ARG2, Trace);
+
+    fragment_call(resolve_fragment(ga->get_raise_shared()));
+
+    /* `line` instructions need to know the latest offset that may throw an
+     * exception. See the `line` instruction for details. */
+    last_error_offset = a.offset();
 }
 
 void BeamModuleAssembler::emit_build_stacktrace() {
-- 
2.35.3

openSUSE Build Service is sponsored by