aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2015-01-21 18:09:52 +0100
committerBjörn-Egil Dahlberg <[email protected]>2015-03-12 18:56:41 +0100
commitb0b6eff0bebd25ba371a027b824426b87bd2a1d6 (patch)
tree58a5de9d1a108876f7db89d62a17b17f997b8615 /erts/emulator/beam
parent4007301c3cbd9e86a42cb122692736f493d2d3f9 (diff)
downloadotp-b0b6eff0bebd25ba371a027b824426b87bd2a1d6.tar.gz
otp-b0b6eff0bebd25ba371a027b824426b87bd2a1d6.tar.bz2
otp-b0b6eff0bebd25ba371a027b824426b87bd2a1d6.zip
erts: Refactor hashmap_to_list to use hashmap_do_foreach
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/erl_hashmap.c61
1 files changed, 15 insertions, 46 deletions
diff --git a/erts/emulator/beam/erl_hashmap.c b/erts/emulator/beam/erl_hashmap.c
index 5a18ec3e9b..8e651dd776 100644
--- a/erts/emulator/beam/erl_hashmap.c
+++ b/erts/emulator/beam/erl_hashmap.c
@@ -748,55 +748,24 @@ not_found:
return res;
}
+static void hashmap_to_list_doer(Eterm* kv, hashmap_doer_state* sp);
+
static Eterm hashmap_to_list(Process *p, Eterm node) {
- Eterm *hp;
- Eterm res = NIL;
- Eterm *ptr, tup, hdr;
- Uint sz, n;
- DECLARE_ESTACK(stack);
+ hashmap_head_t* root;
+ hashmap_doer_state state;
- ptr = boxed_val(node);
- n = (Uint)ptr[1];
- hp = HAlloc(p, n * (2 + 3));
- ESTACK_PUSH(stack, node);
- do {
- node = ESTACK_POP(stack);
- switch(primary_tag(node)) {
- case TAG_PRIMARY_LIST:
- ptr = list_val(node);
- tup = TUPLE2(hp, CAR(ptr), CDR(ptr)); hp += 3;
- res = CONS(hp, tup, res); hp += 2;
- break;
- case TAG_PRIMARY_BOXED:
- ptr = boxed_val(node);
- hdr = *ptr;
- ASSERT(is_header(hdr));
- switch(hdr & _HEADER_MAP_SUBTAG_MASK) {
- case HAMT_SUBTAG_HEAD_ARRAY:
- ptr++;
- case HAMT_SUBTAG_NODE_ARRAY:
- ptr++;
- sz = 16;
- while(sz--) { ESTACK_PUSH(stack, ptr[sz]); }
- break;
- case HAMT_SUBTAG_HEAD_BITMAP:
- ptr++;
- case HAMT_SUBTAG_NODE_BITMAP:
- sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
- ASSERT(sz < 17);
- ptr++;
- while(sz--) { ESTACK_PUSH(stack, ptr[sz]); }
- break;
- default:
- erl_exit(1, "bad header\r\n");
- break;
- }
- }
- } while(!ESTACK_ISEMPTY(stack));
+ root = (hashmap_head_t*) boxed_val(node);
+ state.hp = HAlloc(p, root->size * (2 + 3));
+ state.res = NIL;
+ hashmap_do_foreach(node, hashmap_to_list_doer, &state);
+ return state.res;
+}
- DESTROY_ESTACK(stack);
- ERTS_HOLE_CHECK(p);
- return res;
+static void hashmap_to_list_doer(Eterm* kv, hashmap_doer_state* sp) {
+ Eterm tup = TUPLE2(sp->hp, CAR(kv), CDR(kv));
+ sp->hp += 3;
+ sp->res = CONS(sp->hp, tup, sp->res);
+ sp->hp += 2;
}
#define HALLOC_EXTRA 200