diff options
Diffstat (limited to 'erts/emulator/hipe')
-rw-r--r-- | erts/emulator/hipe/hipe_bif0.c | 39 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_bif0.tab | 3 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_bif2.c | 11 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_bif2.tab | 1 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_bif_list.m4 | 24 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_debug.c | 1 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_mode_switch.c | 34 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_mode_switch.h | 3 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_native_bif.c | 17 | ||||
-rw-r--r-- | erts/emulator/hipe/hipe_x86_signal.c | 6 |
10 files changed, 100 insertions, 39 deletions
diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c index fa99c817f0..2497d51df1 100644 --- a/erts/emulator/hipe/hipe_bif0.c +++ b/erts/emulator/hipe/hipe_bif0.c @@ -1101,9 +1101,9 @@ BIF_RETTYPE hipe_bifs_make_fun_3(BIF_ALIST_3) #endif /* - * args: Nativecodeaddress, Module, {Uniq, Index, BeamAddress} + * args: Module, {Uniq, Index, BeamAddress} */ -BIF_RETTYPE hipe_bifs_make_fe_3(BIF_ALIST_3) +BIF_RETTYPE hipe_bifs_get_fe_2(BIF_ALIST_2) { Eterm mod; Uint index; @@ -1111,20 +1111,15 @@ BIF_RETTYPE hipe_bifs_make_fe_3(BIF_ALIST_3) void *beam_address; ErlFunEntry *fe; Eterm *tp; - void *native_address; - - native_address = term_to_address(BIF_ARG_1); - if (!native_address) - BIF_ERROR(BIF_P, BADARG); - if (is_not_atom(BIF_ARG_2)) + if (is_not_atom(BIF_ARG_1)) BIF_ERROR(BIF_P, BADARG); - mod = BIF_ARG_2; + mod = BIF_ARG_1; - if (is_not_tuple(BIF_ARG_3) || - (arityval(*tuple_val(BIF_ARG_3)) != 3)) + if (is_not_tuple(BIF_ARG_2) || + (arityval(*tuple_val(BIF_ARG_2)) != 3)) BIF_ERROR(BIF_P, BADARG); - tp = tuple_val(BIF_ARG_3); + tp = tuple_val(BIF_ARG_2); if (term_to_Uint(tp[1], &uniq) == 0) BIF_ERROR(BIF_P, BADARG); if (term_to_Uint(tp[2], &index) == 0) @@ -1144,10 +1139,28 @@ BIF_RETTYPE hipe_bifs_make_fe_3(BIF_ALIST_3) printf("no fun entry for %s %ld:%ld\n", atom_buf, uniq, index); BIF_ERROR(BIF_P, BADARG); } + BIF_RET(address_to_term((void *)fe, BIF_P)); +} + +/* + * args: FE, Nativecodeaddress + */ +BIF_RETTYPE hipe_bifs_set_native_address_in_fe_2(BIF_ALIST_2) +{ + ErlFunEntry *fe; + void *native_address; + + fe = (ErlFunEntry *)term_to_address(BIF_ARG_1); + if (!fe) + BIF_ERROR(BIF_P, BADARG); + native_address = term_to_address(BIF_ARG_2); + if (!native_address) + BIF_ERROR(BIF_P, BADARG); + fe->native_address = native_address; if (erts_refc_dectest(&fe->refc, 0) == 0) erts_erase_fun_entry(fe); - BIF_RET(address_to_term((void *)fe, BIF_P)); + BIF_RET(am_true); } #if 0 /* XXX: unused */ diff --git a/erts/emulator/hipe/hipe_bif0.tab b/erts/emulator/hipe/hipe_bif0.tab index ce641365e9..2514b1c3a5 100644 --- a/erts/emulator/hipe/hipe_bif0.tab +++ b/erts/emulator/hipe/hipe_bif0.tab @@ -69,7 +69,8 @@ bif hipe_bifs:atom_to_word/1 bif hipe_bifs:term_to_word/1 #bif hipe_bifs:make_fun/3 -bif hipe_bifs:make_fe/3 +bif hipe_bifs:get_fe/2 +bif hipe_bifs:set_native_address_in_fe/2 #bif hipe_bifs:make_native_stub/2 bif hipe_bifs:find_na_or_make_stub/2 diff --git a/erts/emulator/hipe/hipe_bif2.c b/erts/emulator/hipe/hipe_bif2.c index e09988e2c5..054911e822 100644 --- a/erts/emulator/hipe/hipe_bif2.c +++ b/erts/emulator/hipe/hipe_bif2.c @@ -31,6 +31,7 @@ #include "erl_process.h" #include "bif.h" #include "big.h" +#include "erl_map.h" #include "hipe_debug.h" #include "hipe_mode_switch.h" #include "hipe_arch.h" @@ -156,7 +157,8 @@ BIF_RETTYPE hipe_bifs_modeswitch_debug_off_0(BIF_ALIST_0) 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) + if ((P)) erts_proc_lc_require_lock((P), ERTS_PROC_LOCK_MAIN,\ + __FILE__, __LINE__) # define ERTS_SMP_UNREQ_PROC_MAIN_LOCK(P) \ if ((P)) erts_proc_lc_unrequire_lock((P), ERTS_PROC_LOCK_MAIN) @@ -180,3 +182,10 @@ BIF_RETTYPE hipe_bifs_debug_native_called_2(BIF_ALIST_2) BIF_RET(am_ok); } +/* Stub-BIF for LLVM: + * Reloads BP, SP (in llvm unwind label) */ + +BIF_RETTYPE hipe_bifs_llvm_fix_pinned_regs_0(BIF_ALIST_0) +{ + BIF_RET(am_ok); +} diff --git a/erts/emulator/hipe/hipe_bif2.tab b/erts/emulator/hipe/hipe_bif2.tab index 45a395bf57..1b659cfa90 100644 --- a/erts/emulator/hipe/hipe_bif2.tab +++ b/erts/emulator/hipe/hipe_bif2.tab @@ -30,3 +30,4 @@ bif hipe_bifs:in_native/0 bif hipe_bifs:modeswitch_debug_on/0 bif hipe_bifs:modeswitch_debug_off/0 bif hipe_bifs:debug_native_called/2 +bif hipe_bifs:llvm_fix_pinned_regs/0 diff --git a/erts/emulator/hipe/hipe_bif_list.m4 b/erts/emulator/hipe/hipe_bif_list.m4 index 764b8d180c..5f92b6bac4 100644 --- a/erts/emulator/hipe/hipe_bif_list.m4 +++ b/erts/emulator/hipe/hipe_bif_list.m4 @@ -1,7 +1,7 @@ /* * %CopyrightBegin% * - * Copyright Ericsson AB 2004-2012. All Rights Reserved. + * Copyright Ericsson AB 2004-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -151,10 +151,9 @@ standard_bif_interface_0(nbif_ports_0, ports_0) * BIFs and primops that may do a GC (change heap limit and walk the native stack). * XXX: erase/1 and put/2 cannot fail */ -gc_bif_interface_2(nbif_check_process_code_2, hipe_check_process_code_2) +gc_bif_interface_2(nbif_erts_internal_check_process_code_2, hipe_erts_internal_check_process_code_2) gc_bif_interface_1(nbif_erase_1, erase_1) gc_bif_interface_0(nbif_garbage_collect_0, garbage_collect_0) -gc_bif_interface_1(nbif_garbage_collect_1, hipe_garbage_collect_1) gc_nofail_primop_interface_1(nbif_gc_1, hipe_gc) gc_bif_interface_2(nbif_put_2, put_2) @@ -263,7 +262,24 @@ noproc_primop_interface_1(nbif_atomic_inc, hipe_atomic_inc) * Standard BIFs. * BIF_LIST(ModuleAtom,FunctionAtom,Arity,CFun,Index) */ -define(BIF_LIST,`standard_bif_interface_$3(nbif_$4, $4)') + +/* BIFs that disable GC while trapping are called via a wrapper + * to reserve stack space for the "trap frame". + */ +define(CFUN,`ifelse($1,term_to_binary_1,hipe_wrapper_term_to_binary_1, +ifelse($1,term_to_binary_2,hipe_wrapper_term_to_binary_2, +ifelse($1,binary_to_term_1,hipe_wrapper_binary_to_term_1, +ifelse($1,binary_to_term_2,hipe_wrapper_binary_to_term_2, +ifelse($1,binary_to_list_1,hipe_wrapper_binary_to_list_1, +ifelse($1,binary_to_list_3,hipe_wrapper_binary_to_list_3, +ifelse($1,bitstring_to_list_1,hipe_wrapper_bitstring_to_list_1, +ifelse($1,list_to_binary_1,hipe_wrapper_list_to_binary_1, +ifelse($1,iolist_to_binary_1,hipe_wrapper_iolist_to_binary_1, +ifelse($1,binary_list_to_bin_1,hipe_wrapper_binary_list_to_bin_1, +ifelse($1,list_to_bitstring_1,hipe_wrapper_list_to_bitstring_1, +$1)))))))))))') + +define(BIF_LIST,`standard_bif_interface_$3(nbif_$4, CFUN($4))') include(TARGET/`erl_bif_list.h') /* diff --git a/erts/emulator/hipe/hipe_debug.c b/erts/emulator/hipe/hipe_debug.c index bf25ba82af..32694a8f97 100644 --- a/erts/emulator/hipe/hipe_debug.c +++ b/erts/emulator/hipe/hipe_debug.c @@ -36,6 +36,7 @@ #include "beam_load.h" #include "hipe_mode_switch.h" #include "hipe_debug.h" +#include "erl_map.h" static const char dashes[2*sizeof(long)+5] = { [0 ... 2*sizeof(long)+3] = '-' diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c index adc8793469..4ddc2790b1 100644 --- a/erts/emulator/hipe/hipe_mode_switch.c +++ b/erts/emulator/hipe/hipe_mode_switch.c @@ -37,7 +37,8 @@ #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) + if ((P)) erts_proc_lc_require_lock((P), ERTS_PROC_LOCK_MAIN, \ + __FILE__, __LINE__) # define ERTS_SMP_UNREQ_PROC_MAIN_LOCK(P) \ if ((P)) erts_proc_lc_unrequire_lock((P), ERTS_PROC_LOCK_MAIN) #else @@ -184,21 +185,46 @@ void hipe_set_call_trap(Uint *bfun, void *nfun, int is_closure) bfun[-4] = (Uint)nfun; } -static __inline__ void -hipe_push_beam_trap_frame(Process *p, Eterm reg[], unsigned arity) +void hipe_reserve_beam_trap_frame(Process *p, Eterm reg[], unsigned arity) { /* ensure that at least 2 words are available on the BEAM stack */ if ((p->stop - 2) < p->htop) { - DPRINTF("calling gc to increase BEAM stack size"); + DPRINTF("calling gc to reserve BEAM stack size"); p->fcalls -= erts_garbage_collect(p, 2, reg, arity); + ASSERT(!((p->stop - 2) < p->htop)); } p->stop -= 2; + p->stop[0] = NIL; + p->stop[1] = NIL; +} + +static __inline__ void +hipe_push_beam_trap_frame(Process *p, Eterm reg[], unsigned arity) +{ + if (p->flags & F_DISABLE_GC) { + /* Trap frame already reserved */ + ASSERT(p->stop[0] == NIL && p->stop[1] == NIL); + } + else { + if ((p->stop - 2) < p->htop) { + DPRINTF("calling gc to increase BEAM stack size"); + p->fcalls -= erts_garbage_collect(p, 2, reg, arity); + ASSERT(!((p->stop - 2) < p->htop)); + } + p->stop -= 2; + } p->stop[1] = hipe_beam_catch_throw; p->stop[0] = make_cp(p->cp); ++p->catches; p->cp = hipe_beam_pc_return; } +void hipe_unreserve_beam_trap_frame(Process *p) +{ + ASSERT(p->stop[0] == NIL && p->stop[1] == NIL); + p->stop += 2; +} + static __inline__ void hipe_pop_beam_trap_frame(Process *p) { p->cp = cp_val(p->stop[0]); diff --git a/erts/emulator/hipe/hipe_mode_switch.h b/erts/emulator/hipe/hipe_mode_switch.h index a3e908a3b3..06721e3c04 100644 --- a/erts/emulator/hipe/hipe_mode_switch.h +++ b/erts/emulator/hipe/hipe_mode_switch.h @@ -59,6 +59,9 @@ void hipe_empty_nstack(Process *p); void hipe_set_closure_stub(ErlFunEntry *fe, unsigned num_free); Eterm hipe_build_stacktrace(Process *p, struct StackTrace *s); +void hipe_reserve_beam_trap_frame(Process*, Eterm reg[], unsigned arity); +void hipe_unreserve_beam_trap_frame(Process*); + extern Uint hipe_beam_pc_return[]; extern Uint hipe_beam_pc_throw[]; extern Uint hipe_beam_pc_resume[]; diff --git a/erts/emulator/hipe/hipe_native_bif.c b/erts/emulator/hipe/hipe_native_bif.c index 1f76268934..7d343dd91e 100644 --- a/erts/emulator/hipe/hipe_native_bif.c +++ b/erts/emulator/hipe/hipe_native_bif.c @@ -41,8 +41,7 @@ */ /* for -Wmissing-prototypes :-( */ -extern Eterm hipe_check_process_code_2(BIF_ALIST_2); -extern Eterm hipe_garbage_collect_1(BIF_ALIST_1); +extern Eterm hipe_erts_internal_check_process_code_2(BIF_ALIST_2); extern Eterm hipe_show_nstack_1(BIF_ALIST_1); /* Used when a BIF can trigger a stack walk. */ @@ -51,22 +50,12 @@ static __inline__ void hipe_set_narity(Process *p, unsigned int arity) p->hipe.narity = arity; } -Eterm hipe_check_process_code_2(BIF_ALIST_2) +Eterm hipe_erts_internal_check_process_code_2(BIF_ALIST_2) { Eterm ret; hipe_set_narity(BIF_P, 2); - ret = check_process_code_2(BIF_P, BIF__ARGS); - hipe_set_narity(BIF_P, 0); - return ret; -} - -Eterm hipe_garbage_collect_1(BIF_ALIST_1) -{ - Eterm ret; - - hipe_set_narity(BIF_P, 1); - ret = garbage_collect_1(BIF_P, BIF__ARGS); + ret = erts_internal_check_process_code_2(BIF_P, BIF__ARGS); hipe_set_narity(BIF_P, 0); return ret; } diff --git a/erts/emulator/hipe/hipe_x86_signal.c b/erts/emulator/hipe/hipe_x86_signal.c index 8f997aafab..f5668013e2 100644 --- a/erts/emulator/hipe/hipe_x86_signal.c +++ b/erts/emulator/hipe/hipe_x86_signal.c @@ -2,7 +2,7 @@ * %CopyrightBegin% * - * Copyright Ericsson AB 2001-2013. All Rights Reserved. + * Copyright Ericsson AB 2001-2014. All Rights Reserved. * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in @@ -304,7 +304,9 @@ static void hipe_sigaltstack(void *ss_sp) */ void hipe_thread_signal_init(void) { - hipe_sigaltstack(erts_alloc(ERTS_ALC_T_HIPE, SIGSTKSZ)); + /* Stack don't really need to be cache aligned. + We use it to suppress false leak report from valgrind */ + hipe_sigaltstack(erts_alloc_permanent_cache_aligned(ERTS_ALC_T_HIPE, SIGSTKSZ)); } #endif |