File 2153-Simplify-the-raise-instruction-to-reduce-code-size.patch of Package erlang

From 3c0f98c1b0e74eb58a4e4e82a3ec89dc7ecdb579 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Thu, 7 Apr 2016 10:06:44 +0200
Subject: [PATCH 1/2] Simplify the raise instruction to reduce code size

The raise/2 instruction is almost always used like this:

  raise x(2) x(1)

Therefore, we can translate it to an internal i_raise/0
instruction that uses x(2) x(1) as its implicit operands.

We will also remove the backward compatibility with R10-0.  It is
unlikely that anyone still is using BEAM files compiled with the R10-0
compiler, especially since most of those modules cannot be loaded. The
loader will refuse to load any module that uses the old non-GCIng
arithmetic instructions or the non-GCing versions of length/1 or
size/1.

Doing these changes will reduce both the size of the loaded BEAM
code and size of the code in process_main().
---
 erts/emulator/beam/beam_emu.c | 54 ++++++++++---------------------------------
 erts/emulator/beam/ops.tab    |  9 +++++++-
 2 files changed, 20 insertions(+), 43 deletions(-)

diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 09a41f2..d648a2f 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -3360,48 +3360,18 @@ do {						\
      goto do_schedule;
  }
 
- OpCase(raise_ss): {
-     /* This was not done very well in R10-0; then, we passed the tag in
-	the first argument and hoped that the existing c_p->ftrace was
-	still correct. But the ftrace-object already includes the tag
-	(or rather, the freason). Now, we pass the original ftrace in
-	the first argument. We also handle atom tags in the first
-	argument for backwards compatibility.
-     */
-     Eterm raise_val1;
-     Eterm raise_val2;
-     GetArg2(0, raise_val1, raise_val2);
-     c_p->fvalue = raise_val2;
-     if (c_p->freason == EXC_NULL) {
-       /* a safety check for the R10-0 case; should not happen */
-       c_p->ftrace = NIL;
-       c_p->freason = EXC_ERROR;
-     }
-     /* for R10-0 code, keep existing c_p->ftrace and hope it's correct */
-     switch (raise_val1) {
-     case am_throw:
-       c_p->freason = EXC_THROWN & ~EXF_SAVETRACE;
-       break;
-     case am_error:
-       c_p->freason = EXC_ERROR & ~EXF_SAVETRACE;
-       break;
-     case am_exit:
-       c_p->freason = EXC_EXIT & ~EXF_SAVETRACE;
-       break;
-     default:
-       {/* R10-1 and later
-	   XXX note: should do sanity check on given trace if it can be
-	   passed from a user! Currently only expecting generated calls.
-	*/
-	 struct StackTrace *s;
-	 c_p->ftrace = raise_val1;
-	 s = get_trace_from_exc(raise_val1);
-	 if (s == NULL) {
-	   c_p->freason = EXC_ERROR;
-	 } else {
-	   c_p->freason = PRIMARY_EXCEPTION(s->freason);
-	 }
-       }
+ OpCase(i_raise): {
+     Eterm raise_trace = x(2);
+     Eterm raise_value = x(1);
+     struct StackTrace *s;
+
+     c_p->fvalue = raise_value;
+     c_p->ftrace = raise_trace;
+     s = get_trace_from_exc(raise_trace);
+     if (s == NULL) {
+	 c_p->freason = EXC_ERROR;
+     } else {
+	 c_p->freason = PRIMARY_EXCEPTION(s->freason);
      }
      goto find_func_info;
  }
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 15f2783..96a3a72 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -251,7 +251,14 @@ case_end x
 badmatch x
 
 if_end
-raise s s
+
+# Operands for raise/2 are almost always in x(2) and x(1).
+# Optimize for that case.
+raise x==2 x==1 => i_raise
+raise Trace=y Value=y => move Trace x=2 | move Value x=1 | i_raise
+raise Trace Value => move Trace x=3 | move Value x=1 | move x=3 x=2 | i_raise
+
+i_raise
 
 # Internal now, but could be useful to make known to the compiler.
 badarg j
-- 
2.1.4

openSUSE Build Service is sponsored by