Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions erts/emulator/beam/erl_bif_atomics.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ BIF_RETTYPE atomics_info_1(BIF_ALIST_1)
values[3] = erts_bld_uword(&hp, NULL, memory);

res = erts_map_from_ks_and_vs(&factory, keys, values, 4);
ASSERT(is_map(res));
erts_factory_close(&factory);
return res;
}
38 changes: 14 additions & 24 deletions erts/emulator/beam/erl_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -666,9 +666,9 @@ Eterm erts_hashmap_from_array(ErtsHeapFactory* factory, Eterm *leafs, Uint n,
return res;
}

static ERTS_INLINE Eterm
from_ks_and_vs(ErtsHeapFactory *factory, Eterm *ks, Eterm *vs,
Uint n, flatmap_t **fmpp)
/* Returns THE_NON_VALUE if duplicate keys found. */
Eterm
erts_map_from_ks_and_vs(ErtsHeapFactory *factory, Eterm *ks, Eterm *vs, Uint n)
{
if (n <= MAP_SMALL_MAP_LIMIT) {
Eterm *hp;
Expand Down Expand Up @@ -698,34 +698,23 @@ from_ks_and_vs(ErtsHeapFactory *factory, Eterm *ks, Eterm *vs,

sys_memcpy((void *) hp, (void *) vs, n * sizeof(Eterm));

*fmpp = fmp;
return THE_NON_VALUE;
} else {
*fmpp = NULL;
return erts_hashmap_from_ks_and_vs(factory, ks, vs, n);
}
}

Eterm erts_map_from_ks_and_vs(ErtsHeapFactory *factory, Eterm *ks, Eterm *vs, Uint n)
{
Eterm res;
flatmap_t *fmp;

res = from_ks_and_vs(factory, ks, vs, n, &fmp);
if (fmp) {
if (erts_validate_and_sort_flatmap(fmp)) {
res = make_flatmap(fmp);
return make_flatmap(fmp);
}
else {
res = THE_NON_VALUE;
return THE_NON_VALUE;
}
} else {
return erts_hashmap_from_ks_and_vs_extra(factory, ks, vs, n,
THE_NON_VALUE, THE_NON_VALUE,
1);
}
return res;
}

Eterm erts_hashmap_from_ks_and_vs_extra(ErtsHeapFactory *factory,
Eterm *ks, Eterm *vs, Uint n,
Eterm key, Eterm value) {
Eterm key, Eterm value,
int reject_dupkeys) {
erts_ihash_t sw, hx;
Uint i,sz;
hxnode_t *hxns;
Expand Down Expand Up @@ -756,7 +745,8 @@ Eterm erts_hashmap_from_ks_and_vs_extra(ErtsHeapFactory *factory,
hxns[i].i = i;
}

res = hashmap_from_unsorted_array(factory, hxns, sz, 0, ERTS_ALC_T_TMP);
res = hashmap_from_unsorted_array(factory, hxns, sz, reject_dupkeys,
ERTS_ALC_T_TMP);

erts_free(ERTS_ALC_T_TMP, (void *) hxns);

Expand Down Expand Up @@ -2177,7 +2167,7 @@ Eterm erts_maps_put(Process *p, Eterm key, Eterm value, Eterm map) {
vs = flatmap_get_values(mp);

erts_factory_proc_init(&factory, p);
res = erts_hashmap_from_ks_and_vs_extra(&factory,ks,vs,n,key,value);
res = erts_hashmap_from_ks_and_vs_extra(&factory,ks,vs,n,key,value,0);
erts_factory_close(&factory);

return res;
Expand Down
5 changes: 3 additions & 2 deletions erts/emulator/beam/erl_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,13 @@ int hashmap_key_hash_cmp(Eterm* ap, Eterm* bp);
Eterm erts_hashmap_from_array(ErtsHeapFactory*, Eterm *leafs, Uint n, int reject_dupkeys);

#define erts_hashmap_from_ks_and_vs(F, KS, VS, N) \
erts_hashmap_from_ks_and_vs_extra((F), (KS), (VS), (N), THE_NON_VALUE, THE_NON_VALUE);
erts_hashmap_from_ks_and_vs_extra((F), (KS), (VS), (N), THE_NON_VALUE, THE_NON_VALUE, 0);

Eterm erts_map_from_ks_and_vs(ErtsHeapFactory *factory, Eterm *ks, Eterm *vs, Uint n);
Eterm erts_hashmap_from_ks_and_vs_extra(ErtsHeapFactory *factory,
Eterm *ks, Eterm *vs, Uint n,
Eterm k, Eterm v);
Eterm k, Eterm v,
int reject_dupkeys);

const Eterm *erts_maps_get(Eterm key, Eterm map);

Expand Down
1 change: 1 addition & 0 deletions erts/emulator/beam/erl_msacc.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ Eterm erts_msacc_gather_stats(ErtsMsAcc *msacc, ErtsHeapFactory *factory) {

state_map = erts_map_from_ks_and_vs(factory, erts_msacc_state_atoms, cvs,
ERTS_MSACC_STATE_COUNT);
ASSERT(is_map(state_map));

hp = erts_produce_heap(factory, MAP_HEADER_FLATMAP_SZ + 3, 0);
map = (flatmap_t*)hp;
Expand Down
5 changes: 5 additions & 0 deletions erts/emulator/test/nif_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2078,6 +2078,11 @@ maps(Config) when is_list(Config) ->

has_duplicate_keys = maps_from_list_nif([{1,1},{1,1}]),

%% Duplicate keys with > MAP_SMALL_MAP_LIMIT (32) entries must also
%% be rejected (GH-#10975)
DupPairs = [{I rem 2, I} || I <- lists:seq(0, 33)],
has_duplicate_keys = maps_from_list_nif(DupPairs),

verify_tmpmem(TmpMem),
ok.

Expand Down
Loading