diff options
author | Sverker Eriksson <[email protected]> | 2014-02-25 15:27:59 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2014-02-25 15:27:59 +0100 |
commit | b9440a0529bea5ccc3f4341db29ddda6f4b7c536 (patch) | |
tree | fbd7e7c946eb9621fe1f923d04f857b921bd8378 /erts/emulator/hipe/hipe_mode_switch.c | |
parent | 98776a40609d1fa80292d2959708a8697f8cb756 (diff) | |
parent | eb53a3f0b7a7d6c4d0a877fe71bc0b0ca11d1597 (diff) | |
download | otp-b9440a0529bea5ccc3f4341db29ddda6f4b7c536.tar.gz otp-b9440a0529bea5ccc3f4341db29ddda6f4b7c536.tar.bz2 otp-b9440a0529bea5ccc3f4341db29ddda6f4b7c536.zip |
Merge branch 'sverk/hipe-disable-gc-bug'
* sverk/hipe-disable-gc-bug:
erts: Fix heap overwrite by hipe "trap frames" when GC is disabled
ASSERT that GC is not tried with "need" when GC is disabled
Diffstat (limited to 'erts/emulator/hipe/hipe_mode_switch.c')
-rw-r--r-- | erts/emulator/hipe/hipe_mode_switch.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c index 8ebe5da670..4ddc2790b1 100644 --- a/erts/emulator/hipe/hipe_mode_switch.c +++ b/erts/emulator/hipe/hipe_mode_switch.c @@ -185,21 +185,46 @@ void hipe_set_call_trap(Uint *bfun, void *nfun, int is_closure) bfun[-4] = (Uint)nfun; } -static __inline__ void -hipe_push_beam_trap_frame(Process *p, Eterm reg[], unsigned arity) +void hipe_reserve_beam_trap_frame(Process *p, Eterm reg[], unsigned arity) { /* ensure that at least 2 words are available on the BEAM stack */ if ((p->stop - 2) < p->htop) { - DPRINTF("calling gc to increase BEAM stack size"); + DPRINTF("calling gc to reserve BEAM stack size"); p->fcalls -= erts_garbage_collect(p, 2, reg, arity); + ASSERT(!((p->stop - 2) < p->htop)); } p->stop -= 2; + p->stop[0] = NIL; + p->stop[1] = NIL; +} + +static __inline__ void +hipe_push_beam_trap_frame(Process *p, Eterm reg[], unsigned arity) +{ + if (p->flags & F_DISABLE_GC) { + /* Trap frame already reserved */ + ASSERT(p->stop[0] == NIL && p->stop[1] == NIL); + } + else { + if ((p->stop - 2) < p->htop) { + DPRINTF("calling gc to increase BEAM stack size"); + p->fcalls -= erts_garbage_collect(p, 2, reg, arity); + ASSERT(!((p->stop - 2) < p->htop)); + } + p->stop -= 2; + } p->stop[1] = hipe_beam_catch_throw; p->stop[0] = make_cp(p->cp); ++p->catches; p->cp = hipe_beam_pc_return; } +void hipe_unreserve_beam_trap_frame(Process *p) +{ + ASSERT(p->stop[0] == NIL && p->stop[1] == NIL); + p->stop += 2; +} + static __inline__ void hipe_pop_beam_trap_frame(Process *p) { p->cp = cp_val(p->stop[0]); |