summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/external.c
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/external.c')
-rw-r--r--erts/emulator/beam/external.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 67584e38ec..cfac7a5290 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -3035,7 +3035,6 @@ dec_pid(ErtsDistExternal *edep, ErtsHeapFactory* factory, const byte* ep,
#define ENC_BIN_COPY ((Eterm) 3)
#define ENC_MAP_PAIR ((Eterm) 4)
#define ENC_HASHMAP_NODE ((Eterm) 5)
-#define ENC_STORE_MAP_ELEMENT ((Eterm) 6)
#define ENC_START_SORTING_MAP ((Eterm) 7)
#define ENC_CONTINUE_SORTING_MAP ((Eterm) 8)
#define ENC_PUSH_SORTED_MAP ((Eterm) 9)
@@ -3193,18 +3192,32 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
case ENC_HASHMAP_NODE:
if (is_list(obj)) { /* leaf node [K|V] */
ptr = list_val(obj);
+ if (dflags & DFLAG_DETERMINISTIC) {
+ *next_map_element++ = CAR(ptr);
+ *next_map_element++ = CDR(ptr);
+ goto outer_loop;
+ }
WSTACK_PUSH2(s, ENC_TERM, CDR(ptr));
obj = CAR(ptr);
}
- break;
- case ENC_STORE_MAP_ELEMENT: /* option `deterministic` */
- if (is_list(obj)) { /* leaf node [K|V] */
- ptr = list_val(obj);
- *next_map_element++ = CAR(ptr);
- *next_map_element++ = CDR(ptr);
+ else if (is_tuple(obj)) { /* collision node */
+ Uint tpl_sz;
+ ptr = tuple_val(obj);
+ tpl_sz = arityval(*ptr);
+ ASSERT(tpl_sz >= 2);
+ ptr++;
+ WSTACK_RESERVE(s, tpl_sz * 2);
+ while(tpl_sz--) {
+ ASSERT(is_list(*ptr));
+ WSTACK_FAST_PUSH(s, ENC_HASHMAP_NODE);
+ WSTACK_FAST_PUSH(s, *ptr++);
+ }
goto outer_loop;
- }
- break;
+ }
+ else
+ ASSERT((*boxed_val(obj) & _HEADER_MAP_SUBTAG_MASK)
+ == HAMT_SUBTAG_NODE_BITMAP);
+ break;
case ENC_START_SORTING_MAP: /* option `deterministic` */
{
long num_reductions = r;
@@ -3489,7 +3502,6 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
} else {
Eterm hdr;
Uint node_sz;
- Eterm node_processor;
ptr = boxed_val(obj);
hdr = *ptr;
ASSERT(is_header(hdr));
@@ -3530,17 +3542,14 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep,
node_sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
ASSERT(node_sz < 17);
break;
- default:
- erts_exit(ERTS_ERROR_EXIT, "bad header\r\n");
- }
-
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header\r\n");
+ }
ptr++;
- node_processor = (dflags & DFLAG_DETERMINISTIC) ?
- ENC_STORE_MAP_ELEMENT : ENC_HASHMAP_NODE;
WSTACK_RESERVE(s, node_sz*2);
while(node_sz--) {
- WSTACK_FAST_PUSH(s, node_processor);
- WSTACK_FAST_PUSH(s, *ptr++);
+ WSTACK_FAST_PUSH(s, ENC_HASHMAP_NODE);
+ WSTACK_FAST_PUSH(s, *ptr++);
}
}
break;
@@ -5312,8 +5321,8 @@ encode_size_struct_int(TTBSizeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj,
node_sz = hashmap_bitcount(MAP_HEADER_VAL(hdr));
ASSERT(node_sz < 17);
break;
- default:
- erts_exit(ERTS_ERROR_EXIT, "bad header\r\n");
+ default:
+ erts_exit(ERTS_ERROR_EXIT, "bad header\r\n");
}
ptr++;