diff options
author | Sverker Eriksson <[email protected]> | 2015-03-25 20:50:12 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2015-03-25 20:50:12 +0100 |
commit | d09ec9ee97816bd987e6322797b0e28c27f8590a (patch) | |
tree | 7cb8b29b30f17d768b9276d2ace0f04207de2087 /erts/emulator/beam/external.c | |
parent | 5d5543fb1e1a30e4572e90bac2ec194a61ca4e30 (diff) | |
download | otp-d09ec9ee97816bd987e6322797b0e28c27f8590a.tar.gz otp-d09ec9ee97816bd987e6322797b0e28c27f8590a.tar.bz2 otp-d09ec9ee97816bd987e6322797b0e28c27f8590a.zip |
erts: Fix bug in term_to_binary size estimation for hamt
Diffstat (limited to 'erts/emulator/beam/external.c')
-rw-r--r-- | erts/emulator/beam/external.c | 39 |
1 files changed, 35 insertions, 4 deletions
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; |