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) {
|
||||
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
|
||||
// copies.
|
||||
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);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
|
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 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 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;
|
||||
mp_map_elem_t *table;
|
||||
} mp_map_t;
|
||||
|
Loading…
Reference in New Issue
Block a user