diff options
author | Kostis Sagonas <[email protected]> | 2013-03-12 18:22:07 +0100 |
---|---|---|
committer | Kostis Sagonas <[email protected]> | 2013-03-12 18:22:07 +0100 |
commit | 8df7d196b1bc491debb677779def8a317f95ad5c (patch) | |
tree | 94b6c189aed45bf0656baffa1038266851d8ed56 | |
parent | bec7094e6b238774997bcb12f308f7f5bfadf160 (diff) | |
download | otp-8df7d196b1bc491debb677779def8a317f95ad5c.tar.gz otp-8df7d196b1bc491debb677779def8a317f95ad5c.tar.bz2 otp-8df7d196b1bc491debb677779def8a317f95ad5c.zip |
Loosen the assumptions of code that handles escaping functions
The HiPE compiler implicitly relied on the assumption that a function
will never appear as both exported and also used as function closure.
This was true because the BEAM compiler prior to R16B created module
local anonymous functions for each closure. A proposed change to the
BEAM compiler invalidates this invariant, so in order to accommodate
for this change there needs to be a change of how the set of possibly
escaping functions is computed.
While doing this, the code was simplified by taking out a boolean()
tag that indicated whether a function is a closure or exported and
also slightly cleaned up the affected modules.
-rw-r--r-- | lib/hipe/icode/hipe_icode_coordinator.erl | 18 | ||||
-rw-r--r-- | lib/hipe/main/hipe.erl | 21 |
2 files changed, 19 insertions, 20 deletions
diff --git a/lib/hipe/icode/hipe_icode_coordinator.erl b/lib/hipe/icode/hipe_icode_coordinator.erl index d8c82cf01c..79e3304e6f 100644 --- a/lib/hipe/icode/hipe_icode_coordinator.erl +++ b/lib/hipe/icode/hipe_icode_coordinator.erl @@ -2,7 +2,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2011. All Rights Reserved. +%% Copyright Ericsson AB 2007-2013. 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 @@ -36,18 +36,16 @@ %%--------------------------------------------------------------------- --spec coordinate(hipe_digraph:hdg(), [{mfa(),boolean()}], [mfa()], module()) -> +-spec coordinate(hipe_digraph:hdg(), [mfa()], [mfa()], module()) -> no_return(). coordinate(CG, Escaping, NonEscaping, Mod) -> ServerPid = initialize_server(Escaping, Mod), - Clean = [MFA || {MFA, _} <- Escaping], - All = NonEscaping ++ Clean, - Restart = - fun (MFALists, PM) -> restart_funs(MFALists, PM, All, ServerPid) end, - LastAction = - fun (PM) -> last_action(PM, ServerPid, Mod, All) end, - coordinate({Clean,All}, CG, gb_trees:empty(), Restart, LastAction, ServerPid). + All = ordsets:from_list(Escaping ++ NonEscaping), + Restart = fun (MFALs, PM) -> restart_funs(MFALs, PM, All, ServerPid) end, + LastAction = fun (PM) -> last_action(PM, ServerPid, Mod, All) end, + MFALists = {Escaping, All}, + coordinate(MFALists, CG, gb_trees:empty(), Restart, LastAction, ServerPid). -type mfalists() :: {[mfa()], [mfa()]}. @@ -129,7 +127,7 @@ restart_funs({Queue, Busy} = QB, PM, All, ServerPid) -> initialize_server(Escaping, Mod) -> Pid = spawn_link(fun () -> info_server(Mod) end), - lists:foreach(fun ({MFA, _}) -> Pid ! {set_escaping, MFA} end, Escaping), + lists:foreach(fun (MFA) -> Pid ! {set_escaping, MFA} end, Escaping), Pid. safe_get_args(MFA, Cfg, Pid, Mod) -> diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl index 6e00b13292..434d5c3061 100644 --- a/lib/hipe/main/hipe.erl +++ b/lib/hipe/main/hipe.erl @@ -2,7 +2,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2001-2012. All Rights Reserved. +%% Copyright Ericsson AB 2001-2013. 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 @@ -242,8 +242,7 @@ %% %% @see load/2 --spec load(Mod) -> {'module', Mod} | {'error', term()} - when is_subtype(Mod, mod()). +-spec load(Mod) -> {'module', Mod} | {'error', term()} when Mod :: mod(). load(Mod) -> load(Mod, beam_file(Mod)). @@ -265,7 +264,7 @@ load(Mod) -> %% @see load/1 -spec load(Mod, string()) -> {'module', Mod} | {'error', term()} - when is_subtype(Mod, mod()). + when Mod :: mod(). load(Mod, BeamFileName) when is_list(BeamFileName) -> Architecture = erlang:system_info(hipe_architecture), @@ -522,7 +521,7 @@ compile(Name, Core, File, Opts) when is_atom(Name) -> %% @equiv file(File, []) -spec file(Mod) -> {'ok', Mod, compile_ret()} | {'error', term()} - when is_subtype(Mod, mod()). + when Mod :: mod(). file(File) -> file(File, []). @@ -542,7 +541,7 @@ file(File) -> -spec file(Mod, comp_options()) -> {'ok', Mod, compile_ret()} | {'error', term()} - when is_subtype(Mod, mod()). + when Mod :: mod(). file(File, Options) when is_atom(File) -> case beam_lib:info(File) of L when is_list(L) -> @@ -760,13 +759,15 @@ finalize_fun_concurrent(MfaIcodeList, Exports, Opts) -> case MfaIcodeList of [{{M,_,_},_}|_] -> CallGraph = hipe_icode_callgraph:construct_callgraph(MfaIcodeList), - Closures = [{MFA, true} || {MFA, Icode} <- MfaIcodeList, - hipe_icode:icode_is_closure(Icode)], - Exported = [{{M, F, A}, false} || {F, A} <- Exports], + Exported = [{M, F, A} || {F, A} <- Exports], + Closures = [MFA || {MFA, Icode} <- MfaIcodeList, + hipe_icode:icode_is_closure(Icode)], + %% In principle, a function could both be exported and used as a + %% closure so make sure to add it only once in Escaping below + Escaping = ordsets:from_list(Exported ++ Closures), NonEscaping = [MFA || {{_M, F, A} = MFA, Icode} <- MfaIcodeList, not lists:member({F, A}, Exports), not hipe_icode:icode_is_closure(Icode)], - Escaping = Closures ++ Exported, TypeServerFun = fun() -> hipe_icode_coordinator:coordinate(CallGraph, Escaping, |