浏览 2425 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-09-21
最后修改:2009-09-21
erlang的VM作为register based的VM, 大概有400条指令.指令分为hot, normal, cold 3大类别。beam_emu.c是vm的实现,hot和cold指令在编译的时候 由脚本生成的,include到beam_emu去的。 hot是热门的操作如list, tuple操作, cold的就是比较偏的指令。 erlang的编译器支持生成汇编码, 让我们的研究成可能,具体用法是 erlc +"'S'" m.erl 会生成m.S 这个汇编文件. root@nd-desktop:~# cat gram.erl -module(gram). -export([start/1]). start([X])-> %% bif X1 = list_to_integer(atom_to_list(X)), %% list W =[1,2,3], W1 = [4|W], K=[W1,9], %% constant fold A = 1 + 2, %% if B = if X1 + A > 0 -> 5; true -> 4 end, %% case C = case B of {x, T} -> T; 5 -> a1; 3 -> a2; 2 -> 1.0; other -> 2; true -> 3 end, %% receive D = receive a1 -> 2 + 1.2; 2 -> 3; {tag, N}->N; a2 -> 5; _ -> ok after A -> timeout end, %% anon fun E = fun (1)-> D; (x)-> 2; (y)-> C; (<<"12">>)->1; (_) -> error end, F = E(D), %% fun G = f(B), io:format("~p~p~p~p~n",[F, G,W,K]), done. f(1)-> 1; f(2) ->2; f(3) ->3; f(4) ->4; f(5) ->5; f(x1) ->1; f(x2) ->2; f(x3) ->3; f(x4) ->4; f(x5) ->5; f({x,1}) -> 1; f({x,2}) ->2; f({x,3}) ->3; f({x,4}) ->4; f({x,5}) ->5; f(<<1:8, X:32, "xyz", F/float>>) -> {X, F}; f(_) -> err. root@nd-desktop:~# erlc +"'S'" gram.erl root@nd-desktop:~# cat gram.S {module, gram}. %% version = 0 {exports, [{module_info,0},{module_info,1},{start,1}]}. {attributes, []}. {labels, 45}. %%每个标签是跳转地址 %%每个指令对应这相应的opcode,在beam_emu中都可以找到。 {function, start, 1, 2}. {label,1}. {func_info,{atom,gram},{atom,start},1}. {label,2}. {test,is_nonempty_list,{f,1},[{x,0}]}. {get_list,{x,0},{x,1},{x,2}}. {test,is_nil,{f,1},[{x,2}]}. {allocate_zero,2,2}. {move,{x,1},{x,0}}. %% bif调用 {call_ext,1,{extfunc,erlang,atom_to_list,1}}. {call_ext,1,{extfunc,erlang,list_to_integer,1}}. %% 符号也是bif %% 3= 1 +2 const fold {gc_bif,'+',{f,3},1,[{x,0},{integer,3}],{x,1}}. %% if 语句是如此简单 {test,is_lt,{f,3},[{integer,0},{x,1}]}. {move,{integer,5},{x,0}}. {jump,{f,4}}. {label,3}. {move,{integer,4},{x,0}}. {label,4}. {move,{x,0},{y,1}}. %% case语句同样是个if else的判断 %% tuple是如何匹配的 效率高 {test,is_tuple,{f,5},[{x,0}]}. {test,test_arity,{f,21},[{x,0},2]}. {get_tuple_element,{x,0},0,{x,1}}. {get_tuple_element,{x,0},1,{x,2}}. {test,is_eq_exact,{f,21},[{x,1},{atom,x}]}. {move,{x,2},{x,0}}. {jump,{f,12}}. {label,5}. {test,is_atom,{f,8},[{x,0}]}. %% 2分查找 {select_val,{x,0},{f,21},{list,[{atom,true},{f,6},{atom,other},{f,7}]}}. {label,6}. {move,{integer,3},{x,0}}. {jump,{f,12}}. {label,7}. {move,{integer,2},{x,0}}. {jump,{f,12}}. {label,8}. {test,is_integer,{f,21},[{x,0}]}. %% 编译器会聪明的做这类事情 {select_val,{x,0}, {f,21}, {list,[{integer,2}, {f,9}, {integer,3}, {f,10}, {integer,5}, {f,11}]}}. {label,9}. {move,{float,1.0},{x,0}}. {jump,{f,12}}. {label,10}. {move,{atom,a2},{x,0}}. {jump,{f,12}}. {label,11}. {move,{atom,a1},{x,0}}. {label,12}. {move,{x,0},{y,0}}. %% receive语句 {label,13}. {loop_rec,{f,19},{x,0}}. {test,is_tuple,{f,14},[{x,0}]}. {test,test_arity,{f,18},[{x,0},2]}. {get_tuple_element,{x,0},0,{x,1}}. {get_tuple_element,{x,0},1,{x,2}}. {test,is_eq_exact,{f,18},[{x,1},{atom,tag}]}. %%从消息队列移除 remove_message. {move,{x,2},{x,0}}. {jump,{f,20}}. {label,14}. {test,is_atom,{f,17},[{x,0}]}. {select_val,{x,0},{f,18},{list,[{atom,a2},{f,15},{atom,a1},{f,16}]}}. {label,15}. remove_message. {move,{integer,5},{x,0}}. {jump,{f,20}}. {label,16}. remove_message. {move,{float,3.2},{x,0}}. {jump,{f,20}}. {label,17}. {test,is_eq_exact,{f,18},[{x,0},{integer,2}]}. remove_message. {move,{integer,3},{x,0}}. {jump,{f,20}}. {label,18}. remove_message. {move,{atom,ok},{x,0}}. {jump,{f,20}}. {label,19}. %% timeout添加到定时器 {wait_timeout,{f,13},{integer,3}}. timeout. {move,{atom,timeout},{x,0}}. {label,20}. %% 闭包 {move,{x,0},{x,1}}. {move,{y,0},{x,0}}. {move,{x,1},{y,0}}. {make_fun2,{f,39},0,133275192,2}. {move,{x,0},{x,1}}. {move,{y,0},{x,0}}. {trim,1,1}. {call_fun,1}. {move,{x,0},{x,1}}. {move,{y,0},{x,0}}. {move,{x,1},{y,0}}. {call,1,{f,23}}. {test_heap,4,1}. %% 列表操作 {put_list,{x,0},{literal,[[1,2,3],[[4,1,2,3],9]]},{x,0}}. {put_list,{y,0},{x,0},{x,1}}. {trim,1,0}. {move,{literal,"~p~p~p~p~n"},{x,0}}. {call_ext,2,{extfunc,io,format,2}}. {move,{atom,done},{x,0}}. {deallocate,0}. return. {label,21}. {case_end,{x,0}}. {function, f, 1, 23}. {label,22}. {func_info,{atom,gram},{atom,f},1}. {label,23}. {test,bs_start_match2,{f,24},1,[{x,0},0],{x,0}}. {test,bs_match_string,{f,33},[{x,0},8,{string,[1]}]}. {test,bs_get_integer2, {f,33}, 1, [{x,0}, {integer,32}, 1, {field_flags,[{anno,[78,{file,"./gram.erl"}]},unsigned,big]}], {x,1}}. {test,bs_match_string,{f,33},[{x,0},24,{string,"xyz"}]}. {test,bs_get_float2, {f,33}, 2, [{x,0}, {integer,64}, 1, {field_flags,[{anno,[78,{file,"./gram.erl"}]},unsigned,big]}], {x,2}}. {test,bs_test_tail2,{f,33},[{x,0},0]}. {test_heap,3,3}. {put_tuple,2,{x,0}}. {put,{x,1}}. {put,{x,2}}. return. {label,24}. {test,is_tuple,{f,25},[{x,0}]}. {test,test_arity,{f,33},[{x,0},2]}. {get_tuple_element,{x,0},0,{x,1}}. {get_tuple_element,{x,0},1,{x,2}}. {test,is_eq_exact,{f,33},[{x,1},{atom,x}]}. {test,is_integer,{f,33},[{x,2}]}. {select_val,{x,2}, {f,33}, {list,[{integer,5}, {f,26}, {integer,4}, {f,27}, {integer,3}, {f,28}, {integer,2}, {f,29}, {integer,1}, {f,30}]}}. {label,25}. {test,is_atom,{f,31},[{x,0}]}. {select_val,{x,0}, {f,33}, {list,[{atom,x5}, {f,26}, {atom,x4}, {f,27}, {atom,x3}, {f,28}, {atom,x2}, {f,29}, {atom,x1}, {f,30}]}}. {label,26}. {move,{integer,5},{x,0}}. return. {label,27}. {move,{integer,4},{x,0}}. return. {label,28}. {move,{integer,3},{x,0}}. return. {label,29}. {move,{integer,2},{x,0}}. return. {label,30}. {move,{integer,1},{x,0}}. return. {label,31}. {test,is_integer,{f,33},[{x,0}]}. {select_val,{x,0}, {f,33}, {list,[{integer,5}, {f,32}, {integer,4}, {f,32}, {integer,3}, {f,32}, {integer,2}, {f,32}, {integer,1}, {f,32}]}}. {label,32}. return. {label,33}. {move,{atom,err},{x,0}}. return. %%这2个函数是complier要硬性加上去的 {function, module_info, 0, 35}. {label,34}. {func_info,{atom,gram},{atom,module_info},0}. {label,35}. {move,{atom,gram},{x,0}}. {call_ext_only,1,{extfunc,erlang,get_module_info,1}}. {function, module_info, 1, 37}. {label,36}. {func_info,{atom,gram},{atom,module_info},1}. {label,37}. {move,{x,0},{x,1}}. {move,{atom,gram},{x,0}}. {call_ext_only,2,{extfunc,erlang,get_module_info,2}}. %%匿名函数的命名 {function, '-start/1-fun-0-', 3, 39}. {label,38}. {func_info,{atom,gram},{atom,'-start/1-fun-0-'},3}. {label,39}. {test,bs_start_match2,{f,40},3,[{x,0},0],{x,0}}. {test,bs_match_string,{f,44},[{x,0},16,{string,"12"}]}. {test,bs_test_tail2,{f,44},[{x,0},0]}. %% bitstring的代码很优化。 {move,{integer,1},{x,0}}. return. {label,40}. {test,is_atom,{f,43},[{x,0}]}. {select_val,{x,0},{f,44},{list,[{atom,y},{f,41},{atom,x},{f,42}]}}. %% 一类的数据放在一起 用二分查找匹配 {label,41}. {move,{x,1},{x,0}}. return. {label,42}. {move,{integer,2},{x,0}}. return. {label,43}. {test,is_eq_exact,{f,44},[{x,0},{integer,1}]}. {move,{x,2},{x,0}}. return. {label,44}. {move,{atom,error},{x,0}}. return. 所以无论函数match, 表达式match在vm层面都是if else这样的判断。从这个角度来讲if, case这些都只是erlang的语法糖。事实上也是,这些语法都是后来添加的,取悦用户的。 函数匹配是erlang的所有事情的核心。 结论:erlang的compiler很智能,这个VM和lua的非常像, 效率也相当。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-09-21
哇,好有料
|
|
返回顶楼 | |
发表时间:2009-09-21
opcode都长的差不多 明白了lua这个一看也就明白了
|
|
返回顶楼 | |
发表时间:2009-09-23
yeah,这个东东要好好的看了,好漫长哈。
|
|
返回顶楼 | |