From 27e57aa05354b743b735a41716c0e3af18f2843e Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 10 Mar 2015 19:03:19 +0100 Subject: erts: Refactor maps naming convention flatmap: Small map hashmap: Large map map: flatmap or hashmap --- erts/emulator/beam/io.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'erts/emulator/beam/io.c') diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index dc4c6fc350..804d3ddf50 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -5595,16 +5595,16 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len) int size = (int)ptr[0]; Eterm* tp = hp; Eterm* vp; - map_t *mp; + flatmap_t *mp; *tp = make_arityval(size); hp += 1 + size; - mp = (map_t*)hp; + mp = (flatmap_t*)hp; mp->thing_word = MAP_HEADER; mp->size = size; mp->keys = make_tuple(tp); - mess = make_map(mp); + mess = make_flatmap(mp); hp += MAP_HEADER_SIZE + size; /* advance "heap" pointer */ @@ -5615,7 +5615,7 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len) *vp-- = ESTACK_POP(stack); *tp-- = ESTACK_POP(stack); } - if (!erts_validate_and_sort_map(mp)) + if (!erts_validate_and_sort_flatmap(mp)) ERTS_DDT_FAIL; ptr++; break; -- cgit v1.2.3 From f9e568cbad942043592453d0fb7640d8bc02b1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?= Date: Wed, 11 Mar 2015 10:25:37 +0100 Subject: erts: Add hashmap construction to driver API --- erts/emulator/beam/io.c | 78 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 26 deletions(-) (limited to 'erts/emulator/beam/io.c') diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 804d3ddf50..b64854aac9 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -5349,7 +5349,11 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len) case ERL_DRV_MAP: { /* int */ ERTS_DDT_CHK_ENOUGH_ARGS(1); if ((int) ptr[0] < 0) ERTS_DDT_FAIL; - need += MAP_HEADER_SIZE + 1 + 2*ptr[0]; + if (ptr[0] > MAP_SMALL_MAP_LIMIT) { + need += hashmap_over_estimated_heap_size(ptr[0]); + } else { + need += MAP_HEADER_SIZE + 1 + 2*ptr[0]; + } depth -= 2*ptr[0]; if (depth < 0) ERTS_DDT_FAIL; ptr++; @@ -5593,31 +5597,53 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len) case ERL_DRV_MAP: { /* int */ int size = (int)ptr[0]; - Eterm* tp = hp; - Eterm* vp; - flatmap_t *mp; - - *tp = make_arityval(size); - - hp += 1 + size; - mp = (flatmap_t*)hp; - mp->thing_word = MAP_HEADER; - mp->size = size; - mp->keys = make_tuple(tp); - mess = make_flatmap(mp); - - hp += MAP_HEADER_SIZE + size; /* advance "heap" pointer */ - - tp += size; /* point at last key */ - vp = hp - 1; /* point at last value */ - - while(size--) { - *vp-- = ESTACK_POP(stack); - *tp-- = ESTACK_POP(stack); - } - if (!erts_validate_and_sort_flatmap(mp)) - ERTS_DDT_FAIL; - ptr++; + if (size > MAP_SMALL_MAP_LIMIT) { + int ix = 2*size; + ErtsHeapFactory factory; + Eterm* leafs = hp; + + hp += 2*size; + while(ix--) { *--hp = ESTACK_POP(stack); } + + hp += 2*size; + factory.p = NULL; + factory.hp = hp; + /* We assume heap will suffice (see hashmap_over_estimated_heap_size) */ + factory.hp_end = hp + (ERTS_SWORD_MAX / sizeof(Eterm)); + + mess = erts_hashmap_from_array(&factory, leafs, size, 1); + + if (is_non_value(mess)) + ERTS_DDT_FAIL; + + hp = factory.hp; + } else { + Eterm* tp = hp; + Eterm* vp; + flatmap_t *mp; + + *tp = make_arityval(size); + + hp += 1 + size; + mp = (flatmap_t*)hp; + mp->thing_word = MAP_HEADER; + mp->size = size; + mp->keys = make_tuple(tp); + mess = make_flatmap(mp); + + hp += MAP_HEADER_SIZE + size; /* advance "heap" pointer */ + + tp += size; /* point at last key */ + vp = hp - 1; /* point at last value */ + + while(size--) { + *vp-- = ESTACK_POP(stack); + *tp-- = ESTACK_POP(stack); + } + if (!erts_validate_and_sort_flatmap(mp)) + ERTS_DDT_FAIL; + } + ptr++; break; } -- cgit v1.2.3 From 12fc63bcaf68b4a9e89ce91e1235aafb8bcdaee5 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Fri, 13 Mar 2015 18:00:33 +0100 Subject: erts: Fix map bug in dec_term for 32-bit debug VM Adding ERTS_SWORD_MAX to a pointer does not work as a way to disable a bound check. Remove the hp_end from ErtsHeapFactory as it isn't really used anyway. --- erts/emulator/beam/io.c | 1 - 1 file changed, 1 deletion(-) (limited to 'erts/emulator/beam/io.c') diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index b64854aac9..62254ca34d 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -5609,7 +5609,6 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len) factory.p = NULL; factory.hp = hp; /* We assume heap will suffice (see hashmap_over_estimated_heap_size) */ - factory.hp_end = hp + (ERTS_SWORD_MAX / sizeof(Eterm)); mess = erts_hashmap_from_array(&factory, leafs, size, 1); -- cgit v1.2.3