From ce00ecb42c136b55d91ece38c9cf29b0d0cc6380 Mon Sep 17 00:00:00 2001 From: Paul Guyot Date: Mon, 27 Sep 2010 18:10:24 +0200 Subject: 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. --- .gitignore | 1 + 1 file changed, 1 insertion(+) (limited to '.gitignore') diff --git a/.gitignore b/.gitignore index 54bfadea9a..240f5aaf80 100644 --- a/.gitignore +++ b/.gitignore @@ -165,6 +165,7 @@ make/win32/ /lib/*/test/*_SUITE_make.erl /lib/*/test/*_SUITE_data/Makefile /erts/emulator/test/*_SUITE_make.erl +/erts/emulator/test/*_native_SUITE.erl /erts/emulator/test/*_SUITE_data/Makefile /erts/test/install_SUITE_data/install_bin /erts/test/autoimport_SUITE_data/erlang.xml -- cgit v1.2.3