aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/bif.h
diff options
context:
space:
mode:
authorPaul Guyot <[email protected]>2010-09-27 18:10:24 +0200
committerPaul Guyot <[email protected]>2011-01-29 09:36:14 +0100
commitce00ecb42c136b55d91ece38c9cf29b0d0cc6380 (patch)
treee7db4a8ca6ffc1e4238a65557e904f420efcc411 /erts/emulator/beam/bif.h
parent62dad961329a603110ce0e1d3f62554cc5228152 (diff)
downloadotp-ce00ecb42c136b55d91ece38c9cf29b0d0cc6380.tar.gz
otp-ce00ecb42c136b55d91ece38c9cf29b0d0cc6380.tar.bz2
otp-ce00ecb42c136b55d91ece38c9cf29b0d0cc6380.zip
Fix several bugs related to hibernate/3 and HiPE
This commit fixes four related bugs: - calling hibernate/3 using a dynamic call would fail with badarg as hibernate/3 as a BIF was not implemented. hibernate/3 is generally provided as a Beam instruction, and code is translated to use this instruction when loaded. - calling hibernate/3 from HiPE would fail with badarg because this would call the aforementioned BIF which was not implemented. - calling hibernate/3 with some HiPE-native garbage in the process heap would randomly crash at the next garbage collect. This bug only happened in a complex, yet reproduceable scenarios, where native code calls beam code that calls hibernate/3, and the process has some garbage when being hibernated and the process generates garbage when awaken. - when entering HiPE, the process current_function can be set and be inaccurate. The fix is three folded: - hibernate_3 BIF now actually works instead of throwing a badarg. While hibernate_3 BIF was (usually) not called from BEAM, it is called from HiPE. hibernate behaviour is very close to the scheduler and this is why it is implemented as an instruction in BEAM. The fix consists in doing the actual hibernation (through the now exported erts_hibernate function) and setting the process flag to TRAP as well as the process status to P_WAITING. On BIF epilogue in both BEAM and HiPE, this status is tested on TRAP and if set, the scheduler is invoked. The i_hibernate instruction and translation code is now redundant and could be deleted. - hibernation now also empties the HiPE native stack, with a new function hipe_empty_nstack provided by Mikael Pettersson. - when entering HiPE through hipe_mode_switch, p->current is cleared, as suggested by Mikael Pettersson. p->current normally hold a pointer to the {M,F,A} of the current function if it exists. When hibernating, it is set to {erlang,hibernate,3}, and all stdlib hibernate tests (gen_server_SUITE:hibernate/1, proc_lib_suite:hibernate/1, etc.) actually rely on this information. Clearing p->current fixes the tests and avoids the surprise one might have when querying the process info of a process that hibernated and woke up in a native function. Non-regression tests are provided, a test for the dynamic call as well as a Makefile-handled duplication of the hibernate_SUITE into hibernate_native_SUITE for the HiPE case.
Diffstat (limited to 'erts/emulator/beam/bif.h')
-rw-r--r--erts/emulator/beam/bif.h6
1 files changed, 6 insertions, 0 deletions
diff --git a/erts/emulator/beam/bif.h b/erts/emulator/beam/bif.h
index a84ee7bb23..615714f7f4 100644
--- a/erts/emulator/beam/bif.h
+++ b/erts/emulator/beam/bif.h
@@ -201,6 +201,12 @@ do { \
return THE_NON_VALUE; \
} while(0)
+#define BIF_TRAP_CODE_PTR_(p, Code_) do { \
+ *((UWord *) (UWord) ((p)->def_arg_reg + 3)) = (UWord) (Code_); \
+ (p)->freason = TRAP; \
+ return THE_NON_VALUE; \
+ } while(0)
+
extern Export bif_return_trap_export;
#ifdef DEBUG
#define ERTS_BIF_PREP_YIELD_RETURN_X(RET, P, VAL, DEBUG_VAL) \