1: %%
    2: %% %CopyrightBegin%
    3: %% 
    4: %% Copyright Ericsson AB 2005-2012. All Rights Reserved.
    5: %% 
    6: %% The contents of this file are subject to the Erlang Public License,
    7: %% Version 1.1, (the "License"); you may not use this file except in
    8: %% compliance with the License. You should have received a copy of the
    9: %% Erlang Public License along with this software. If not, it can be
   10: %% retrieved online at http://www.erlang.org/.
   11: %% 
   12: %% Software distributed under the License is distributed on an "AS IS"
   13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
   14: %% the License for the specific language governing rights and limitations
   15: %% under the License.
   16: %% 
   17: %% %CopyrightEnd%
   18: %%
   19: 
   20: -module(erts_debug_SUITE).
   21: -include_lib("test_server/include/test_server.hrl").
   22: 
   23: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 
   24: 	 init_per_group/2,end_per_group/2,
   25: 	 init_per_testcase/2,end_per_testcase/2,
   26: 	 test_size/1,flat_size_big/1,df/1,
   27: 	 instructions/1]).
   28: 
   29: suite() -> [{ct_hooks,[ts_install_cth]}].
   30: 
   31: all() -> 
   32:     [test_size, flat_size_big, df, instructions].
   33: 
   34: groups() -> 
   35:     [].
   36: 
   37: init_per_suite(Config) ->
   38:     Config.
   39: 
   40: end_per_suite(_Config) ->
   41:     ok.
   42: 
   43: init_per_group(_GroupName, Config) ->
   44:     Config.
   45: 
   46: end_per_group(_GroupName, Config) ->
   47:     Config.
   48: 
   49: 
   50: init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
   51:     Dog=?t:timetrap(?t:minutes(2)),
   52:     [{watchdog, Dog}|Config].
   53: 
   54: end_per_testcase(_Func, Config) ->
   55:     Dog=?config(watchdog, Config),
   56:     ?t:timetrap_cancel(Dog).
   57: 
   58: test_size(Config) when is_list(Config) ->
   59:     ConsCell1 = id([a|b]),
   60:     ConsCell2 = id(ConsCell1),
   61:     ConsCellSz = 2,
   62: 
   63:     0 = do_test_size([]),
   64:     0 = do_test_size(42),
   65:     ConsCellSz = do_test_size(ConsCell1),
   66:     1 = do_test_size({}),
   67:     2 = do_test_size({[]}),
   68:     3 = do_test_size({a,b}),
   69:     7 = do_test_size({a,[b,c]}),
   70: 
   71:     %% Test internal consistency of sizes, but without testing
   72:     %% exact sizes.
   73:     Const = id(42),
   74:     AnotherConst = id(7),
   75: 
   76:     %% Fun environment size = 0 (the smallest fun possible)
   77:     SimplestFun = fun() -> ok end,
   78:     FunSz0 = do_test_size(SimplestFun),
   79: 
   80:     %% Fun environment size = 1
   81:     FunSz1 = do_test_size(fun() -> Const end),
   82:     FunSz1 = FunSz0 + 1,
   83: 
   84:     %% Fun environment size = 2
   85:     FunSz2 = do_test_size(fun() -> Const+AnotherConst end),
   86:     FunSz2 = FunSz1 + 1,
   87: 
   88:     FunSz1 = do_test_size(fun() -> ConsCell1 end) - do_test_size(ConsCell1),
   89: 
   90:     %% Test shared data structures.
   91:     do_test_size([ConsCell1|ConsCell1],
   92: 		 3*ConsCellSz,
   93: 		 2*ConsCellSz),
   94:     do_test_size(fun() -> {ConsCell1,ConsCell2} end,
   95: 		 FunSz2 + 2*ConsCellSz,
   96: 		 FunSz2 + ConsCellSz),
   97:     do_test_size({SimplestFun,SimplestFun},
   98: 		 2*FunSz0+do_test_size({a,b}),
   99: 		 FunSz0+do_test_size({a,b})),
  100:     ok.
  101: 
  102: do_test_size(Term) ->
  103:     Sz = erts_debug:flat_size(Term),
  104:     Sz = erts_debug:size(Term).
  105: 
  106: do_test_size(Term, FlatSz, Sz) ->
  107:     FlatSz = erts_debug:flat_size(Term),
  108:     Sz = erts_debug:size(Term).
  109: 
  110: flat_size_big(Config) when is_list(Config) ->
  111:     %% Build a term whose external size only fits in a big num (on 32-bit CPU).
  112:     flat_size_big_1(16#11111111111111117777777777777777888889999, 0, 16#FFFFFFF).
  113: 
  114: flat_size_big_1(Term, Size0, Limit) when Size0 < Limit ->
  115:     case erts_debug:flat_size(Term) of
  116: 	Size when is_integer(Size), Size0 < Size ->
  117: 	    io:format("~p", [Size]),
  118: 	    flat_size_big_1([Term|Term], Size, Limit)
  119:     end;
  120: flat_size_big_1(_, _, _) -> ok.
  121: 
  122: df(Config) when is_list(Config) ->
  123:     ?line P0 = pps(),
  124:     ?line PrivDir = ?config(priv_dir, Config),
  125:     ?line ok = file:set_cwd(PrivDir),
  126:     ?line erts_debug:df(?MODULE),
  127:     ?line Beam = filename:join(PrivDir, ?MODULE_STRING++".dis"),
  128:     ?line {ok,Bin} = file:read_file(Beam),
  129:     ?line ok = io:put_chars(binary_to_list(Bin)),
  130:     ?line ok = file:delete(Beam),
  131:     ?line true = (P0 == pps()),    
  132:     ok.
  133: 
  134: pps() ->
  135:     {erlang:ports()}.
  136: 
  137: instructions(Config) when is_list(Config) ->
  138:     ?line Is = erts_debug:instructions(),
  139:     ?line _ = [list_to_atom(I) || I <- Is],
  140:     ok.
  141: 
  142: id(I) ->
  143:     I.