Changes between Version 1 and Version 2 of DynamicCallAnalysis


Ignore:
Timestamp:
Sep 21, 2012, 1:13:12 PM (12 years ago)
Author:
manualwiki
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • DynamicCallAnalysis

    v1 v2  
    4545ri:clean_dyn(). 
    4646}}} 
     47 
     48{{{#!comment 
     49 
     50== Configurable dynamic function analyzer == 
     51 
     52Dynamic function analyzer was extended to handle user defined functions that has semantics similar to apply BIF. 
     53 
     54In Erlang it is sometimes preferable to use custom functions that act as a wrapper for a simple apply.  
     55For example for load distribution among different Erlang nodes. Or implementing callback functions. 
     56 
     57=== Small example === 
     58 
     59Consider the following small example. 
     60 
     61The module which is going to be analyzed. 
     62{{{#!erlang 
     63-module(dynfun_example). 
     64-compile(export_all). 
     65 
     66a()-> 
     67    1. 
     68 
     69b()-> 
     70    erlang:apply(?MODULE, a, []). 
     71}}} 
     72 
     73The configuration file, which is located at the tool root, and is called {{{dynfunref.conf}}}: 
     74{{{#!erlang 
     75{ 
     76{erlang, apply}, 
     77['$1', '$2', '$3'], 
     78[{'$1', '$2', '$3'}] 
     79}. 
     80}}} 
     81 
     82The result: 
     83{{{#!erlang 
     84(refactorerl@localhost)8> ri:reset().                           
     85{ok,[]} 
     86ok 
     87(refactorerl@localhost)9> ri:add("/Users/V/erlang/dynfun_766"). 
     88| 1.22 kB/s >>>>>>>>>>>>>>>>>>>| [   4/   4] dynfun_example.erl 
     89ok 
     90(refactorerl@localhost)10> ri:q("mods.funs.dyncalls").           
     91ok 
     92(refactorerl@localhost)11> ri:anal_dyn().                        
     93Function reference patterns loaded (1, dynfunref.conf) 
     94 
     95Analysing local funs... (0 done).                                               
     96Collecting function calls... 
     971 function calls found in the database. 
     98Looking for dynamic references... 
     991 dynamic function references found. 
     100Inspecting dynamic references... (1/1) 
     1011 potential callee successfully spotted. 
     102Storing dynamic references... (1/1) 
     103Updating the call graph... (1/1) 
     104 
     105Analysis completed. 
     106ok 
     107(refactorerl@localhost)12> ri:q("mods.funs.dyncalls").           
     108dynfun_example:b/0 
     109    dynfun_example:a/0 
     110ok 
     111}}} 
     112 
     113A user-defined references to link from the original function call was made.  
     114 
     115=== How to specify a valid Erlang match specification === 
     116{{{#!erlang 
     117{ 
     118{erlang, apply},       %analyzed module and function 
     119['$1', '$2', '$3'],    %match 
     120[{'$1', '$2', '$3'}]   %where to link (an exact function) 
     121}. 
     122}}} 
     123The first element of the tuple is a tuple, which first element is the name of the module in which the analyzed function is located. The name of the function is at the second element.  
     124The second element is a list of match specs. Its length equals to the arity of the analyzed function.  
     125The third argument is a list of mappings represented by tuples. One element of a mapping is a 3-tuple representing an exact function. The third element is represent arity rather than agrments. 
     126 
     127=== Another example === 
     128Consider the following 2 module. 
     129{{{#!erlang 
     130-module(router). 
     131-export([route/2]). 
     132 
     133route(ReqID, Args)-> 
     134    [Function | Args0] = tuple_to_list(Args), 
     135    Master =self(),     
     136    Worker = fun()-> 
     137        Result = try 
     138            apply(router_backend, Function, [ReqID]++Args0) 
     139        catch 
     140            _ -> error 
     141        end, 
     142        Master ! {ReqID, Result} 
     143        end, 
     144    spawn(Worker), 
     145    receive 
     146         {ReqID, Result} -> Result 
     147    end. 
     148     
     149ex_call()-> 
     150    route(1, {a}). 
     151 
     152ex_call2()-> 
     153    route(2,{b,1}). 
     154}}} 
     155 
     156{{{#!erlang 
     157-module(router_backend). 
     158-compile(export_all). 
     159 
     160a(_)-> 
     161    2. 
     162 
     163b(_,A)-> 
     164    A+1. 
     165}}} 
     166 
     167The configuration file: 
     168{{{#!erlang 
     169%will link router_backend:a/1 to router:ex_call/0 
     170{{router,route}, 
     171['_', {'$1'}], 
     172[ 
     173    {router_backend, '$1', 1} 
     174]}. 
     175 
     176%will link router_backend:b/2 to router:ex_call2/0 
     177{{router,route}, 
     178['_', {'$1','_'}], 
     179[ 
     180    {router_backend, '$1', 2} 
     181]}. 
     182}}} 
     183 
     184 
     185The result: 
     186{{{#!erlang 
     187(refactorerl@localhost)26> ri:reset().                            
     188{ok,[]} 
     189ok 
     190(refactorerl@localhost)27> ri:add("/Users/V/erlang/mini_router"). 
     191| 1.12 kB/s >>>>>>>>>>>>>>>>>>>| [   4/   4] router.erl 
     192| 1.18 kB/s >>>>>>>>>>>>>>>>>>>| [   4/   4] router_backend.erl 
     193ok 
     194(refactorerl@localhost)28> ri:anal_dyn(). 
     195Function reference patterns loaded (2, dynfunref.conf) 
     196 
     197Analysing local funs... (1 done).                                               
     198Collecting function calls... 
     1996 function calls found in the database. 
     200Looking for dynamic references... 
     2015 dynamic function references found. 
     202Inspecting dynamic references... (5/5) 
     2033 potential callee successfully spotted. 
     204Storing dynamic references... (3/3) 
     205Updating the call graph... (3/3) 
     206 
     207Analysis completed. 
     208ok 
     209(refactorerl@localhost)29> ri:q("mods.funs.dyncalls"). 
     210router:ex_call/0 
     211    router_backend:a/1 
     212router:ex_call2/0 
     213    router_backend:b/2 
     214ok 
     215}}} 
     216 
     217A dynamic function reference were made to link {{{router_backend:a/1}}} to {{{router:ex_call/0 }}}, 
     218and to link {{{router_backend:b/2}}} to {{{router:ex_call2/0}}}. 
     219}}}