diff options
author | Björn Gustavsson <[email protected]> | 2018-09-02 08:42:51 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2018-09-03 09:09:41 +0200 |
commit | 5801fcb2b36e04c433dcf0b90a8c47b86e34fc07 (patch) | |
tree | 8c6252cd8f481a3937b8351d818383145f1ca891 /erts/emulator/beam/ops.tab | |
parent | 860ee1974caac4447dcbd7f9d7c27a252170d7a3 (diff) | |
download | otp-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.
Diffstat (limited to 'erts/emulator/beam/ops.tab')
-rw-r--r-- | erts/emulator/beam/ops.tab | 2 |
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 |