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