aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_disasm.erl
AgeCommit message (Collapse)Author
2019-05-22Make the swap instruction known to the compilerBjörn Gustavsson
BEAM has had a `swap` instruction for several releases, but it was not known to the compiler. The loader would translate a sequence of three `move` instructions to the `swap` instructions, but only when it was possible to determine that it would be safe. By making `swap` known to the compiler, it can be applied in more situations since it is easier for the compiler than for the loader to ensure that the usage is safe, and the loader shenanigans can be eliminated.
2018-09-28Rewrite BSM optimizations in the new SSA-based intermediate formatJohn Högberg
This commit improves the bit-syntax match optimization pass, leveraging the new SSA intermediate format to perform much more aggressive optimizations. Some highlights: * Watch contexts can be reused even after being passed to a function or being used in a try block. * Sub-binaries are no longer eagerly extracted, making it far easier to keep "happy paths" free from binary creation. * Trivial wrapper functions no longer disable context reuse.
2018-09-03Introduce a put_tuple2 instructionBjörn Gustavsson
Sometimes when building a tuple, there is no way to avoid an extra `move` instruction. Consider this code: make_tuple(A) -> {ok,A}. The corresponding BEAM code looks like this: {test_heap,3,1}. {put_tuple,2,{x,1}}. {put,{atom,ok}}. {put,{x,0}}. {move,{x,1},{x,0}}. return. To avoid overwriting the source register `{x,0}`, a `move` instruction is necessary. The problem doesn't exist when building a list: %% build_list(A) -> [A]. {test_heap,2,1}. {put_list,{x,0},nil,{x,0}}. return. Introduce a new `put_tuple2` instruction that builds a tuple in a single instruction, so that the `move` instruction can be eliminated: %% make_tuple(A) -> {ok,A}. {test_heap,3,1}. {put_tuple2,{x,0},{list,[{atom,ok},{x,0}]}}. return. Note that the BEAM loader already combines `put_tuple` and `put` instructions into an internal instruction similar to `put_tuple2`. Therefore the introduction of the new instruction will not speed up execution of tuple building itself, but it will be less work for the loader to load the new instruction.
2018-06-18Update copyright yearHenrik Nord
2018-01-26Eliminate get_list/3 internally in the compilerBjörn Gustavsson
Instructions that produce more than one result complicate optimizations. get_list/3 is one of two instructions that produce multiple results (get_map_elements/3 is the other). Introduce the get_hd/2 and get_tl/2 instructions that return the head and tail of a cons cell, respectively, and use it internally in all optimization passes. For efficiency, we still want to use get_list/3 if both head and tail are used, so we will translate matching pairs of get_hd and get_tl back to get_list instructions.
2018-01-22Don't build a stacktrace if it's only passed to erlang:raise/3Björn Gustavsson
Consider the following function: function({function,Name,Arity,CLabel,Is0}, Lc0) -> try %% Optimize the code for the function. catch Class:Error:Stack -> io:format("Function: ~w/~w\n", [Name,Arity]), erlang:raise(Class, Error, Stack) end. The stacktrace is retrieved, but it is only used in the call to erlang:raise/3. There is no need to build a stacktrace in this function. We can avoid the building if we introduce an instruction called raw_raise/3 that works exactly like the erlang:raise/3 BIF except that its third argument must be a raw stacktrace.
2017-12-15Merge branch 'bjorn/compiler/coverage'Björn Gustavsson
* bjorn/compiler/coverage: beam_utils: Refactor combine_alloc_lists() to cover more lines map_SUITE: Cover beam_utils:bif_to_test/3 beam_disasm: Remove support for obsolete instructions guard_SUITE: Test is_bitstring/1 and is_map/1 on literals
2017-12-08beam_disasm: Remove support for obsolete instructionsBjörn Gustavsson
2017-12-08Use the new syntax for retrieving stack tracesBjörn Gustavsson
2017-11-30Add syntax in try/catch to retrieve the stacktrace directlyBjörn Gustavsson
This commit adds a new syntax for retrieving the stacktrace without calling erlang:get_stacktrace/0. That allow us to deprecate erlang:get_stacktrace/0 and ultimately remove it. The problem with erlang:get_stacktrace/0 is that it can keep huge terms in a process for an indefinite time after an exception. The stacktrace can be huge after a 'function_clause' exception or a failed call to a BIF or operator, because the arguments for the call will be included in the stacktrace. For example: 1> catch abs(lists:seq(1, 1000)). {'EXIT',{badarg,[{erlang,abs, [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20|...]], []}, {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]}, {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,431}]}, {shell,exprs,7,[{file,"shell.erl"},{line,687}]}, {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]}, {shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}]}} 2> erlang:get_stacktrace(). [{erlang,abs, [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22, 23,24|...]], []}, {erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,674}]}, {erl_eval,expr,5,[{file,"erl_eval.erl"},{line,431}]}, {shell,exprs,7,[{file,"shell.erl"},{line,687}]}, {shell,eval_exprs,7,[{file,"shell.erl"},{line,642}]}, {shell,eval_loop,3,[{file,"shell.erl"},{line,627}]}] 3> We can extend the syntax for clauses in try/catch to optionally bind the stacktrace to a variable. Here is an example using the current syntax: try Expr catch C:E -> Stk = erlang:get_stacktrace(), . . . In the new syntax, it would look like: try Expr catch C:E:Stk -> . . . Only a variable (not a pattern) is allowed in the stacktrace position, to discourage matching of the stacktrace. (Matching would also be expensive, because the raw format of the stacktrace would have to be converted to the cooked form before matching.) Note that: try Expr catch E -> . . . is a shorthand for: try Expr catch throw:E -> . . . If the stacktrace is to be retrieved for a throw, the 'throw:' prefix must be explicitly included: try Expr catch throw:E:Stk -> . . .
2017-03-24compiler: Add is_tagged_tuple instructionBjörn-Egil Dahlberg
Rewrite the instruction stream on tagged tuple tests. Tagged tuples means a tuple of any arity with an atom as its first element. Typically records, ok-tuples and error-tuples. from: ... {test,is_tuple,Fail,[Src]}. {test,test_arity,Fail,[Src,Sz]}. ... {get_tuple_element,Src,0,Dst}. ... {test,is_eq_exact,Fail,[Dst,Atom]}. ... to: ... {test,is_tagged_tuple,Fail,[Src,Sz,Atom]}. ...
2016-05-27Declare the type of function entry pointsKostis Sagonas
This shuts off compiler warnings and will allow to enable stronger compiler checks files that include beam_disasm.hrl in the hipe application. While doing that, also modified a comment in the header file and turned a case statement into effectively an assertion: there should not really be any beam files where functions do not have a label as entry point, right?
2016-03-15update copyright-yearHenrik Nord
2015-06-18Change license text to APLv2Bruce Yinhe
2014-03-28Support the translation of the is_map BEAM instruction to IcodeKostis Sagonas
2014-02-23Deprecate pre-defined built-in typesHans Bolinder
The types array(), dict(), digraph(), gb_set(), gb_tree(), queue(), set(), and tid() have been deprecated. They will be removed in OTP 18.0. Instead the types array:array(), dict:dict(), digraph:graph(), gb_set:set(), gb_tree:tree(), queue:queue(), sets:set(), and ets:tid() can be used. (Note: it has always been necessary to use ets:tid().) It is allowed in OTP 17.0 to locally re-define the types array(), dict(), and so on. New types array:array/1, dict:dict/2, gb_sets:set/1, gb_trees:tree/2, queue:queue/1, and sets:set/1 have been added.
2014-02-19compiler: Check literal order in beam_validatorBjörn-Egil Dahlberg
2014-02-13compiler: Change map instructions for fetching valuesBjörn-Egil Dahlberg
* Combine multiple get values with one instruction * Combine multiple check keys with one instruction
2014-01-31compiler: Teach beam_disasm has_map_field instructionBjörn-Egil Dahlberg
2014-01-28compiler: Teach Maps to beam_disasmBjörn-Egil Dahlberg
2013-02-22Update copyright yearsBjörn-Egil Dahlberg
2013-01-31compiler: Use the literal pool for floating point constantsBjörn Gustavsson
The BEAM loader will put floating point constants into the literal pools for the module, but it will not check for duplicates. We can do much better by having the compiler use the literal pool for floating point constants.
2012-02-20Fix discrepancy in compile_infoKostis Sagonas
The BEAM disassembler used the atom 'none' to signify the absence of a compile_info chunk in a .beam file. This clashes with the type declaration of the compile_info field of a #beam_file{} record as containing a list. Use [] to signify the absence of this chunk. This simplifies the code and avoids a dialyzer warning. For fixing a similar problem and for consistency, changed also the return type of the attributes field of the #beam_file{} record. This required a change in the beam_disasm test suite.
2011-09-29Merge branch 'dev' into majorBjörn-Egil Dahlberg
* dev: Update copyright years
2011-09-29Update copyright yearsBjörn-Egil Dahlberg
2011-09-22Merge branch 'dev' into majorHenrik Nord
2011-09-21beam_disasm: Handle stripped BEAM filesHaitao Li
beam_disasm:file/1 would crash if asked to disassemble a stripped BEAM file without an "Attr" chunk.
2011-08-16Include location information for line instructions in BEAM filesBjörn Gustavsson
2011-08-16compiler, emulator: Introduce the line/1 instructionBjörn Gustavsson
Introduce the line/1 instruction in the compiler and the BEAM virtual machine. It will not yet be generated by the compiler and will not actually carry any information.
2010-05-20Remove stray support for the put_literal/2 instructionBjörn Gustavsson
put_literal/2 was an experimental instruction added in R11 to support literals, but before the R12 release support for literals was implemented for all instruction, making the put_literal/2 instruction redundant. Although the beam_disasm module supports dissambley of instructions in older releases, there is no reason to have it support experimental instructions.
2010-05-20Remove stray support for the bs_bits_to_bytes2/2 instructionBjörn Gustavsson
bs_bits_to_bytes2/2 was an experimental instruction added in R11, but was removed in R12. Although the beam_disasm and beam_validator modules do support instructions in older releases, there is no reason to have them support experimental instructions.
2010-05-17Add guard BIFs binary_part/2,3Patrik Nyblom
Add the gc_bif's to the VM. Add infrastructure for gc_bif's (guard bifs that can gc) with two and. three arguments in VM (loader and VM). Add compiler support for gc_bif with three arguments. Add compiler (and interpreter) support for new guard BIFs. Add testcases for new guard BIFs in compiler and emulator.
2010-05-12Merge branch 'bg/opt-receive' into devErlang/OTP
* bg/opt-receive: Test that gen_server:call/2,3 are fast even with a huge message queue erts: Add tests for the receive optimization Update primary bootstrap erts: Implement recv_mark/1 and recv_set/1 for real compiler tests: Cover the error handling code in beam_receive compiler test: Test optimization of receive statements Optimize selective receives in the presence of a large message queue Introduce the new recv_mark/1 and recv_mark/1 instructions Compile tests that communicate with R12 nodes with the r12 option Move p_run/2 to test_lib gen: Inline wait_resp_mon/2 to help the compiler optimize OTP-8623 bg/opt-receive reveive statements that can only read out a newly created reference are now specially optimized so that it will execute in constant time regardless of the number of messages in the receive queue for the process. That optimization will benefit calls to gen_server:call(). (See gen:do_call/4 for an example of a receive statement that will be optimized.)
2010-05-11Introduce the new recv_mark/1 and recv_mark/1 instructionsBjörn Gustavsson
Make the recv_mark/1 and recv_mark/1 instructions known to the compiler and run-time system. For the moment, make the loader ignore any occurrences of those instructions in BEAM files. Also update hipe_beam_to_icode to ignore those instructions.
2009-11-20The R13B03 release.OTP_R13B03Erlang/OTP