aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/hipe/hipe_ppc_bifs.m4
diff options
context:
space:
mode:
authorMagnus Lång <[email protected]>2016-04-12 15:26:07 +0200
committerMagnus Lång <[email protected]>2016-06-30 12:30:04 +0200
commit520654d49d9f1c1548dc2a5800c7330001cd3064 (patch)
tree0e72981d83f8f9404d9dec71504b8a1d92282d1e /erts/emulator/hipe/hipe_ppc_bifs.m4
parent1dd81185dfb2fd6ac30b6eb44c905128c8958cb4 (diff)
downloadotp-520654d49d9f1c1548dc2a5800c7330001cd3064.tar.gz
otp-520654d49d9f1c1548dc2a5800c7330001cd3064.tar.bz2
otp-520654d49d9f1c1548dc2a5800c7330001cd3064.zip
hipe: Fix bug in trap frame allocation wrappers
The trap frame allocation wrappers occasionally call the garbage collector, even though built-in functions are not supposed to. On non-{x86,amd64} platforms, HiPE was optimising the BIF wrapper interface on the basis that BIFs do not GC. So, when hipe_reserve_beam_trap_frame called the garbage collector, the state in the PCB was stale and corruption happened. Now, these particular BIFs are reclassified as GC BIFs. Unfortunately, in order to do that we needed to introduce a gc_bif_interface_3 macro in every hipe_$ARCH_bifs.m4 file.
Diffstat (limited to 'erts/emulator/hipe/hipe_ppc_bifs.m4')
-rw-r--r--erts/emulator/hipe/hipe_ppc_bifs.m436
1 files changed, 35 insertions, 1 deletions
diff --git a/erts/emulator/hipe/hipe_ppc_bifs.m4 b/erts/emulator/hipe/hipe_ppc_bifs.m4
index 57b4208bee..b540562185 100644
--- a/erts/emulator/hipe/hipe_ppc_bifs.m4
+++ b/erts/emulator/hipe/hipe_ppc_bifs.m4
@@ -212,8 +212,9 @@ ASYM($1):
* gc_bif_interface_0(nbif_name, cbif_name)
* gc_bif_interface_1(nbif_name, cbif_name)
* gc_bif_interface_2(nbif_name, cbif_name)
+ * gc_bif_interface_3(nbif_name, cbif_name)
*
- * Generate native interface for a BIF with 0-2 parameters and
+ * Generate native interface for a BIF with 0-3 parameters and
* standard failure mode.
* The BIF may do a GC.
*/
@@ -300,6 +301,39 @@ ASYM($1):
TYPE_FUNCTION(ASYM($1))
#endif')
+define(gc_bif_interface_3,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ GLOBAL(ASYM($1))
+ASYM($1):
+ /* Set up C argument registers. */
+ mr r3, P
+ NBIF_ARG(r4,3,0)
+ NBIF_ARG(r5,3,1)
+ NBIF_ARG(r6,3,2)
+
+ /* Save caller-save registers and call the C function. */
+ SAVE_CONTEXT_GC
+ STORE r4, P_ARG0(r3) /* Store BIF__ARGS in def_arg_reg[] */
+ STORE r5, P_ARG1(r3)
+ STORE r6, P_ARG2(r3)
+ addi r4, r3, P_ARG0
+ CALL_BIF($2)
+ TEST_GOT_MBUF
+
+ /* Restore registers. Check for exception. */
+ CMPI r3, THE_NON_VALUE
+ RESTORE_CONTEXT_GC
+ beq- 1f
+ NBIF_RET(3)
+1: /* workaround for bc:s small offset operand */
+ b CSYM(nbif_3_simple_exception)
+ HANDLE_GOT_MBUF(3)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
+#endif')
+
/*
* gc_nofail_primop_interface_1(nbif_name, cbif_name)
*