From 2ae91c3ade0538500ff4dbda29ad539e595f64df Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 15 Oct 2015 20:10:46 +0200 Subject: erts: Change erts_internal:map_type/1 into term_type/1 to support other terms, not just maps --- erts/emulator/beam/atom.h | 1 + erts/emulator/beam/bif.tab | 2 +- erts/emulator/beam/erl_map.c | 25 +++++++++++++++++-------- erts/emulator/test/map_SUITE.erl | 4 ++-- 4 files changed, 21 insertions(+), 11 deletions(-) (limited to 'erts/emulator') diff --git a/erts/emulator/beam/atom.h b/erts/emulator/beam/atom.h index ead56c83d8..2c002ca92f 100644 --- a/erts/emulator/beam/atom.h +++ b/erts/emulator/beam/atom.h @@ -129,6 +129,7 @@ typedef enum { (erts_is_atom_utf8_bytes((byte *) LSTR, sizeof(LSTR) - 1, (TERM))) #define ERTS_DECL_AM(S) Eterm AM_ ## S = am_atom_put(#S, sizeof(#S) - 1) #define ERTS_INIT_AM(S) AM_ ## S = am_atom_put(#S, sizeof(#S) - 1) +#define ERTS_MAKE_AM(Str) am_atom_put(Str, sizeof(Str) - 1) int atom_table_size(void); /* number of elements */ int atom_table_sz(void); /* table size in bytes, excluding stored objects */ diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab index c49a3ff313..07d4702b92 100644 --- a/erts/emulator/beam/bif.tab +++ b/erts/emulator/beam/bif.tab @@ -167,7 +167,7 @@ bif erts_internal:request_system_task/3 bif erts_internal:check_process_code/2 bif erts_internal:map_to_tuple_keys/1 -bif erts_internal:map_type/1 +bif erts_internal:term_type/1 bif erts_internal:map_hashmap_children/1 bif erts_internal:time_unit/0 diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c index 29b3024644..ac10b9a3e3 100644 --- a/erts/emulator/beam/erl_map.c +++ b/erts/emulator/beam/erl_map.c @@ -2698,29 +2698,38 @@ BIF_RETTYPE erts_internal_map_to_tuple_keys_1(BIF_ALIST_1) { } /* - * erts_internal:map_type/1 + * erts_internal:term_type/1 * * Used in erts_debug:size/1 */ -BIF_RETTYPE erts_internal_map_type_1(BIF_ALIST_1) { - DECL_AM(hashmap); - DECL_AM(hashmap_node); - DECL_AM(flatmap); +BIF_RETTYPE erts_internal_term_type_1(BIF_ALIST_1) { if (is_map(BIF_ARG_1)) { Eterm hdr = *(boxed_val(BIF_ARG_1)); ASSERT(is_header(hdr)); switch (hdr & _HEADER_MAP_SUBTAG_MASK) { case HAMT_SUBTAG_HEAD_FLATMAP: - BIF_RET(AM_flatmap); + BIF_RET(ERTS_MAKE_AM("flatmap")); case HAMT_SUBTAG_HEAD_ARRAY: case HAMT_SUBTAG_HEAD_BITMAP: - BIF_RET(AM_hashmap); + BIF_RET(ERTS_MAKE_AM("hashmap")); case HAMT_SUBTAG_NODE_BITMAP: - BIF_RET(AM_hashmap_node); + BIF_RET(ERTS_MAKE_AM("hashmap_node")); default: erl_exit(1, "bad header"); } + } else if (is_immed(BIF_ARG_1)) { + if (is_small(BIF_ARG_1)) { + BIF_RET(ERTS_MAKE_AM("small")); + } else if (is_ifloat(BIF_ARG_1)) { + BIF_RET(ERTS_MAKE_AM("ifloat")); + } + } else if (is_boxed(BIF_ARG_1)) { + if (is_big(BIF_ARG_1)) { + BIF_RET(ERTS_MAKE_AM("big")); + } else if (is_hfloat(BIF_ARG_1)) { + BIF_RET(ERTS_MAKE_AM("hfloat")); + } } BIF_P->fvalue = BIF_ARG_1; BIF_ERROR(BIF_P, BADMAP); diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl index 6890c42b7a..bde0d408f3 100644 --- a/erts/emulator/test/map_SUITE.erl +++ b/erts/emulator/test/map_SUITE.erl @@ -2598,7 +2598,7 @@ hashmap_balance(KeyFun) -> F = fun(I, {M0,Max0}) -> Key = KeyFun(I), M1 = M0#{Key => Key}, - Max1 = case erts_internal:map_type(M1) of + Max1 = case erts_internal:term_type(M1) of hashmap -> Nodes = hashmap_nodes(M1), Avg = maps:size(M1) * 0.4, @@ -3004,7 +3004,7 @@ t_gc_rare_map_overflow(Config) -> Loop() end), FatMap = fatmap(34), - false = (flatmap =:= erts_internal:map_type(FatMap)), + false = (flatmap =:= erts_internal:term_type(FatMap)), t_gc_rare_map_overflow_do(Echo, FatMap, fun() -> erlang:garbage_collect() end), -- cgit v1.2.3 From f6eacb9981b40604a031c9d61967b0c3a3588bdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Fri, 13 Nov 2015 17:41:36 +0100 Subject: erts: Let term_type/1 encompass all types --- erts/emulator/beam/erl_map.c | 101 +++++++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 27 deletions(-) (limited to 'erts/emulator') diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c index ac10b9a3e3..d0ffb11e79 100644 --- a/erts/emulator/beam/erl_map.c +++ b/erts/emulator/beam/erl_map.c @@ -2704,35 +2704,82 @@ BIF_RETTYPE erts_internal_map_to_tuple_keys_1(BIF_ALIST_1) { */ BIF_RETTYPE erts_internal_term_type_1(BIF_ALIST_1) { - if (is_map(BIF_ARG_1)) { - Eterm hdr = *(boxed_val(BIF_ARG_1)); - ASSERT(is_header(hdr)); - switch (hdr & _HEADER_MAP_SUBTAG_MASK) { - case HAMT_SUBTAG_HEAD_FLATMAP: - BIF_RET(ERTS_MAKE_AM("flatmap")); - case HAMT_SUBTAG_HEAD_ARRAY: - case HAMT_SUBTAG_HEAD_BITMAP: - BIF_RET(ERTS_MAKE_AM("hashmap")); - case HAMT_SUBTAG_NODE_BITMAP: - BIF_RET(ERTS_MAKE_AM("hashmap_node")); - default: - erl_exit(1, "bad header"); - } - } else if (is_immed(BIF_ARG_1)) { - if (is_small(BIF_ARG_1)) { - BIF_RET(ERTS_MAKE_AM("small")); - } else if (is_ifloat(BIF_ARG_1)) { - BIF_RET(ERTS_MAKE_AM("ifloat")); - } - } else if (is_boxed(BIF_ARG_1)) { - if (is_big(BIF_ARG_1)) { - BIF_RET(ERTS_MAKE_AM("big")); - } else if (is_hfloat(BIF_ARG_1)) { - BIF_RET(ERTS_MAKE_AM("hfloat")); + Eterm obj = BIF_ARG_1; + switch (primary_tag(obj)) { + case TAG_PRIMARY_LIST: + BIF_RET(ERTS_MAKE_AM("list")); + case TAG_PRIMARY_BOXED: { + Eterm hdr = *boxed_val(obj); + ASSERT(is_header(hdr)); + switch (hdr & _TAG_HEADER_MASK) { + case ARITYVAL_SUBTAG: + BIF_RET(ERTS_MAKE_AM("tuple")); + case EXPORT_SUBTAG: + BIF_RET(ERTS_MAKE_AM("export")); + case FUN_SUBTAG: + BIF_RET(ERTS_MAKE_AM("fun")); + case MAP_SUBTAG: + switch (MAP_HEADER_TYPE(hdr)) { + case MAP_HEADER_TAG_FLATMAP_HEAD : + BIF_RET(ERTS_MAKE_AM("flatmap")); + case MAP_HEADER_TAG_HAMT_HEAD_BITMAP : + case MAP_HEADER_TAG_HAMT_HEAD_ARRAY : + BIF_RET(ERTS_MAKE_AM("hashmap")); + case MAP_HEADER_TAG_HAMT_NODE_BITMAP : + BIF_RET(ERTS_MAKE_AM("hashmap_node")); + default: + erl_exit(ERTS_ABORT_EXIT, "term_type: bad map header type %d\n", MAP_HEADER_TYPE(hdr)); + } + case REFC_BINARY_SUBTAG: + BIF_RET(ERTS_MAKE_AM("refc_binary")); + case HEAP_BINARY_SUBTAG: + BIF_RET(ERTS_MAKE_AM("heap_binary")); + case SUB_BINARY_SUBTAG: + BIF_RET(ERTS_MAKE_AM("sub_binary")); + case BIN_MATCHSTATE_SUBTAG: + BIF_RET(ERTS_MAKE_AM("matchstate")); + case POS_BIG_SUBTAG: + case NEG_BIG_SUBTAG: + BIF_RET(ERTS_MAKE_AM("bignum")); + case REF_SUBTAG: + BIF_RET(ERTS_MAKE_AM("reference")); + case EXTERNAL_REF_SUBTAG: + BIF_RET(ERTS_MAKE_AM("external_reference")); + case EXTERNAL_PID_SUBTAG: + BIF_RET(ERTS_MAKE_AM("external_pid")); + case EXTERNAL_PORT_SUBTAG: + BIF_RET(ERTS_MAKE_AM("external_port")); + case FLOAT_SUBTAG: + BIF_RET(ERTS_MAKE_AM("hfloat")); + default: + erl_exit(ERTS_ABORT_EXIT, "term_type: Invalid tag (0x%X)\n", hdr); + } } + case TAG_PRIMARY_IMMED1: + switch (obj & _TAG_IMMED1_MASK) { + case _TAG_IMMED1_SMALL: + BIF_RET(ERTS_MAKE_AM("fixnum")); + case _TAG_IMMED1_PID: + BIF_RET(ERTS_MAKE_AM("pid")); + case _TAG_IMMED1_PORT: + BIF_RET(ERTS_MAKE_AM("port")); + case _TAG_IMMED1_IMMED2: + switch (obj & _TAG_IMMED2_MASK) { + case _TAG_IMMED2_ATOM: + BIF_RET(ERTS_MAKE_AM("atom")); + case _TAG_IMMED2_CATCH: + BIF_RET(ERTS_MAKE_AM("catch")); + case _TAG_IMMED2_NIL: + BIF_RET(ERTS_MAKE_AM("nil")); + default: + erl_exit(ERTS_ABORT_EXIT, "term_type: Invalid tag (0x%X)\n", obj); + } + default: + erl_exit(ERTS_ABORT_EXIT, "term_type: Invalid tag (0x%X)\n", obj); + } + default: + erl_exit(ERTS_ABORT_EXIT, "term_type: Invalid tag (0x%X)\n", obj); } - BIF_P->fvalue = BIF_ARG_1; - BIF_ERROR(BIF_P, BADMAP); } /* -- cgit v1.2.3 From 4f3212c9a84e6feaea1bbffdc1972e4760cc7815 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Fri, 13 Nov 2015 19:14:10 +0100 Subject: Test erts_internal:term_type/1 --- erts/emulator/test/erts_debug_SUITE.erl | 45 +++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) (limited to 'erts/emulator') diff --git a/erts/emulator/test/erts_debug_SUITE.erl b/erts/emulator/test/erts_debug_SUITE.erl index 35677f9953..bbba829501 100644 --- a/erts/emulator/test/erts_debug_SUITE.erl +++ b/erts/emulator/test/erts_debug_SUITE.erl @@ -24,13 +24,13 @@ -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, init_per_group/2,end_per_group/2, init_per_testcase/2,end_per_testcase/2, - test_size/1,flat_size_big/1,df/1, + test_size/1,flat_size_big/1,df/1,term_type/1, instructions/1]). suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> - [test_size, flat_size_big, df, instructions]. + [test_size, flat_size_big, df, instructions, term_type]. groups() -> []. @@ -138,6 +138,47 @@ flat_size_big_1(Term, Size0, Limit) when Size0 < Limit -> end; flat_size_big_1(_, _, _) -> ok. + +term_type(Config) when is_list(Config) -> + Ts = [{fixnum, 1}, + {fixnum, -1}, + {bignum, 1 bsl 300}, + {bignum, -(1 bsl 300)}, + {hfloat, 0.0}, + {hfloat, 0.0/-1}, + {hfloat, 1.0/(1 bsl 302)}, + {hfloat, 1.0*(1 bsl 302)}, + {hfloat, -1.0/(1 bsl 302)}, + {hfloat, -1.0*(1 bsl 302)}, + {hfloat, 3.1416}, + {hfloat, 1.0e18}, + {hfloat, -3.1416}, + {hfloat, -1.0e18}, + + {heap_binary, <<1,2,3>>}, + {refc_binary, <<0:(8*80)>>}, + {sub_binary, <<5:7>>}, + + {flatmap, #{ a => 1}}, + {hashmap, maps:from_list([{I,I}||I <- lists:seq(1,76)])}, + + {list, [1,2,3]}, + {nil, []}, + {tuple, {1,2,3}}, + {tuple, {}}, + + {export, fun lists:sort/1}, + {'fun', fun() -> ok end}, + {pid, self()}, + {atom, atom}], + lists:foreach(fun({E,Val}) -> + R = erts_internal:term_type(Val), + io:format("expecting term type ~w, got ~w (~p)~n", [E,R,Val]), + E = R + end, Ts), + ok. + + df(Config) when is_list(Config) -> P0 = pps(), PrivDir = ?config(priv_dir, Config), -- cgit v1.2.3