aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-05-05 05:23:54 +0200
committerBjörn Gustavsson <[email protected]>2017-05-05 11:46:38 +0200
commitff94c59ca65ab3f4d9a1660e64ae31ed2232a5c2 (patch)
tree7ce197c990305e6678c503d41ee33000c05fbb7d /erts/emulator/beam
parent6962098f2ff7dcff5ce46364898815c685d0f0b8 (diff)
downloadotp-ff94c59ca65ab3f4d9a1660e64ae31ed2232a5c2.tar.gz
otp-ff94c59ca65ab3f4d9a1660e64ae31ed2232a5c2.tar.bz2
otp-ff94c59ca65ab3f4d9a1660e64ae31ed2232a5c2.zip
Clear p->fvalue when handling a try/catch
p->fvalue will be set by BIFs that generate exceptions (such as throw/1), and it will not be cleared before another exception is generated. Potentially, p->fvalue may contain a huge term (e.g. after throw(HugeTerm)) which will be kept in the heap. We can shorten the lifetime of f->value by clearing it in the instructions that handle catches: catch_end and try_end. That is safe because BEAM code will never access p->fvalue. If BEAM code needs to rethrow an exception it will use a reference to the value passed in an X register. The reason that p->fvalue must not be cleared already in handle_error() is that native code trap handlers will use it. (See the comment before handle_error() and the comment at the end of handle_error() in beam_emu.c for some more information about exception handling.)
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/beam_emu.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 311bb94242..a90e6a0ba8 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -1814,6 +1814,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array)
c_p->catches--;
make_blank(yb(Arg(0)));
if (is_non_value(r(0))) {
+ c_p->fvalue = NIL;
if (x(1) == am_throw) {
r(0) = x(2);
} else {
@@ -1843,6 +1844,7 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array)
c_p->catches--;
make_blank(yb(Arg(0)));
if (is_non_value(r(0))) {
+ c_p->fvalue = NIL;
r(0) = x(1);
x(1) = x(2);
x(2) = x(3);