aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/bif.tab2
-rw-r--r--erts/emulator/beam/erl_hashmap.c135
-rw-r--r--erts/emulator/beam/erl_map.c133
3 files changed, 134 insertions, 136 deletions
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index e9c5e83203..f9127ef955 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -613,9 +613,9 @@ bif erlang:fun_info_mfa/1
#
bif erlang:get_keys/0
+bif erts_debug:map_info/1
# Hash Array Mappped Trie
-bif hashmap:info/1
bif hashmap:merge/2
#
diff --git a/erts/emulator/beam/erl_hashmap.c b/erts/emulator/beam/erl_hashmap.c
index 29a14a9f20..fecdc2ef31 100644
--- a/erts/emulator/beam/erl_hashmap.c
+++ b/erts/emulator/beam/erl_hashmap.c
@@ -45,10 +45,6 @@
#include "erl_map.h"
#include "erl_hashmap.h"
-#ifndef DECL_AM
-#define DECL_AM(S) Eterm AM_ ## S = am_atom_put(#S, sizeof(#S) - 1)
-#endif
-
#if 0
static char *format_binary(Uint64 x, char *b) {
int z;
@@ -62,7 +58,6 @@ static char *format_binary(Uint64 x, char *b) {
static Eterm hashmap_merge(Process *p, Eterm nodeA, Eterm nodeB);
-static Eterm hashmap_bld_tuple_uint(Uint **hpp, Uint *szp, Uint n, Uint nums[]);
/* hashmap:new/0 */
@@ -100,10 +95,6 @@ BIF_RETTYPE hashmap_merge_2(BIF_ALIST_2) {
/* impl. */
-/* n must be > 1
- * hash values in hxns has to be unique
- */
-
#define HALLOC_EXTRA 200
static Eterm hashmap_merge(Process *p, Eterm nodeA, Eterm nodeB) {
@@ -354,129 +345,3 @@ int hashmap_key_hash_cmp(Eterm* ap, Eterm* bp)
}
/* hashmap:info/0 */
-
-static Eterm hashmap_info(Process *p, Eterm node) {
- Eterm *hp;
- Eterm res = NIL, info = NIL;
- Eterm *ptr, tup, hdr;
- Uint sz;
- DECL_AM(depth);
- DECL_AM(leafs);
- DECL_AM(bitmaps);
- DECL_AM(arrays);
- Uint nleaf=0, nbitmap=0, narray=0;
- Uint bitmap_usage[16], leaf_usage[16];
- Uint lvl = 0, clvl;
- DECLARE_ESTACK(stack);
-
- for (sz = 0; sz < 16; sz++) {
- bitmap_usage[sz] = 0;
- leaf_usage[sz] = 0;
- }
-
- ptr = boxed_val(node);
- ESTACK_PUSH(stack, 0);
- ESTACK_PUSH(stack, node);
- do {
- node = ESTACK_POP(stack);
- clvl = ESTACK_POP(stack);
- lvl = MAX(lvl,clvl);
- switch(primary_tag(node)) {
- case TAG_PRIMARY_LIST:
- nleaf++;
- leaf_usage[clvl] += 1;
- break;
- case TAG_PRIMARY_BOXED:
- ptr = boxed_val(node);
- hdr = *ptr;
- ASSERT(is_header(hdr));
- switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
- case HAMT_SUBTAG_NODE_ARRAY:
- narray++;
- sz = 16;
- while(sz--) {
- ESTACK_PUSH(stack, clvl + 1);
- ESTACK_PUSH(stack, ptr[sz+1]);
- }
- break;
- case HAMT_SUBTAG_NODE_BITMAP:
- nbitmap++;
- sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
- ASSERT(sz < 17);
- bitmap_usage[sz-1] += 1;
- while(sz--) {
- ESTACK_PUSH(stack, clvl + 1);
- ESTACK_PUSH(stack, ptr[sz+1]);
- }
- break;
- case HAMT_SUBTAG_HEAD_BITMAP:
- nbitmap++;
- sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
- bitmap_usage[sz-1] += 1;
- while(sz--) {
- ESTACK_PUSH(stack, clvl + 1);
- ESTACK_PUSH(stack, ptr[sz+2]);
- }
- break;
- case HAMT_SUBTAG_HEAD_ARRAY:
- narray++;
- sz = 16;
- while(sz--) {
- ESTACK_PUSH(stack, clvl + 1);
- ESTACK_PUSH(stack, ptr[sz+2]);
- }
- break;
- default:
- erl_exit(1, "bad header\r\n");
- break;
- }
- }
- } while(!ESTACK_ISEMPTY(stack));
-
-
- /* size */
- sz = 0;
- hashmap_bld_tuple_uint(NULL,&sz,16,leaf_usage);
- hashmap_bld_tuple_uint(NULL,&sz,16,bitmap_usage);
-
- /* alloc */
- hp = HAlloc(p, 2+3 + 3*(2+4) + sz);
-
- info = hashmap_bld_tuple_uint(&hp,NULL,16,leaf_usage);
- tup = TUPLE3(hp, AM_leafs, make_small(nleaf),info); hp += 4;
- res = CONS(hp, tup, res); hp += 2;
-
- info = hashmap_bld_tuple_uint(&hp,NULL,16,bitmap_usage);
- tup = TUPLE3(hp, AM_bitmaps, make_small(nbitmap), info); hp += 4;
- res = CONS(hp, tup, res); hp += 2;
-
- tup = TUPLE3(hp, AM_arrays, make_small(narray),NIL); hp += 4;
- res = CONS(hp, tup, res); hp += 2;
-
- tup = TUPLE2(hp, AM_depth, make_small(lvl)); hp += 3;
- res = CONS(hp, tup, res); hp += 2;
-
- DESTROY_ESTACK(stack);
- ERTS_HOLE_CHECK(p);
- return res;
-}
-
-static Eterm hashmap_bld_tuple_uint(Uint **hpp, Uint *szp, Uint n, Uint nums[]) {
- Eterm res = THE_NON_VALUE;
- Eterm *ts = (Eterm *)erts_alloc(ERTS_ALC_T_TMP, n * sizeof(Eterm));
- Uint i;
-
- for (i = 0; i < n; i++) {
- ts[i] = erts_bld_uint(hpp, szp, nums[i]);
- }
- res = erts_bld_tuplev(hpp, szp, n, ts);
- erts_free(ERTS_ALC_T_TMP, (void *) ts);
- return res;
-}
-
-BIF_RETTYPE hashmap_info_1(BIF_ALIST_1) {
- if (is_hashmap(BIF_ARG_1)) {
- BIF_RET(hashmap_info(BIF_P,BIF_ARG_1));
- }
- BIF_ERROR(BIF_P, BADARG);
-}
diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c
index 7281353af5..14f16e9050 100644
--- a/erts/emulator/beam/erl_map.c
+++ b/erts/emulator/beam/erl_map.c
@@ -63,6 +63,10 @@
* - erts_internal:map_to_tuple_keys/1
*/
+#ifndef DECL_AM
+#define DECL_AM(S) Eterm AM_ ## S = am_atom_put(#S, sizeof(#S) - 1)
+#endif
+
/* for hashmap_from_list/1 */
typedef struct {
Uint32 hx;
@@ -82,6 +86,8 @@ static Eterm hashmap_from_validated_list(Process *p, Eterm list, Uint size);
static Eterm hashmap_from_unsorted_array(Process *p, hxnode_t *hxns, Uint n);
static Eterm hashmap_from_sorted_unique_array(Process *p, hxnode_t *hxns, Uint n, int is_root);
static Eterm hashmap_from_chunked_array(Process *p, hxnode_t *hxns, Uint n, int is_root);
+static Eterm hashmap_info(Process *p, Eterm node);
+static Eterm hashmap_bld_tuple_uint(Uint **hpp, Uint *szp, Uint n, Uint nums[]);
static int hxnodecmp(hxnode_t* a, hxnode_t* b);
static int hxnodecmpkey(hxnode_t* a, hxnode_t* b);
@@ -1993,6 +1999,13 @@ int erts_validate_and_sort_map(map_t* mp)
return 1;
}
+BIF_RETTYPE erts_debug_map_info_1(BIF_ALIST_1) {
+ if (is_hashmap(BIF_ARG_1)) {
+ BIF_RET(hashmap_info(BIF_P,BIF_ARG_1));
+ }
+ BIF_ERROR(BIF_P, BADARG);
+}
+
/*
* erts_internal:map_to_tuple_keys/1
*
@@ -2007,6 +2020,126 @@ BIF_RETTYPE erts_internal_map_to_tuple_keys_1(BIF_ALIST_1) {
BIF_ERROR(BIF_P, BADARG);
}
+static Eterm hashmap_info(Process *p, Eterm node) {
+ Eterm *hp;
+ Eterm res = NIL, info = NIL;
+ Eterm *ptr, tup, hdr;
+ Uint sz;
+ DECL_AM(depth);
+ DECL_AM(leafs);
+ DECL_AM(bitmaps);
+ DECL_AM(arrays);
+ Uint nleaf=0, nbitmap=0, narray=0;
+ Uint bitmap_usage[16], leaf_usage[16];
+ Uint lvl = 0, clvl;
+ DECLARE_ESTACK(stack);
+
+ for (sz = 0; sz < 16; sz++) {
+ bitmap_usage[sz] = 0;
+ leaf_usage[sz] = 0;
+ }
+
+ ptr = boxed_val(node);
+ ESTACK_PUSH(stack, 0);
+ ESTACK_PUSH(stack, node);
+ do {
+ node = ESTACK_POP(stack);
+ clvl = ESTACK_POP(stack);
+ lvl = MAX(lvl,clvl);
+ switch(primary_tag(node)) {
+ case TAG_PRIMARY_LIST:
+ nleaf++;
+ leaf_usage[clvl] += 1;
+ break;
+ case TAG_PRIMARY_BOXED:
+ ptr = boxed_val(node);
+ hdr = *ptr;
+ ASSERT(is_header(hdr));
+ switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
+ case HAMT_SUBTAG_NODE_ARRAY:
+ narray++;
+ sz = 16;
+ while(sz--) {
+ ESTACK_PUSH(stack, clvl + 1);
+ ESTACK_PUSH(stack, ptr[sz+1]);
+ }
+ break;
+ case HAMT_SUBTAG_NODE_BITMAP:
+ nbitmap++;
+ sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ ASSERT(sz < 17);
+ bitmap_usage[sz-1] += 1;
+ while(sz--) {
+ ESTACK_PUSH(stack, clvl + 1);
+ ESTACK_PUSH(stack, ptr[sz+1]);
+ }
+ break;
+ case HAMT_SUBTAG_HEAD_BITMAP:
+ nbitmap++;
+ sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ bitmap_usage[sz-1] += 1;
+ while(sz--) {
+ ESTACK_PUSH(stack, clvl + 1);
+ ESTACK_PUSH(stack, ptr[sz+2]);
+ }
+ break;
+ case HAMT_SUBTAG_HEAD_ARRAY:
+ narray++;
+ sz = 16;
+ while(sz--) {
+ ESTACK_PUSH(stack, clvl + 1);
+ ESTACK_PUSH(stack, ptr[sz+2]);
+ }
+ break;
+ default:
+ erl_exit(1, "bad header\r\n");
+ break;
+ }
+ }
+ } while(!ESTACK_ISEMPTY(stack));
+
+
+ /* size */
+ sz = 0;
+ hashmap_bld_tuple_uint(NULL,&sz,16,leaf_usage);
+ hashmap_bld_tuple_uint(NULL,&sz,16,bitmap_usage);
+
+ /* alloc */
+ hp = HAlloc(p, 2+3 + 3*(2+4) + sz);
+
+ info = hashmap_bld_tuple_uint(&hp,NULL,16,leaf_usage);
+ tup = TUPLE3(hp, AM_leafs, make_small(nleaf),info); hp += 4;
+ res = CONS(hp, tup, res); hp += 2;
+
+ info = hashmap_bld_tuple_uint(&hp,NULL,16,bitmap_usage);
+ tup = TUPLE3(hp, AM_bitmaps, make_small(nbitmap), info); hp += 4;
+ res = CONS(hp, tup, res); hp += 2;
+
+ tup = TUPLE3(hp, AM_arrays, make_small(narray),NIL); hp += 4;
+ res = CONS(hp, tup, res); hp += 2;
+
+ tup = TUPLE2(hp, AM_depth, make_small(lvl)); hp += 3;
+ res = CONS(hp, tup, res); hp += 2;
+
+ DESTROY_ESTACK(stack);
+ ERTS_HOLE_CHECK(p);
+ return res;
+}
+
+static Eterm hashmap_bld_tuple_uint(Uint **hpp, Uint *szp, Uint n, Uint nums[]) {
+ Eterm res = THE_NON_VALUE;
+ Eterm *ts = (Eterm *)erts_alloc(ERTS_ALC_T_TMP, n * sizeof(Eterm));
+ Uint i;
+
+ for (i = 0; i < n; i++) {
+ ts[i] = erts_bld_uint(hpp, szp, nums[i]);
+ }
+ res = erts_bld_tuplev(hpp, szp, n, ts);
+ erts_free(ERTS_ALC_T_TMP, (void *) ts);
+ return res;
+}
+
+
/* implementation of builtin emulations */
#if !defined(__GNUC__)