From 5d5543fb1e1a30e4572e90bac2ec194a61ca4e30 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 25 Mar 2015 19:55:43 +0100 Subject: erts: Optimize term_to_binary size estimation for tuples and maps containing ascii strings (lists). --- erts/emulator/beam/external.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'erts/emulator/beam') diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index b0b232f185..4cd57d8aeb 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -4109,8 +4109,9 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, } for (i = 1; i <= arity; ++i) { if (is_list(ptr[i])) { - if ((m = is_string(obj)) && (m < MAX_STRING_LEN)) { + if ((m = is_string(ptr[i])) && (m < MAX_STRING_LEN)) { result += m + 2 + 1; + continue; } else { result += 5; } @@ -4131,31 +4132,29 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, /* push values first */ ptr = flatmap_get_values(mp); - i = size; - while(i--) { + for (i = size; i; i--, ptr++) { if (is_list(*ptr)) { if ((m = is_string(*ptr)) && (m < MAX_STRING_LEN)) { result += m + 2 + 1; + continue; } else { result += 5; } } ESTACK_PUSH(s,*ptr); - ++ptr; } ptr = flatmap_get_keys(mp); - i = size; - while(i--) { + for (i = size; i; i--, ptr++) { if (is_list(*ptr)) { if ((m = is_string(*ptr)) && (m < MAX_STRING_LEN)) { result += m + 2 + 1; + continue; } else { result += 5; } } ESTACK_PUSH(s,*ptr); - ++ptr; } goto outer_loop; } -- cgit v1.2.3 From d09ec9ee97816bd987e6322797b0e28c27f8590a Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Wed, 25 Mar 2015 20:50:12 +0100 Subject: erts: Fix bug in term_to_binary size estimation for hamt --- erts/emulator/beam/external.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) (limited to 'erts/emulator/beam') diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 4cd57d8aeb..8f0e19d27d 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -4172,8 +4172,12 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, case HAMT_SUBTAG_HEAD_ARRAY: ptr++; node_sz = 16; + result += 1 + 4; /* tag + 4 bytes size */ break; - case HAMT_SUBTAG_HEAD_BITMAP: ptr++; + case HAMT_SUBTAG_HEAD_BITMAP: + ptr++; + result += 1 + 4; /* tag + 4 bytes size */ + /*fall through*/ case HAMT_SUBTAG_NODE_BITMAP: node_sz = hashmap_bitcount(MAP_HEADER_VAL(hdr)); ASSERT(node_sz < 17); @@ -4183,11 +4187,38 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, } ptr++; - ESTACK_RESERVE(s, node_sz); + ESTACK_RESERVE(s, node_sz*2); while(node_sz--) { - ESTACK_FAST_PUSH(s, *ptr++); + if (is_list(*ptr)) { + Eterm* leaf = list_val(*ptr); + if (is_not_list(CAR(leaf))) { + ESTACK_FAST_PUSH(s, CAR(leaf)); + } + else { + if ((m = is_string(CAR(leaf))) && (m < MAX_STRING_LEN)) { + result += m + 2 + 1; + } else { + result += 5; + ESTACK_FAST_PUSH(s, CAR(leaf)); + } + } + if (is_not_list(CDR(leaf))) { + ESTACK_FAST_PUSH(s, CDR(leaf)); + } + else { + if ((m = is_string(CDR(leaf))) && (m < MAX_STRING_LEN)) { + result += m + 2 + 1; + } else { + result += 5; + ESTACK_FAST_PUSH(s, CDR(leaf)); + } + } + } + else { + ESTACK_FAST_PUSH(s, *ptr); + } + ptr++; } - result += 1 + 4; /* tag + 4 bytes size */ } break; -- cgit v1.2.3