Prevent repetitive recursive scanning of dicts when making them long-lived
This commit is contained in:
parent
85a5276f36
commit
be1d882a8b
|
@ -91,6 +91,13 @@ mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth) {
|
||||||
if (dict == NULL || max_depth == 0) {
|
if (dict == NULL || max_depth == 0) {
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
// Don't recurse unnecessarily. Return immediately if we've already seen this dict.
|
||||||
|
if (dict->map.scanning) {
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
// Mark that we're processing this dict.
|
||||||
|
dict->map.scanning = 1;
|
||||||
|
|
||||||
// Update all of the references first so that we reduce the chance of references to the old
|
// Update all of the references first so that we reduce the chance of references to the old
|
||||||
// copies.
|
// copies.
|
||||||
dict->map.table = gc_make_long_lived(dict->map.table);
|
dict->map.table = gc_make_long_lived(dict->map.table);
|
||||||
|
@ -100,7 +107,10 @@ mp_obj_dict_t *make_dict_long_lived(mp_obj_dict_t *dict, uint8_t max_depth) {
|
||||||
dict->map.table[i].value = make_obj_long_lived(value, max_depth - 1);
|
dict->map.table[i].value = make_obj_long_lived(value, max_depth - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return gc_make_long_lived(dict);
|
dict = gc_make_long_lived(dict);
|
||||||
|
// Done recursing through this dict.
|
||||||
|
dict->map.scanning = 0;
|
||||||
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_str_t *make_str_long_lived(mp_obj_str_t *str) {
|
mp_obj_str_t *make_str_long_lived(mp_obj_str_t *str) {
|
||||||
|
|
4
py/obj.h
4
py/obj.h
|
@ -359,7 +359,9 @@ typedef struct _mp_map_t {
|
||||||
size_t all_keys_are_qstrs : 1;
|
size_t all_keys_are_qstrs : 1;
|
||||||
size_t is_fixed : 1; // a fixed array that can't be modified; must also be ordered
|
size_t is_fixed : 1; // a fixed array that can't be modified; must also be ordered
|
||||||
size_t is_ordered : 1; // an ordered array
|
size_t is_ordered : 1; // an ordered array
|
||||||
size_t used : (8 * sizeof(size_t) - 3);
|
size_t scanning : 1; // true if we're in the middle of scanning linked dictionaries,
|
||||||
|
// e.g., make_dict_long_lived()
|
||||||
|
size_t used : (8 * sizeof(size_t) - 4);
|
||||||
size_t alloc;
|
size_t alloc;
|
||||||
mp_map_elem_t *table;
|
mp_map_elem_t *table;
|
||||||
} mp_map_t;
|
} mp_map_t;
|
||||||
|
|
Loading…
Reference in New Issue