summaryrefslogtreecommitdiff
path: root/py/qstr.c
AgeCommit message (Collapse)Author
2020-04-05all: Use MP_ERROR_TEXT for all error messages.Jim Mussared
2020-04-05py: Implement "common word" compression scheme for error messages.Jim Mussared
The idea here is that there's a moderate amount of ROM used up by exception text. Obviously we try to keep the messages short, and the code can enable terse errors, but it still adds up. Listed below is the total string data size for various ports: bare-arm 2860 minimal 2876 stm32 8926 (PYBV11) cc3200 3751 esp32 5721 This commit implements compression of these strings. It takes advantage of the fact that these strings are all 7-bit ascii and extracts the top 128 frequently used words from the messages and stores them packed (dropping their null-terminator), then uses (0x80 | index) inside strings to refer to these common words. Spaces are automatically added around words, saving more bytes. This happens transparently in the build process, mirroring the steps that are used to generate the QSTR data. The MP_COMPRESSED_ROM_TEXT macro wraps any literal string that should compressed, and it's automatically decompressed in mp_decompress_rom_string. There are many schemes that could be used for the compression, and some are included in py/makecompresseddata.py for reference (space, Huffman, ngram, common word). Results showed that the common-word compression gets better results. This is before counting the increased cost of the Huffman decoder. This might be slightly counter-intuitive, but this data is extremely repetitive at a word-level, and the byte-level entropy coder can't quite exploit that as efficiently. Ideally one would combine both approaches, but for now the common-word approach is the one that is used. For additional comparison, the size of the raw data compressed with gzip and zlib is calculated, as a sort of proxy for a lower entropy bound. With this scheme we come within 15% on stm32, and 30% on bare-arm (i.e. we use x% more bytes than the data compressed with gzip -- not counting the code overhead of a decoder, and how this would be hypothetically implemented). The feature is disabled by default and can be enabled by setting MICROPY_ROM_TEXT_COMPRESSION at the Makefile-level.
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.
2020-01-23py/qstr: Don't include or init qstr_mutex when GIL is enabled.David Lechner
When threads and the GIL are enabled, then the qstr mutex is not needed. The qstr_mutex field is never used in this case because of: #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL #define QSTR_ENTER() mp_thread_mutex_lock(&MP_STATE_VM(qstr_mutex), 1) #define QSTR_EXIT() mp_thread_mutex_unlock(&MP_STATE_VM(qstr_mutex)) #else #define QSTR_ENTER() #define QSTR_EXIT() #endif So, we can completely remove qstr_mutex everywhere when MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL.
2019-11-26py/qstr: Raise exception in qstr_from_strn if str to intern is too long.Léa Saviot
The string length being longer than the allowed qstr length can happen in many locations, for example in the parser with very long variable names. Without an explicit check that the length is within range (as done in this patch) the code would exhibit crashes and strange behaviour with truncated strings.
2019-02-19py/qstr: Evaluate find_qstr only once then pass to Q_GET_HASH macro.Damien George
Q_GET_HASH may evaluate its argument more than once.
2018-12-15py/qstr: Put a lower bound on new qstr pool allocation.Damien George
2017-11-29py/qstr: Rewrite find_qstr to make manifest that it returns a valid ptr.Damien George
So long as the input qstr identifier is valid (below the maximum number of qstrs) the function will always return a valid pointer. This patch eliminates the "return 0" dead-code.
2017-11-01py/compile: Use alloca instead of qstr_build when compiling import name.Damien George
The technique of using alloca is how dotted import names are composed in mp_import_from and mp_builtin___import__, so use the same technique in the compiler. This puts less pressure on the heap (only the stack is used if the qstr already exists, and if it doesn't exist then the standard qstr block memory is used for the new qstr rather than a separate chunk of the heap) and reduces overall code size.
2017-08-15py: Add verbose debug compile-time flag MICROPY_DEBUG_VERBOSE.Stefan Naumann
It enables all the DEBUG_printf outputs in the py/ source code.
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.
2016-11-02py: Fix wrong assumption that m_renew will not move if shrinkingColin Hogben
In both parse.c and qstr.c, an internal chunking allocator tidies up by calling m_renew to shrink an allocated chunk to the size used, and assumes that the chunk will not move. However, when MICROPY_ENABLE_GC is false, m_renew calls the system realloc, which does not guarantee this behaviour. Environments where realloc may return a different pointer include: (1) mbed-os with MBED_HEAP_STATS_ENABLED (which adds a wrapper around malloc & friends; this is where I was hit by the bug); (2) valgrind on linux (how I diagnosed it). The fix is to call m_renew_maybe with allow_move=false.
2016-09-19py/qstr: Remove a comment.Damien George
qstrs are always null terminated so qstr_str will stay as part of the API.
2016-06-28py: Don't use gc or qstr mutex when the GIL is enabled.Damien George
There is no need since the GIL already makes gc and qstr operations atomic.
2016-06-28py: Make interning of qstrs thread safe.Damien George
2016-06-16py: Rename __QSTR_EXTRACT flag to NO_QSTR.Paul Sokolovsky
It has more usages than just qstr extraction, for example, embedding (where people don't care about efficient predefined qstrs).
2016-04-19py: Rework QSTR extraction to work in simple and obvious way.Paul Sokolovsky
When there're C files to be (re)compiled, they're all passed first to preprocessor. QSTR references are extracted from preprocessed output and split per original C file. Then all available qstr files (including those generated previously) are catenated together. Only if the resulting content has changed, the output file is written (causing almost global rebuild to pick up potentially renumbered qstr's). Otherwise, it's not updated to not cause spurious rebuilds. Related make rules are split to minimize amount of commands executed in the interim case (when some C files were updated, but no qstrs were changed).
2016-04-13py: Add ability to have frozen persistent bytecode from .mpy files.Damien George
The config variable MICROPY_MODULE_FROZEN is now made of two separate parts: MICROPY_MODULE_FROZEN_STR and MICROPY_MODULE_FROZEN_MPY. This allows to have none, either or both of frozen strings and frozen mpy files (aka frozen bytecode).
2015-12-17py/qstr: Use size_t instead of mp_uint_t when counting allocated bytes.Damien George
2015-11-29py: Change qstr_* functions to use size_t as the type for str len arg.Damien George
2015-10-13py/qstr: Fix calc of qstr memory usage, due to new qstr chunk allocation.Damien George
2015-07-20py: Make qstr hash size configurable, defaults to 2 bytes.Damien George
This patch makes configurable, via MICROPY_QSTR_BYTES_IN_HASH, the number of bytes used for a qstr hash. It was originally fixed at 2 bytes, and now defaults to 2 bytes. Setting it to 1 byte will save ROM and RAM at a small expense of hash collisions.
2015-07-14py: Improve allocation policy of qstr data.Damien George
Previous to this patch all interned strings lived in their own malloc'd chunk. On average this wastes N/2 bytes per interned string, where N is the number-of-bytes for a quanta of the memory allocator (16 bytes on 32 bit archs). With this patch interned strings are concatenated into the same malloc'd chunk when possible. Such chunks are enlarged inplace when possible, and shrunk to fit when a new chunk is needed. RAM savings with this patch are highly varied, but should always show an improvement (unless only 3 or 4 strings are interned). New version typically uses about 70% of previous memory for the qstr data, and can lead to savings of around 10% of total memory footprint of a running script. Costs about 120 bytes code size on Thumb2 archs (depends on how many calls to gc_realloc are made).
2015-04-16py: Convert occurrences of non-debug printf to mp_printf.Damien George
2015-02-10py: Add option to micropython.qstr_info() to dump actual qstrs.Damien George
2015-01-16py, unix: Allow to compile with -Wsign-compare.Damien George
See issue #699.
2015-01-13py: Never intern data of large string/bytes object; add relevant tests.Damien George
Previously to this patch all constant string/bytes objects were interned by the compiler, and this lead to crashes when the qstr was too long (noticeable now that qstr length storage defaults to 1 byte). With this patch, long string/bytes objects are never interned, and are referenced directly as constant objects within generated code using load_const_obj.
2015-01-11py: Add MICROPY_QSTR_BYTES_IN_LEN config option, defaulting to 1.Damien George
This new config option sets how many fixed-number-of-bytes to use to store the length of each qstr. Previously this was hard coded to 2, but, as per issue #1056, this is considered overkill since no-one needs identifiers longer than 255 bytes. With this patch the number of bytes for the length is configurable, and defaults to 1 byte. The configuration option filters through to the makeqstrdata.py script. Code size savings going from 2 to 1 byte: - unix x64 down by 592 bytes - stmhal down by 1148 bytes - bare-arm down by 284 bytes Also has RAM savings, and will be slightly more efficient in execution.
2015-01-11py: Add qstr cfg capability; generate QSTR_NULL and QSTR_ from script.Damien George
2015-01-11py: Fix hard-coded hash for empty qstr (was 0x0000 now 0x1505).Damien George
2015-01-07py: Put all global state together in state structures.Damien George
This patch consolidates all global variables in py/ core into one place, in a global structure. Root pointers are all located together to make GC tracing easier and more efficient.
2015-01-01py: Move to guarded includes, everywhere in py/ core.Damien George
Addresses issue #1022.
2014-10-31py: Make gc.enable/disable just control auto-GC; alloc is still allowed.Damien George
gc.enable/disable are now the same as CPython: they just control whether automatic garbage collection is enabled or not. If disabled, you can still allocate heap memory, and initiate a manual collection.
2014-10-24py: Improve memory usage debugging; better GC AT dumping.Damien George
In unix port, mem_info(1) now prints pretty GC alloc table.
2014-10-03py: Change [u]int to mp_[u]int_t in qstr.[ch], and some other places.Damien George
This should pretty much resolve 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-06-11py: Fix static defn in qstr; include mpconfigport.h with "" (not <>).Damien George
2014-05-25Change const byte* to const char* where sensible.Damien George
This removes need for some casts (at least, more than it adds need for new casts!).
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-17build: Simplify build directory layout by putting all headers in genhdr.Damien George
Any generated headers go in $(BUILD)/genhdr/, and are #included as 'genhdr/xxx.h'.
2014-04-16build directory can now be renamedAndrew Scheller
The autogenerated header files have been moved about, and an extra include dir has been added, which means you can give a custom BUILD=newbuilddir option to make, and everything "just works" Also tidied up the way the different Makefiles build their include- directory flags
2014-04-14qstr, objstr: Make sure that valid hash != 0, treat 0 as "not computed".Paul Sokolovsky
This feature was proposed with initial hashing RFC, and is prerequisite for seamless static str object definition.
2014-03-25py: Replace naive and teribble hash function with djb2.Damien George
2014-02-26py: Remove name of var arg from macros with var args.Damien George
2014-02-16Make DEBUG_printf() a proper function, implementation is port-dependent.Paul Sokolovsky
In particular, unix outputs to stderr, to allow to run testsuite against micropython built with debug output (by redirecting stderr to /dev/null).
2014-02-12Replace global "static" -> "STATIC", to allow "analysis builds". Part 2.Paul Sokolovsky
2014-01-29Add qstr_info() function and bindings for unix port.Damien George
2014-01-24Rework makefiles. Add proper dependency checking.Dave Hylands
2014-01-23py: Implement bool unary op; tidy up unary op dispatch.Damien George