diff options
author | Björn Gustavsson <[email protected]> | 2017-05-05 05:23:54 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2017-05-05 11:46:38 +0200 |
commit | ff94c59ca65ab3f4d9a1660e64ae31ed2232a5c2 (patch) | |
tree | 7ce197c990305e6678c503d41ee33000c05fbb7d /erts/emulator/beam | |
parent | 6962098f2ff7dcff5ce46364898815c685d0f0b8 (diff) | |
download | otp-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.c | 2 |
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); |