diff options
author | Magnus Lång <[email protected]> | 2016-04-12 15:26:07 +0200 |
---|---|---|
committer | Magnus Lång <[email protected]> | 2016-06-30 12:30:04 +0200 |
commit | 520654d49d9f1c1548dc2a5800c7330001cd3064 (patch) | |
tree | 0e72981d83f8f9404d9dec71504b8a1d92282d1e /erts/emulator/hipe/hipe_ppc_bifs.m4 | |
parent | 1dd81185dfb2fd6ac30b6eb44c905128c8958cb4 (diff) | |
download | otp-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.m4 | 36 |
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) * |