From d0e824387e9bb50b03544969bccced4adf2ac7df Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 5 Apr 2014 23:33:12 +0100 Subject: [PATCH] py: Make mp_map_lookup not allocate memory on removal. --- py/map.c | 16 +++++++++------- py/objdict.c | 4 ---- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/py/map.c b/py/map.c index 5b9e803774..bb3d5d8898 100644 --- a/py/map.c +++ b/py/map.c @@ -91,6 +91,12 @@ STATIC void mp_map_rehash(mp_map_t *map) { m_del(mp_map_elem_t, old_table, old_alloc); } +// MP_MAP_LOOKUP behaviour: +// - returns NULL if not found, else the slot it was found in with key,value non-null +// MP_MAP_LOOKUP_ADD_IF_NOT_FOUND behaviour: +// - returns slot, with key non-null and value=MP_OBJ_NULL if it was added +// MP_MAP_LOOKUP_REMOVE_IF_FOUND behaviour: +// - returns NULL if not found, else the slot if was found in with key null and value non-null mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind) { // if the map is a fixed array then we must do a brute force linear search if (map->table_is_fixed_array) { @@ -135,7 +141,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t } return slot; } else { - return MP_OBJ_NULL; + return NULL; } } else if (slot->key == MP_OBJ_SENTINEL) { // found deleted slot, remember for later @@ -146,10 +152,6 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t // found index // Note: CPython does not replace the index; try x={True:'true'};x[1]='one';x if (lookup_kind & MP_MAP_LOOKUP_REMOVE_IF_FOUND) { - // this leaks this memory (but see dict_get_helper) - mp_map_elem_t *retval = m_new(mp_map_elem_t, 1); - retval->key = slot->key; - retval->value = slot->value; // delete element in this slot map->used--; if (map->table[(pos + 1) % map->alloc].key == MP_OBJ_NULL) { @@ -158,7 +160,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t } else { slot->key = MP_OBJ_SENTINEL; } - return retval; + // keep slot->value so that caller can access it if needed } return slot; } @@ -185,7 +187,7 @@ mp_map_elem_t* mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t start_pos = pos = hash % map->alloc; } } else { - return MP_OBJ_NULL; + return NULL; } } } diff --git a/py/objdict.c b/py/objdict.c index 5a314aed80..db68889bbe 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -208,10 +208,6 @@ STATIC mp_obj_t dict_get_helper(mp_map_t *self, mp_obj_t key, mp_obj_t deflt, mp } } else { value = elem->value; - if (lookup_kind == MP_MAP_LOOKUP_REMOVE_IF_FOUND) { - // catch the leak (from mp_map_lookup) - m_free(elem, sizeof(mp_map_elem_t)); - } } if (lookup_kind == MP_MAP_LOOKUP_ADD_IF_NOT_FOUND) { elem->value = value;