From 8df7d196b1bc491debb677779def8a317f95ad5c Mon Sep 17 00:00:00 2001 From: Kostis Sagonas Date: Tue, 12 Mar 2013 18:22:07 +0100 Subject: 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. --- lib/hipe/icode/hipe_icode_coordinator.erl | 18 ++++++++---------- 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, -- cgit v1.2.3