summaryrefslogtreecommitdiff
path: root/py/map.c
AgeCommit message (Collapse)Author
2023-01-13py/map: Clear value when re-using slot with ordered dictionaries.Philip Peitsch
To adhere to the contract of mp_map_lookup, namely: MP_MAP_LOOKUP_ADD_IF_NOT_FOUND behaviour: - returns slot, with key non-null and value=MP_OBJ_NULL if it was added
2022-07-18py/obj: Add static safety checks to mp_obj_is_type().Yonatan Goldschmidt
Commit d96cfd13e3a464862c introduced a regression by breaking existing users of mp_obj_is_type(.., &mp_obj_bool). This function (and associated helpers like mp_obj_is_int()) have some specific nuances, and mistakes like this one can happen again. This commit adds mp_obj_is_exact_type() which behaves like the the old mp_obj_is_type(). The new mp_obj_is_type() has the same prototype but it attempts to statically assert that it's not called with types which should be checked using mp_obj_is_type(). If called with any of these types: int, str, bool, NoneType - it will cause a compilation error. Additional checked types (e.g function types) can be added in the future. Existing users of mp_obj_is_type() with the now "invalid" types, were translated to use mp_obj_is_exact_type(). The use of MP_STATIC_ASSERT() is not bulletproof - usually GCC (and other compilers) can't statically check conditions that are only known during link-time (like variables' addresses comparison). However, in this case, GCC is able to statically detect these conditions, probably because it's the exact same object - `&mp_type_int == &mp_type_int` is detected. Misuses of this function with runtime-chosen types (e.g: `mp_obj_type_t *x = ...; mp_obj_is_type(..., x);` won't be detected. MSC is unable to detect this, so we use MP_STATIC_ASSERT_NOT_MSC(). Compiling with this commit and without the fix for d96cfd13e3a464862c shows that it detects the problem. Signed-off-by: Yonatan Goldschmidt <yon.goldschmidt@gmail.com>
2021-10-15py: Add wrapper macros so hot VM functions can go in fast code location.Damien George
For example, on esp32 they can go in iRAM to improve performance. Signed-off-by: Damien George <damien@micropython.org>
2021-09-16py/map: Add an optional cache of (map+index) to speed up map lookups.Jim Mussared
The existing inline bytecode caching optimisation, selected by MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE, reserves an extra byte in the bytecode after certain opcodes, which at runtime stores a map index of the likely location of this field when looking up the qstr. This scheme is incompatible with bytecode-in-ROM, and doesn't work with native generated code. It also stores bytecode in .mpy files which is of a different format to when the feature is disabled, making generation of .mpy files more complex. This commit provides an alternative optimisation via an approach that adds a global cache for map offsets, then all mp_map_lookup operations use it. It's less precise than bytecode caching, but allows the cache to be independent and external to the bytecode that is executing. It also works for the native emitter and adds a similar performance boost on top of the gain already provided by the native emitter. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
2020-10-10py/objdict: Add mp_const_empty_dict_obj, use it for mp_const_empty_map.Jim Mussared
2020-04-27py/objdict: Fix popitem for ordered dicts.Jim Mussared
The popitem method wasn't implemented for ordered dicts and would result in an invalid state. Fixes issue #5956.
2020-02-28all: Reformat C and Python source code with tools/codeformat.py.Damien George
This is run with uncrustify 0.70.1, and black 19.10b0.
2019-02-12py: Downcase MP_xxx_SLOT_IS_FILLED inline functions.Damien George
2019-02-12py: Downcase all MP_OBJ_IS_xxx macros to make a more consistent C API.Damien George
These macros could in principle be (inline) functions so it makes sense to have them lower case, to match the other C API functions. The remaining macros that are upper case are: - MP_OBJ_TO_PTR, MP_OBJ_FROM_PTR - MP_OBJ_NEW_SMALL_INT, MP_OBJ_SMALL_INT_VALUE - MP_OBJ_NEW_QSTR, MP_OBJ_QSTR_VALUE - MP_OBJ_FUN_MAKE_SIG - MP_DECLARE_CONST_xxx - MP_DEFINE_CONST_xxx These must remain macros because they are used when defining const data (at least, MP_OBJ_NEW_SMALL_INT is so it makes sense to have MP_OBJ_SMALL_INT_VALUE also a macro). For those macros that have been made lower case, compatibility macros are provided for the old names so that users do not need to change their code immediately.
2018-08-02py: Fix compiling with debug enabled and make more use of DEBUG_printf.Damien George
DEBUG_printf and MICROPY_DEBUG_PRINTER is now used instead of normal printf, and a fault is fixed in mp_obj_class_lookup with debugging enabled; see issue #3999. Debugging can now be enabled on all ports including when nan-boxing is used.
2017-12-19py/map: Don't include ordered-dict mutating code when not needed.Damien George
2017-12-09py/map: Allow to trace rehashing operations.Paul Sokolovsky
2017-10-04all: Remove inclusion of internal py header files.Damien George
Header files that are considered internal to the py core and should not normally be included directly are: py/nlr.h - internal nlr configuration and declarations py/bc0.h - contains bytecode macro definitions py/runtime0.h - contains basic runtime enums Instead, the top-level header files to include are one of: py/obj.h - includes runtime0.h and defines everything to use the mp_obj_t type py/runtime.h - includes mpstate.h and hence nlr.h, obj.h, runtime0.h, and defines everything to use the general runtime support functions Additional, specific headers (eg py/objlist.h) can be included if needed.
2017-08-31py/map: Remove unused new/free functions.Damien George
Maps are always allocated "statically" and (de)initialised via mp_map_init and mp_map_deinit.
2017-08-31py/map: Replace always-false condition with assertion.Damien George
2017-07-31all: Use the name MicroPython consistently in commentsAlexander Steffen
There were several different spellings of MicroPython present in comments, when there should be only one.
2017-03-03py/map: Fix bugs with deletion of elements from OrderedDict.Damien George
There were 2 bugs, now fixed by this patch: - after deleting an element the len of the dict did not decrease by 1 - after deleting an element searching through the dict could lead to a seg fault due to there being an MP_OBJ_SENTINEL in the ordered array
2017-02-08py/map: Change mp_uint_t to size_t where appropriate.Damien George
The internal map/set functions now use size_t exclusively for computing addresses. size_t is enough to reach all of available memory when computing addresses so is the right type to use. In particular, for nanbox builds it saves quite a bit of code size and RAM compared to the original use of mp_uint_t (which is 64-bits on nanbox builds).
2016-05-20py: Declare constant data as properly constant.Damien George
Otherwise some compilers (eg without optimisation) will put this read-only data in RAM instead of ROM.
2016-04-15py/map: Change hash-table allocation policy to be less aggressive.Damien George
Small hash tables (eg those used in user class instances that only have a few members) now only use the minimum amount of memory necessary to hold the key/value pairs. This can reduce performance for instances that have many members (because then there are many reallocations/rehashings of the table), but helps to conserve memory. See issue #1760.
2016-04-01py/map: Prevent map resize failure from destroying map.Stephen Kyle
2015-12-31py/map: In map lookup, check for fixed map independent of ordered map.Damien George
It's possible to have a fixed map that is properly hashed (ie not simply ordered).
2015-12-26py/map: Add fast-path for hashing of map index when it is a qstr.Damien George
Map indicies are most commonly a qstr, and adding a fast-path for hashing of a qstr increases overall performance of the runtime. On pyboard there is a 4% improvement in the pystone benchmark for a cost of 20 bytes of code size. It's about a 2% improvement on unix.
2015-11-20py: Use MP_OBJ_NULL instead of NULL when appropriate.Damien George
2015-11-19py/map: Store key/value in earliest possible slot in hash table.Damien George
This change makes the code behave how it was supposed to work when first written. The avail_slot variable is set to the first free slot when looking for a key (which would come from deleting an entry). So it's more efficient (for subsequent lookups) to insert a new key into such a slot, rather than the very last slot that was searched.
2015-05-12py: Convert hash API to use MP_UNARY_OP_HASH instead of ad-hoc function.Damien George
Hashing is now done using mp_unary_op function with MP_UNARY_OP_HASH as the operator argument. Hashing for int, str and bytes still go via fast-path in mp_unary_op since they are the most common objects which need to be hashed. This lead to quite a bit of code cleanup, and should be more efficient if anything. It saves 176 bytes code space on Thumb2, and 360 bytes on x86. The only loss is that the error message "unhashable type" is now the more generic "unsupported type for __hash__".
2015-04-04py: Some trivial cosmetic changes, for code style consistency.Damien George
2015-03-20py: Clarify API for map/set lookup when removing&adding at once.Damien George
Addresses issue #1160.
2015-03-20py: Implement core of OrderedDict type.Paul Sokolovsky
Given that there's already support for "fixed table" maps, which are essentially ordered maps, the implementation of OrderedDict just extends "fixed table" maps by adding an "is ordered" flag and add/remove operations, and reuses 95% of objdict code, just making methods tolerant to both dict and OrderedDict. Some things are missing so far, like CPython-compatible repr and comparison. OrderedDict is Disabled by default; enabled on unix and stmhal ports.
2015-01-16py, unix: Allow to compile with -Wsign-compare.Damien George
See issue #699.
2015-01-01py: Move to guarded includes, everywhere in py/ core.Damien George
Addresses issue #1022.
2014-12-27py: Allow to properly disable builtin "set" object.Damien George
This patch makes MICROPY_PY_BUILTINS_SET compile-time option fully disable the builtin set object (when set to 0). This includes removing set constructor/comprehension from the grammar, the compiler and the emitters. Now, enabling set costs 8168 bytes on unix x64, and 3576 bytes on stmhal.
2014-11-27map: Add empty fixed map.Paul Sokolovsky
Useful when need to call kw-receiving functions without any keywords from C, etc.
2014-11-05py: Fix some macros defines; cleanup some includes.Damien George
2014-08-30py: Make map, dict, set use mp_int_t/mp_uint_t exclusively.Damien George
Part of code cleanup, towards resolving issue #50.
2014-07-03Rename machine_(u)int_t to mp_(u)int_t.Damien George
See discussion in issue #50.
2014-06-21py: Include mpconfig.h before all other includes.Paul Sokolovsky
It defines types used by all other headers. Fixes #691.
2014-05-03Add license header to (almost) all files.Damien George
Blanket wide to all .c and .h files. Some files originating from ST are difficult to deal with (license wise) so it was left out of those. Also merged modpyb.h, modos.h, modstm.h and modtime.h in stmhal/.
2014-04-28py: Fix bug in map lookup of interned string vs non-interned.Damien George
Had choice of either interning or forcing full equality comparison, and chose latter. See comments in mp_map_lookup. Addresses issue #523.
2014-04-07py: Revert revert for allocation policy of set hash table.Damien George
2014-04-07py: Revert change to allocation policy for mp_set_t.Damien George
Seems that this fixes all set tests.
2014-04-06py: Fix dict.copy() and low-level map/set allocation.Paul Sokolovsky
Two things: 1) set flags in copy properly; make mp_map_init() not be too smart and do something with requested alloc size. Policy of using prime numbers for alloc size is high-level policy which should be applied at corresponding high levels. Low-level functions should just do what they're asked to, because they don't have enough context to be smarter than that. For example, munging with alloc size of course breaks dict copying (as changing sizes requires rehashing).
2014-04-05py: Make mp_map_lookup not allocate memory on removal.Damien George
2014-04-05py: Change module globals from mp_map_t* to mp_obj_dict_t*.Damien George
Towards addressing issue #424. Had a small increase to ROM usage (order 60 bytes).
2014-04-05py: Fix delete operation on map/dict and set objects.Damien George
Hash table can now be completely full (ie now NULL entry) before a resize is triggered. Use sentinel value to indicate delete entry in the table.
2014-04-05map: When removing a key, don't NULL the entry, but mark as deleted.Paul Sokolovsky
When searching next time, such entry should be just skipped, not terminate the search. It's known that marking techique is not efficient at the presense of many removes, but namespace usage should not require many deletes, and as for user dictionaries - well, open addressing map table with linear rehashing and load factor of ~1 is not particularly efficient at all ;-). TODO: May consider "shift other entries in cluster" approach as an alternative.
2014-04-05map: Add mp_map_dump() (#ifdef'ed) to be handy when debugging maps.Paul Sokolovsky
2014-03-30Merge map.h into obj.h.Damien George
Pretty much everyone needs to include map.h, since it's such an integral part of the Micro Python object implementation. Thus, the definitions are now in obj.h instead. map.h is removed.
2014-03-17py: Clean up includes.xbe
Remove unnecessary includes. Add includes that improve portability.
2014-02-12Replace global "static" -> "STATIC", to allow "analysis builds". Part 2.Paul Sokolovsky