From 01c734e6a60bb9579c00079f7d81d197b684c9e3 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Fri, 18 Mar 2011 18:19:45 +0100 Subject: erts-hipe: Enable debug compiled hipe-VM with lock checker Add hipe_debug_bif_wrapper() as a wrapper for every BIF called by native code. --- erts/emulator/hipe/hipe_amd64_bifs.m4 | 16 ++++++++++++---- erts/emulator/hipe/hipe_arm_bifs.m4 | 15 +++++++++++---- erts/emulator/hipe/hipe_bif2.c | 23 +++++++++++++++++++++++ erts/emulator/hipe/hipe_mkliterals.c | 3 +++ erts/emulator/hipe/hipe_mode_switch.c | 13 +++++++++++++ erts/emulator/hipe/hipe_ppc_asm.m4 | 11 +++++++++++ erts/emulator/hipe/hipe_ppc_bifs.m4 | 21 ++++++++++++++------- erts/emulator/hipe/hipe_process.h | 3 +++ erts/emulator/hipe/hipe_sparc_bifs.m4 | 21 ++++++++++++++------- erts/emulator/hipe/hipe_x86_bifs.m4 | 15 +++++++++++---- 10 files changed, 115 insertions(+), 26 deletions(-) diff --git a/erts/emulator/hipe/hipe_amd64_bifs.m4 b/erts/emulator/hipe/hipe_amd64_bifs.m4 index 9385cbd22b..97a8267647 100644 --- a/erts/emulator/hipe/hipe_amd64_bifs.m4 +++ b/erts/emulator/hipe/hipe_amd64_bifs.m4 @@ -20,8 +20,10 @@ changecom(`/*', `*/')dnl include(`hipe/hipe_amd64_asm.m4') +#`include' "config.h" #`include' "hipe_literals.h" + `#if THE_NON_VALUE == 0 #define TEST_GOT_EXN testq %rax, %rax #else @@ -36,6 +38,12 @@ define(HANDLE_GOT_MBUF,` 3: call nbif_$1_gc_after_bif # `HANDLE_GOT_MBUF' jmp 2b') +`#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) +# define CALL_BIF(F) movq $CSYM(F), P_BIF_CALLEE(P); call CSYM(hipe_debug_bif_wrapper) +#else +# define CALL_BIF(F) call CSYM(F) +#endif' + /* * standard_bif_interface_1(nbif_name, cbif_name) * standard_bif_interface_2(nbif_name, cbif_name) @@ -62,7 +70,7 @@ ASYM($1): pushq %rsi movq %rsp, %rsi /* Eterm* BIF__ARGS */ sub $(8), %rsp /* stack frame 16-byte alignment */ - call CSYM($2) + CALL_BIF($2) add $(1*8 + 8), %rsp TEST_GOT_MBUF SWITCH_C_TO_ERLANG @@ -94,7 +102,7 @@ ASYM($1): pushq %rdx pushq %rsi movq %rsp, %rsi /* Eterm* BIF__ARGS */ - call CSYM($2) + CALL_BIF($2) add $(2*8), %rsp TEST_GOT_MBUF SWITCH_C_TO_ERLANG @@ -129,7 +137,7 @@ ASYM($1): pushq %rsi movq %rsp, %rsi /* Eterm* BIF__ARGS */ sub $(8), %rsp /* stack frame 16-byte alignment */ - call CSYM($2) + CALL_BIF($2) add $(3*8 + 8), %rsp TEST_GOT_MBUF SWITCH_C_TO_ERLANG @@ -156,7 +164,7 @@ ASYM($1): /* make the call on the C stack */ SWITCH_ERLANG_TO_C - call CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF SWITCH_C_TO_ERLANG diff --git a/erts/emulator/hipe/hipe_arm_bifs.m4 b/erts/emulator/hipe/hipe_arm_bifs.m4 index cecc493476..e0c6f09796 100644 --- a/erts/emulator/hipe/hipe_arm_bifs.m4 +++ b/erts/emulator/hipe/hipe_arm_bifs.m4 @@ -20,11 +20,18 @@ changecom(`/*', `*/')dnl include(`hipe/hipe_arm_asm.m4') +#`include' "config.h" #`include' "hipe_literals.h" .text .p2align 2 +`#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) +# define CALL_BIF(F) mov r14, #F; str r14, [r0, #P_BIF_CALLEE]; bl hipe_debug_bif_wrapper +#else +# define CALL_BIF(F) bl F +#endif' + define(TEST_GOT_MBUF,`ldr r1, [P, #P_MBUF] /* `TEST_GOT_MBUF' */ cmp r1, #0 blne nbif_$1_gc_after_bif') @@ -52,7 +59,7 @@ $1: SAVE_CONTEXT_BIF str r1, [r0, #P_ARG0] /* Store BIF__ARGS in def_arg_reg[] */ add r1, r0, #P_ARG0 - bl $2 + CALL_BIF($2) TEST_GOT_MBUF(1) /* Restore registers. Check for exception. */ @@ -80,7 +87,7 @@ $1: str r1, [r0, #P_ARG0] /* Store BIF__ARGS in def_arg_reg[] */ str r2, [r0, #P_ARG1] add r1, r0, #P_ARG0 - bl $2 + CALL_BIF($2) TEST_GOT_MBUF(2) /* Restore registers. Check for exception. */ @@ -110,7 +117,7 @@ $1: str r2, [r0, #P_ARG1] str r3, [r0, #P_ARG2] add r1, r0, #P_ARG0 - bl $2 + CALL_BIF($2) TEST_GOT_MBUF(3) /* Restore registers. Check for exception. */ @@ -134,7 +141,7 @@ $1: /* Save caller-save registers and call the C function. */ SAVE_CONTEXT_BIF /* ignore empty BIF__ARGS */ - bl $2 + CALL_BIF($2) TEST_GOT_MBUF(0) /* Restore registers. Check for exception. */ diff --git a/erts/emulator/hipe/hipe_bif2.c b/erts/emulator/hipe/hipe_bif2.c index 2660f74a82..ee97541e15 100644 --- a/erts/emulator/hipe/hipe_bif2.c +++ b/erts/emulator/hipe/hipe_bif2.c @@ -166,3 +166,26 @@ BIF_RETTYPE hipe_bifs_show_message_area_0(BIF_ALIST_0) BIF_RET(am_false); #endif } + +#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) + +BIF_RETTYPE hipe_debug_bif_wrapper(BIF_ALIST_1); + +# define ERTS_SMP_REQ_PROC_MAIN_LOCK(P) \ + if ((P)) erts_proc_lc_require_lock((P), ERTS_PROC_LOCK_MAIN) +# define ERTS_SMP_UNREQ_PROC_MAIN_LOCK(P) \ + if ((P)) erts_proc_lc_unrequire_lock((P), ERTS_PROC_LOCK_MAIN) + +BIF_RETTYPE hipe_debug_bif_wrapper(BIF_ALIST_1) +{ + typedef BIF_RETTYPE Bif(BIF_ALIST_1); + Bif* fp = (Bif*) (BIF_P->hipe.bif_callee); + BIF_RETTYPE res; + ERTS_SMP_UNREQ_PROC_MAIN_LOCK(BIF_P); + res = (*fp)(BIF_P, BIF__ARGS); + ERTS_SMP_REQ_PROC_MAIN_LOCK(BIF_P); + return res; +} + +#endif /* ERTS_ENABLE_LOCK_CHECK && ERTS_SMP */ + diff --git a/erts/emulator/hipe/hipe_mkliterals.c b/erts/emulator/hipe/hipe_mkliterals.c index bced90785d..715764f4d0 100644 --- a/erts/emulator/hipe/hipe_mkliterals.c +++ b/erts/emulator/hipe/hipe_mkliterals.c @@ -289,6 +289,9 @@ static const struct literal { { "P_NRA", offsetof(struct process, hipe.nra) }, #endif { "P_NARITY", offsetof(struct process, hipe.narity) }, +# if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) + { "P_BIF_CALLEE", offsetof(struct process, hipe.bif_callee) }, +# endif #endif /* HIPE */ /* process flags bits */ diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c index 2b0bcca5c6..4d75883fc5 100644 --- a/erts/emulator/hipe/hipe_mode_switch.c +++ b/erts/emulator/hipe/hipe_mode_switch.c @@ -35,6 +35,17 @@ #include "hipe_stack.h" #include "hipe_bif0.h" /* hipe_mfa_info_table_init() */ +#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) +# define ERTS_SMP_REQ_PROC_MAIN_LOCK(P) \ + if ((P)) erts_proc_lc_require_lock((P), ERTS_PROC_LOCK_MAIN) +# define ERTS_SMP_UNREQ_PROC_MAIN_LOCK(P) \ + if ((P)) erts_proc_lc_unrequire_lock((P), ERTS_PROC_LOCK_MAIN) +#else +# define ERTS_SMP_REQ_PROC_MAIN_LOCK(P) +# define ERTS_SMP_UNREQ_PROC_MAIN_LOCK(P) +#endif + + /* * Internal debug support. * #define HIPE_DEBUG to the desired debug level: @@ -458,7 +469,9 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[]) #if !(NR_ARG_REGS > 5) int reds_in = p->def_arg_reg[5]; #endif + ERTS_SMP_UNREQ_PROC_MAIN_LOCK(p); p = schedule(p, reds_in - p->fcalls); + ERTS_SMP_REQ_PROC_MAIN_LOCK(p); #ifdef ERTS_SMP p->hipe_smp.have_receive_locks = 0; reg = p->scheduler_data->x_reg_array; diff --git a/erts/emulator/hipe/hipe_ppc_asm.m4 b/erts/emulator/hipe/hipe_ppc_asm.m4 index 0eb5c441e6..343402f9f0 100644 --- a/erts/emulator/hipe/hipe_ppc_asm.m4 +++ b/erts/emulator/hipe/hipe_ppc_asm.m4 @@ -31,12 +31,23 @@ define(LOAD,ld)dnl define(STORE,std)dnl define(CMPI,cmpdi)dnl define(WSIZE,8)dnl +`#define STORE_IA(ADDR, DST, TMP) \ + addis TMP, 0, ADDR@highest SEMI\ + ori TMP, TMP, ADDR@higher SEMI\ + rldicr TMP, TMP, 32, 31 SEMI\ + oris TMP, TMP, ADDR@h SEMI\ + ori TMP, TMP, ADDR@l SEMI\ + std TMP, DST' ',` /* 32-bit PowerPC */ define(LOAD,lwz)dnl define(STORE,stw)dnl define(CMPI,cmpwi)dnl define(WSIZE,4)dnl +`#define STORE_IA(ADDR, DST, TMP) \ + lis TMP, ADDR@ha SEMI\ + addi TMP, TMP, ADDR@l SEMI\ + stw TMP, DST' ')dnl `#define LOAD 'LOAD `#define STORE 'STORE diff --git a/erts/emulator/hipe/hipe_ppc_bifs.m4 b/erts/emulator/hipe/hipe_ppc_bifs.m4 index 2dfbc48835..d09551d10d 100644 --- a/erts/emulator/hipe/hipe_ppc_bifs.m4 +++ b/erts/emulator/hipe/hipe_ppc_bifs.m4 @@ -20,8 +20,15 @@ changecom(`/*', `*/')dnl include(`hipe/hipe_ppc_asm.m4') +#`include' "config.h" #`include' "hipe_literals.h" +`#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) +# define CALL_BIF(F) STORE_IA(CSYM(F), P_BIF_CALLEE(P), r29); bl CSYM(hipe_debug_bif_wrapper) +#else +# define CALL_BIF(F) bl CSYM(F) +#endif' + .text .p2align 2 @@ -57,7 +64,7 @@ ASYM($1): SAVE_CONTEXT_BIF STORE r4, P_ARG0(r3) # Store BIF__ARGS in def_arg_reg[] addi r4, r3, P_ARG0 - bl CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* Restore registers. Check for exception. */ @@ -88,7 +95,7 @@ ASYM($1): STORE r4, P_ARG0(r3) # Store BIF__ARGS in def_arg_reg[] STORE r5, P_ARG1(r3) addi r4, r3, P_ARG0 - bl CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* Restore registers. Check for exception. */ @@ -121,7 +128,7 @@ ASYM($1): STORE r5, P_ARG1(r3) STORE r6, P_ARG2(r3) addi r4, r3, P_ARG0 - bl CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* Restore registers. Check for exception. */ @@ -148,7 +155,7 @@ ASYM($1): /* Save caller-save registers and call the C function. */ SAVE_CONTEXT_BIF /* ignore empty BIF__ARGS */ - bl CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* Restore registers. Check for exception. */ @@ -184,7 +191,7 @@ ASYM($1): /* Save caller-save registers and call the C function. */ SAVE_CONTEXT_GC /* ignore empty BIF__ARGS */ - bl CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* Restore registers. */ @@ -209,7 +216,7 @@ ASYM($1): SAVE_CONTEXT_GC STORE r4, P_ARG0(r3) # Store BIF__ARGS in def_arg_reg[] addi r4, r3, P_ARG0 - bl CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* Restore registers. Check for exception. */ @@ -240,7 +247,7 @@ ASYM($1): STORE r4, P_ARG0(r3) # Store BIF__ARGS in def_arg_reg[] STORE r5, P_ARG1(r3) addi r4, r3, P_ARG0 - bl CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* Restore registers. Check for exception. */ diff --git a/erts/emulator/hipe/hipe_process.h b/erts/emulator/hipe/hipe_process.h index 5effacb398..43f47d1a28 100644 --- a/erts/emulator/hipe/hipe_process.h +++ b/erts/emulator/hipe/hipe_process.h @@ -42,6 +42,9 @@ struct hipe_process_state { void (*nra)(void); /* Native code return address. */ #endif unsigned int narity; /* Arity of BIF call, for stack walks. */ +#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) + void (*bif_callee)(void); /* When calling BIF's via debug wrapper */ +#endif }; extern void hipe_arch_print_pcb(struct hipe_process_state *p); diff --git a/erts/emulator/hipe/hipe_sparc_bifs.m4 b/erts/emulator/hipe/hipe_sparc_bifs.m4 index 39ca71f1e8..ca5af45d58 100644 --- a/erts/emulator/hipe/hipe_sparc_bifs.m4 +++ b/erts/emulator/hipe/hipe_sparc_bifs.m4 @@ -20,11 +20,18 @@ changecom(`/*', `*/')dnl include(`hipe/hipe_sparc_asm.m4') +#`include' "config.h" #`include' "hipe_literals.h" .section ".text" .align 4 +`#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) +# define CALL_BIF(F) set F, %o7; st %o7, [%o0+P_BIF_CALLEE]; call hipe_debug_bif_wrapper +#else +# define CALL_BIF(F) call F +#endif' + /* * Test for exception. This macro executes its delay slot. */ @@ -65,7 +72,7 @@ $1: SAVE_CONTEXT_BIF st %o1, [%o0+P_ARG0] ! Store BIF__ARGS in def_arg_reg add %o0, P_ARG0, %o1 - call $2 + CALL_BIF($2) nop TEST_GOT_MBUF @@ -94,7 +101,7 @@ $1: st %o1, [%o0+P_ARG0] ! Store BIF__ARGS in def_arg_reg st %o2, [%o0+P_ARG1] add %o0, P_ARG0, %o1 - call $2 + CALL_BIF($2) nop TEST_GOT_MBUF @@ -125,7 +132,7 @@ $1: st %o2, [%o0+P_ARG1] st %o3, [%o0+P_ARG2] add %o0, P_ARG0, %o1 - call $2 + CALL_BIF($2) nop TEST_GOT_MBUF @@ -150,7 +157,7 @@ $1: /* Save caller-save registers and call the C function. */ SAVE_CONTEXT_BIF /* ignore empty BIF__ARGS */ - call $2 + CALL_BIF($2) nop TEST_GOT_MBUF @@ -184,7 +191,7 @@ $1: /* Save caller-save registers and call the C function. */ SAVE_CONTEXT_GC /* ignore empty BIF__ARGS */ - call $2 + CALL_BIF($2) nop TEST_GOT_MBUF @@ -210,7 +217,7 @@ $1: SAVE_CONTEXT_GC st %o1, [%o0+P_ARG0] ! Store BIF__ARGS in def_arg_reg add %o0, P_ARG0, %o1 - call $2 + CALL_BIF($2) nop TEST_GOT_MBUF @@ -239,7 +246,7 @@ $1: st %o1, [%o0+P_ARG0] ! Store BIF__ARGS in def_arg_reg st %o2, [%o0+P_ARG1] add %o0, P_ARG0, %o1 - call $2 + CALL_BIF($2) nop TEST_GOT_MBUF diff --git a/erts/emulator/hipe/hipe_x86_bifs.m4 b/erts/emulator/hipe/hipe_x86_bifs.m4 index dca5721c29..2ea69bde3c 100644 --- a/erts/emulator/hipe/hipe_x86_bifs.m4 +++ b/erts/emulator/hipe/hipe_x86_bifs.m4 @@ -20,6 +20,7 @@ changecom(`/*', `*/')dnl include(`hipe/hipe_x86_asm.m4') +#`include' "config.h" #`include' "hipe_literals.h" `#if THE_NON_VALUE == 0 @@ -28,6 +29,12 @@ include(`hipe/hipe_x86_asm.m4') #define TEST_GOT_EXN cmpl $THE_NON_VALUE,%eax #endif' +`#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP) +# define CALL_BIF(F) movl $CSYM(F), P_BIF_CALLEE(P); call CSYM(hipe_debug_bif_wrapper) +#else +# define CALL_BIF(F) call CSYM(F) +#endif' + define(TEST_GOT_MBUF,`movl P_MBUF(P), %edx # `TEST_GOT_MBUF' testl %edx, %edx jnz 3f @@ -64,7 +71,7 @@ ASYM($1): NBIF_ARG(2,1,0) lea 8(%esp), %eax NBIF_ARG_REG(1,%eax) # BIF__ARGS - call CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* switch to native stack */ @@ -99,7 +106,7 @@ ASYM($1): NBIF_ARG(3,2,1) lea 8(%esp), %eax NBIF_ARG_REG(1,%eax) # BIF__ARGS - call CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* switch to native stack */ @@ -135,7 +142,7 @@ ASYM($1): NBIF_ARG(4,3,2) lea 8(%esp), %eax NBIF_ARG_REG(1,%eax) # BIF__ARGS - call CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* switch to native stack */ @@ -164,7 +171,7 @@ ASYM($1): /* make the call on the C stack */ NBIF_ARG_REG(0,P) /* skip BIF__ARGS */ - call CSYM($2) + CALL_BIF($2) TEST_GOT_MBUF /* switch to native stack */ -- cgit v1.2.3