aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-09-02 08:42:51 +0200
committerBjörn Gustavsson <[email protected]>2018-09-03 09:09:41 +0200
commit5801fcb2b36e04c433dcf0b90a8c47b86e34fc07 (patch)
tree8c6252cd8f481a3937b8351d818383145f1ca891
parent860ee1974caac4447dcbd7f9d7c27a252170d7a3 (diff)
downloadotp-5801fcb2b36e04c433dcf0b90a8c47b86e34fc07.tar.gz
otp-5801fcb2b36e04c433dcf0b90a8c47b86e34fc07.tar.bz2
otp-5801fcb2b36e04c433dcf0b90a8c47b86e34fc07.zip
ops.tab: Fix potentially unsafe optimization of raise/2
The operands for the raise/2 instruction are almost always in x(2) and x(1). Therefore the loader translates the raise/2 instruction to an i_raise/0 instruction which uses the values in x(2) and x(1). If the operands happens to be in other registers, the loader inserts move/2 instruction to move them to x(2) and x(1). The problem is that x(3) is used as a temporary register when generating the move/2 instructions. That is unsafe if the Value operand for raise/2 is x(3). Thus: raise x(0) x(3) will be translated to: move x(0) x(3) move x(3) x(1) move x(3) x(2) i_raise The Trace will be written to both x(2) and x(1). The current compiler will never use x(3) for the Value operand, so there is no need to patch previous releases. But a future compiler version might allocate registers differently.
-rw-r--r--erts/emulator/beam/ops.tab2
1 files changed, 1 insertions, 1 deletions
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index c51e4ef784..e76d896ffc 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -244,7 +244,7 @@ if_end
# 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
+raise Trace Value => move Trace x | move Value x=1 | move x x=2 | i_raise
i_raise