aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2012-02-23 14:54:58 +0100
committerSverker Eriksson <[email protected]>2012-02-23 14:54:58 +0100
commit738c6d54dde1e4c8f6030690eabe50a287301eb9 (patch)
tree61f725e364cd65b8c16204b83536e8ccb3af56ff /lib
parent225da20b097ad73291cf48ba2782c64762163a46 (diff)
parent99c0207298251d5557335864f15547ca07a7b050 (diff)
downloadotp-738c6d54dde1e4c8f6030690eabe50a287301eb9.tar.gz
otp-738c6d54dde1e4c8f6030690eabe50a287301eb9.tar.bz2
otp-738c6d54dde1e4c8f6030690eabe50a287301eb9.zip
Merge branch 'sverk/hipe-debug-cherries'
* sverk/hipe-debug-cherries: hipe,erts: Add DEBUG support with MFA's in stack descriptors hipe: Fix address_to_mfa in hipe loader hipe,erts: Debug support for native call trace erts: Make erts_printf accept internal match states
Diffstat (limited to 'lib')
-rw-r--r--lib/hipe/cerl/erl_bif_types.erl2
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl32
-rw-r--r--lib/hipe/icode/hipe_icode_primops.erl8
-rw-r--r--lib/hipe/rtl/hipe_rtl_primops.erl2
-rw-r--r--lib/kernel/src/hipe_unified_loader.erl40
5 files changed, 69 insertions, 15 deletions
diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl
index bb9dc44a0c..3d1e3e8137 100644
--- a/lib/hipe/cerl/erl_bif_types.erl
+++ b/lib/hipe/cerl/erl_bif_types.erl
@@ -2381,7 +2381,7 @@ arg_types(hipe_bifs, check_crc, 1) ->
arg_types(hipe_bifs, enter_code, 2) ->
[t_binary(), t_sup(t_nil(), t_tuple())];
arg_types(hipe_bifs, enter_sdesc, 1) ->
- [t_tuple([t_integer(), t_integer(), t_integer(), t_integer(), t_integer()])];
+ [t_tuple([t_integer(), t_integer(), t_integer(), t_integer(), t_integer(), t_mfa()])];
arg_types(hipe_bifs, find_na_or_make_stub, 2) ->
[t_mfa(), t_boolean()];
arg_types(hipe_bifs, fun_to_address, 1) ->
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index 2d2b414a70..35a8ce9cfe 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -41,6 +41,9 @@
%%
%%-ifndef(DEBUG).
%%-define(DEBUG,6).
+%% Choose one of two tracing methods
+%%-define(DEBUG_BIF_CALL_TRACE,true).
+%%-define(IO_FORMAT_CALL_TRACE,true).
%%-endif.
-include("../main/hipe.hrl").
@@ -51,8 +54,27 @@
-define(no_debug_msg(Str,Xs),ok).
%%-define(no_debug_msg(Str,Xs),msg(Str,Xs)).
--define(mk_debugcode(MFA, Env, Code),
- case MFA of
+-ifdef(DEBUG_BIF_CALL_TRACE).
+
+%% Use BIF hipe_bifs_debug_native_called_2 to trace function calls
+mk_debug_calltrace({_M,_F,A}=MFA, Env, Code) ->
+ MFAVar = mk_var(new),
+ Ignore = mk_var(new),
+ MkMfa = hipe_icode:mk_move(MFAVar,hipe_icode:mk_const(MFA)),
+ Args = [mk_var({x,I-1}) || I <- lists:seq(1,A)],
+ ArgTup = mk_var(new),
+ MkArgTup = hipe_icode:mk_primop([ArgTup], mktuple, Args),
+ Call = hipe_icode:mk_primop([Ignore], debug_native_called,
+ [MFAVar,ArgTup]),
+ {[MkMfa,MkArgTup,Call | Code], Env}.
+
+-endif.
+
+-ifdef(IO_FORMAT_CALL_TRACE).
+
+%% Use io:format to trace function calls
+mk_debug_calltrace(MFA, Env, Code) ->
+ case MFA of
{io,_,_} ->
%% We do not want to loop infinitely if we are compiling
%% the module io.
@@ -69,7 +91,9 @@
Call =
hipe_icode:mk_call([Ignore],io,format,[StringVar,MFAVar],remote),
{[MkMfa,MkString,Call | Code], Env}
- end).
+ end.
+-endif.
+
%%-----------------------------------------------------------------------
%% Exported types
@@ -127,7 +151,7 @@ trans_mfa_code(M,F,A, FunBeamCode, ClosureInfo) ->
MFA = {M,F,A},
%% Debug code
?IF_DEBUG_LEVEL(5,
- {Code3,_Env3} = ?mk_debugcode(MFA, Env2, Code2),
+ {Code3,_Env3} = mk_debug_calltrace(MFA, Env1, Code2),
{Code3,_Env3} = {Code2,Env1}),
%% For stack optimization
Leafness = leafness(Code3),
diff --git a/lib/hipe/icode/hipe_icode_primops.erl b/lib/hipe/icode/hipe_icode_primops.erl
index a413531c07..b0113fc556 100644
--- a/lib/hipe/icode/hipe_icode_primops.erl
+++ b/lib/hipe/icode/hipe_icode_primops.erl
@@ -137,7 +137,8 @@ is_safe({hipe_bs_primop, {bs_private_append, _, _}}) -> false;
is_safe({hipe_bs_primop, bs_init_writable}) -> true;
is_safe(#mkfun{}) -> true;
is_safe(#unsafe_element{}) -> true;
-is_safe(#unsafe_update_element{}) -> true.
+is_safe(#unsafe_update_element{}) -> true;
+is_safe(debug_native_called) -> false.
-spec fails(icode_funcall()) -> boolean().
@@ -237,6 +238,7 @@ fails({hipe_bs_primop, bs_init_writable}) -> true;
fails(#mkfun{}) -> false;
fails(#unsafe_element{}) -> false;
fails(#unsafe_update_element{}) -> false;
+fails(debug_native_called) -> false;
%% Apparently, we are calling fails/1 for all MFAs which are compiled.
%% This is weird and we should restructure the compiler to avoid
%% calling fails/1 for things that are not primops.
@@ -721,6 +723,8 @@ type(Primop, Args) ->
erl_types:t_any();
redtest ->
erl_types:t_any();
+ debug_native_called ->
+ erl_types:t_any();
{M, F, A} ->
erl_bif_types:type(M, F, A, Args)
end.
@@ -893,6 +897,8 @@ type(Primop) ->
erl_types:t_any();
redtest ->
erl_types:t_any();
+ debug_native_called ->
+ erl_types:t_any();
{M, F, A} ->
erl_bif_types:type(M, F, A)
end.
diff --git a/lib/hipe/rtl/hipe_rtl_primops.erl b/lib/hipe/rtl/hipe_rtl_primops.erl
index 5f273d8251..53aaa72aa6 100644
--- a/lib/hipe/rtl/hipe_rtl_primops.erl
+++ b/lib/hipe/rtl/hipe_rtl_primops.erl
@@ -396,6 +396,8 @@ gen_primop({Op,Dst,Args,Cont,Fail}, IsGuard, ConstTab) ->
[Dst1]->
hipe_tagscheme:unsafe_tag_float(Dst1, Arg)
end;
+ debug_native_called ->
+ [hipe_rtl:mk_call(Dst, Op, Args, Cont, Fail, not_remote)];
%% Only names listed above are accepted! MFA:s are not primops!
_ ->
diff --git a/lib/kernel/src/hipe_unified_loader.erl b/lib/kernel/src/hipe_unified_loader.erl
index 1b56cd8d90..cedaaf4f7e 100644
--- a/lib/kernel/src/hipe_unified_loader.erl
+++ b/lib/kernel/src/hipe_unified_loader.erl
@@ -503,7 +503,7 @@ patch_offset(Type, Data, Address, ConstAndZone, Addresses) ->
Atom = Data,
patch_atom(Address, Atom);
sdesc ->
- patch_sdesc(Data, Address, ConstAndZone);
+ patch_sdesc(Data, Address, ConstAndZone, Addresses);
x86_abs_pcrel ->
patch_instr(Address, Data, x86_abs_pcrel)
%% _ ->
@@ -516,14 +516,16 @@ patch_atom(Address, Atom) ->
patch_instr(Address, hipe_bifs:atom_to_word(Atom), atom).
patch_sdesc(?STACK_DESC(SymExnRA, FSize, Arity, Live),
- Address, {_ConstMap2,CodeAddress}) ->
+ Address, {_ConstMap2,CodeAddress}, _Addresses) ->
ExnRA =
case SymExnRA of
[] -> 0; % No catch
LabelOffset -> CodeAddress + LabelOffset
end,
?ASSERT(assert_local_patch(Address)),
- hipe_bifs:enter_sdesc({Address, ExnRA, FSize, Arity, Live}).
+ DBG_MFA = ?IF_DEBUG(address_to_mfa_lth(Address, _Addresses), {undefined,undefined,0}),
+ hipe_bifs:enter_sdesc({Address, ExnRA, FSize, Arity, Live, DBG_MFA}).
+
%%----------------------------------------------------------------
%% Handle a 'load_address'-type patch.
@@ -730,7 +732,7 @@ find_const(ConstNo, []) ->
%%
add_ref(CalleeMFA, Address, Addresses, RefType, Trampoline, RemoteOrLocal) ->
- CallerMFA = address_to_mfa(Address, Addresses),
+ CallerMFA = address_to_mfa_lth(Address, Addresses),
%% just a sanity assertion below
true = case RemoteOrLocal of
local ->
@@ -743,11 +745,31 @@ add_ref(CalleeMFA, Address, Addresses, RefType, Trampoline, RemoteOrLocal) ->
%% io:format("Adding ref ~w\n",[{CallerMFA, CalleeMFA, Address, RefType}]),
hipe_bifs:add_ref(CalleeMFA, {CallerMFA,Address,RefType,Trampoline,RemoteOrLocal}).
-address_to_mfa(Address, [#fundef{address=Adr, mfa=MFA}|_Rest]) when Address >= Adr -> MFA;
-address_to_mfa(Address, [_ | Rest]) -> address_to_mfa(Address, Rest);
-address_to_mfa(Address, []) ->
- ?error_msg("Local adddress not found ~w\n",[Address]),
- exit({?MODULE, local_address_not_found}).
+% For FunDefs sorted from low to high addresses
+address_to_mfa_lth(Address, FunDefs) ->
+ case address_to_mfa_lth(Address, FunDefs, false) of
+ false ->
+ ?error_msg("Local adddress not found ~w\n",[Address]),
+ exit({?MODULE, local_address_not_found});
+ MFA ->
+ MFA
+ end.
+
+address_to_mfa_lth(Address, [#fundef{address=Adr, mfa=MFA}|Rest], Prev) ->
+ if Address < Adr ->
+ Prev;
+ true ->
+ address_to_mfa_lth(Address, Rest, MFA)
+ end;
+address_to_mfa_lth(_Address, [], Prev) ->
+ Prev.
+
+% For FunDefs sorted from high to low addresses
+%% address_to_mfa_htl(Address, [#fundef{address=Adr, mfa=MFA}|_Rest]) when Address >= Adr -> MFA;
+%% address_to_mfa_htl(Address, [_ | Rest]) -> address_to_mfa_htl(Address, Rest);
+%% address_to_mfa_htl(Address, []) ->
+%% ?error_msg("Local adddress not found ~w\n",[Address]),
+%% exit({?MODULE, local_address_not_found}).
%%----------------------------------------------------------------
%% Change callers of the given module to instead trap to BEAM.