summaryrefslogtreecommitdiff
path: root/py/gc.c
AgeCommit message (Collapse)Author
2019-06-06Include display objects in gc.Dan Halbert
2019-04-18Correct collect of permanent pointers.Scott Shawcroft
The previous implementation managed to keep all but the head pointer of the list. Fixes #1814
2019-04-09Check that a never free pointer is on the heap.Scott Shawcroft
This fixes a crash on boards with built-in displays which statically allocate the display bus. When the pointer is provided to never free, it tries to allocate on the non-existant heap and crashes.
2019-04-08Reorganize board busses into shared-bindings and shared-module.Scott Shawcroft
2019-03-12Fix function signatureScott Shawcroft
2019-03-12Enter safe mode when an allocation is attempted on an uninitialized heap.Scott Shawcroft
2018-07-11WIP: after merge; before testingDan Halbert
2018-07-03Analysis fixes and long lived tweaks.Scott Shawcroft
2018-06-12py/gc: Add gc_sweep_all() function to run all remaining finalisers.Damien George
This patch adds the gc_sweep_all() function which does a garbage collection without tracing any root pointers, so frees all the memory, and most importantly runs any remaining finalisers. This helps primarily for soft reset: it will close any open files, any open sockets, and help to get the system back to a clean state upon soft reset.
2018-05-21py/gc: When GC threshold is hit don't unnecessarily collect twice.Damien George
Without this, if GC threshold is hit and there is not enough memory left to satisfy the request, gc_collect() will run a second time and the search for memory will happen again and will fail again. Thanks to @adritium for pointing out this issue, see #3786.
2018-05-13py/mpstate.h: Adjust start of root pointer section to exclude non-ptrs.Damien George
This patch moves the start of the root pointer section in mp_state_ctx_t so that it skips entries that are not pointers and don't need scanning. Previously, the start of the root pointer section was at the very beginning of the mp_state_ctx_t struct (which is the beginning of mp_state_thread_t). This was the original assembler version of the NLR code was hard-coded to have the nlr_top pointer at the start of this state structure. But now that the NLR code is partially written in C there is no longer this restriction on the location of nlr_top (and a comment to this effect has been removed in this patch). So now the root pointer section starts part way through the mp_state_thread_t structure, after the entries which are not root pointers. This patch also moves the non-pointer entries for MICROPY_ENABLE_SCHEDULER outside the root pointer section. Moving non-pointer entries out of the root pointer section helps to make the GC more precise and should help to prevent some cases of collectable garbage being kept. This patch also has a measurable improvement in performance of the pystone.py benchmark: on unix x86-64 and stm32 there was an improvement of roughly 0.6% (tested with both gcc 7.3 and gcc 8.1).
2018-02-19py/gc: Update comment now that gc_drain_stack is called gc_mark_subtree.Damien George
2018-02-19py/gc: Make GC stack pointer a local variable.Ayke van Laethem
This saves a bit in code size, and saves some precious .bss RAM: .text .bss minimal CROSS=1: -28 -4 unix (64-bit): -64 -8
2018-02-19py/gc: Rename gc_drain_stack to gc_mark_subtree and pass it first block.Ayke van Laethem
This saves a bit in code size: minimal CROSS=1: -44 unix: -96
2018-02-19py/gc: Reduce code size by specialising VERIFY_MARK_AND_PUSH macro.Ayke van Laethem
This macro is written out explicitly in the two locations that it is used and then the code is optimised, opening possibilities for further optimisations and reducing code size: unix: -48 minimal CROSS=1: -32 stm32: -32
2018-01-24Fix the initial state and polish a couple comments.Scott Shawcroft
2018-01-24Introduce a long lived section of the heap.Scott Shawcroft
This adapts the allocation process to start from either end of the heap when searching for free space. The default behavior is identical to the existing behavior where it starts with the lowest block and looks higher. Now it can also look from the highest block and lower depending on the long_lived parameter to gc_alloc. As the heap fills, the two sections may overlap. When they overlap, a collect may be triggered in order to keep the long lived section compact. However, free space is always eligable for each type of allocation. By starting from either of the end of the heap we have ability to separate short lived objects from long lived ones. This separation reduces heap fragmentation because long lived objects are easy to densely pack. Most objects are short lived initially but may be made long lived when they are referenced by a type or module. This involves copying the memory and then letting the collect phase free the old portion. QSTR pools and chunks are always long lived because they are never freed. The reallocation, collection and free processes are largely unchanged. They simply also maintain an index to the highest free block as well as the lowest. These indices are used to speed up the allocation search until the next collect. In practice, this change may slightly slow down import statements with the benefit that memory is much less fragmented afterwards. For example, a test import into a 20k heap that leaves ~6k free previously had the largest continuous free space of ~400 bytes. After this change, the largest continuous free space is over 3400 bytes.
2017-12-11py: Introduce a Python stack for scoped allocation.Damien George
This patch introduces the MICROPY_ENABLE_PYSTACK option (disabled by default) which enables a "Python stack" that allows to allocate and free memory in a scoped, or Last-In-First-Out (LIFO) way, similar to alloca(). A new memory allocation API is introduced along with this Py-stack. It includes both "local" and "nonlocal" LIFO allocation. Local allocation is intended to be equivalent to using alloca(), whereby the same function must free the memory. Nonlocal allocation is where another function may free the memory, so long as it's still LIFO. Follow-up patches will convert all uses of alloca() and VLA to the new scoped allocation API. The old behaviour (using alloca()) will still be available, but when MICROPY_ENABLE_PYSTACK is enabled then alloca() is no longer required or used. The benefits of enabling this option are (or will be once subsequent patches are made to convert alloca()/VLA): - Toolchains without alloca() can use this feature to obtain correct and efficient scoped memory allocation (compared to using the heap instead of alloca(), which is slower). - Even if alloca() is available, enabling the Py-stack gives slightly more efficient use of stack space when calling nested Python functions, due to the way that compilers implement alloca(). - Enabling the Py-stack with the stackless mode allows for even more efficient stack usage, as well as retaining high performance (because the heap is no longer used to build and destroy stackless code states). - With Py-stack and stackless enabled, Python-calling-Python is no longer recursive in the C mp_execute_bytecode function. The micropython.pystack_use() function is included to measure usage of the Python stack.
2017-12-09py/gc: In sweep debug output, print pointer as a pointer.Paul Sokolovsky
Or it will be truncated on a 64-bit platform.
2017-12-09py/gc: Factor out a macro to trace GC mark operations.Paul Sokolovsky
To allow easier override it for custom tracing.
2017-12-08py/gc: Add CLEAR_ON_SWEEP option to debug mis-traced objects.Paul Sokolovsky
Accessing them will crash immediately instead still working for some time, until overwritten by some other data, leading to much less deterministic crashes.
2017-11-29py/gc: In gc_realloc, convert pointer sanity checks to assertions.Damien George
These checks are assumed to be true in all cases where gc_realloc is called with a valid pointer, so no need to waste code space and time checking them in a non-debug build.
2017-10-24Merge commit 'f869d6b2e339c04469c6c9ea3fb2fabd7bbb2d8c' into nrf2_mergeScott Shawcroft
This is prep for merging in the NRF5 pull request.
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-25Initial merge of micropython v1.9.2 into circuitpython 2.0.0 (in ↵Dan Halbert
development) master. cpx build compiles and loads and works in repl; test suite not run yet esp8266 not tested yet
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.
2017-07-12py/gc: Refactor assertions in gc_free function.Damien George
gc_free() expects either NULL or a valid pointer into the heap, so the checks for a valid pointer can be turned into assertions.
2017-06-20Merge tag 'v1.9.1'2.0.0-alpha.0Scott Shawcroft
Fixes for stmhal USB mass storage, lwIP bindings and VFS regressions This release provides an important fix for the USB mass storage device in the stmhal port by implementing the SCSI SYNCHRONIZE_CACHE command, which is now require by some Operating Systems. There are also fixes for the lwIP bindings to improve non-blocking sockets and error codes. The VFS has some regressions fixed including the ability to statvfs the root. All changes are listed below. py core: - modbuiltins: add core-provided version of input() function - objstr: catch case of negative "maxsplit" arg to str.rsplit() - persistentcode: allow to compile with complex numbers disabled - objstr: allow to compile with obj-repr D, and unicode disabled - modsys: allow to compile with obj-repr D and PY_ATTRTUPLE disabled - provide mp_decode_uint_skip() to help reduce stack usage - makeqstrdefs.py: make script run correctly with Python 2.6 - objstringio: if created from immutable object, follow copy on write policy extmod: - modlwip: connect: for non-blocking mode, return EINPROGRESS - modlwip: fix error codes for duplicate calls to connect() - modlwip: accept: fix error code for non-blocking mode - vfs: allow to statvfs the root directory - vfs: allow "buffering" and "encoding" args to VFS's open() - modframebuf: fix signed/unsigned comparison pendantic warning lib: - libm: use isfinite instead of finitef, for C99 compatibility - utils/interrupt_char: remove support for KBD_EXCEPTION disabled tests: - basics/string_rsplit: add tests for negative "maxsplit" argument - float: convert "sys.exit()" to "raise SystemExit" - float/builtin_float_minmax: PEP8 fixes - basics: convert "sys.exit()" to "raise SystemExit" - convert remaining "sys.exit()" to "raise SystemExit" unix port: - convert to use core-provided version of built-in import() - Makefile: replace references to make with $(MAKE) windows port: - convert to use core-provided version of built-in import() qemu-arm port: - Makefile: adjust object-file lists to get correct dependencies - enable micropython.mem_*() functions to allow more tests stmhal port: - boards: enable DAC for NUCLEO_F767ZI board - add support for NUCLEO_F446RE board - pass USB handler as parameter to allow more than one USB handler - usb: use local USB handler variable in Start-of-Frame handler - usb: make state for USB device private to top-level USB driver - usbdev: for MSC implement SCSI SYNCHRONIZE_CACHE command - convert from using stmhal's input() to core provided version cc3200 port: - convert from using stmhal's input() to core provided version teensy port: - convert from using stmhal's input() to core provided version esp8266 port: - Makefile: replace references to make with $(MAKE) - Makefile: add clean-modules target - convert from using stmhal's input() to core provided version zephyr port: - modusocket: getaddrinfo: Fix mp_obj_len() usage - define MICROPY_PY_SYS_PLATFORM (to "zephyr") - machine_pin: use native Zephyr types for Zephyr API calls docs: - machine.Pin: remove out_value() method - machine.Pin: add on() and off() methods - esp8266: consistently replace Pin.high/low methods with .on/off - esp8266/quickref: polish Pin.on()/off() examples - network: move confusingly-named cc3200 Server class to its reference - uos: deconditionalize, remove minor port-specific details - uos: move cc3200 port legacy VFS mounting functions to its ref doc - machine: sort machine classes in logical order, not alphabetically - network: first step to describe standard network class interface examples: - embedding: use core-provided KeyboardInterrupt object
2017-05-05atmel-samd: Fix sporadic "syntax errors"Scott Shawcroft
The GC was deleting memory that was in use because its scan of the stack missed the very top. Switching to _estack fixes this by relying on the location from the linker. Fixes #124
2017-04-12py/gc: Execute finaliser code in a protected environment.Damien George
If a finaliser raises an exception then it must not propagate through the GC sweep function. This patch protects against such a thing by running finaliser code via the mp_call_function_1_protected call. This patch also adds scheduler lock/unlock calls around the finaliser execution to further protect against any possible reentrancy issues: the memory manager is already locked when doing a collection, but we also don't want to allow any scheduled code to run, KeyboardInterrupts to interupt the code, nor threads to switch.
2016-11-29Revert "py: Add ability to manually mark blocks during collect."Scott Shawcroft
This reverts commit 93218281588b42331d83e4aaa45ac1abe4af130b.
2016-11-23Add heap analysis scripts based on GDB breakpoint logs.Scott Shawcroft
2016-11-21This introduces an alternative hardware API called nativeio structured ↵Scott Shawcroft
around different functions that are typically accelerated by native hardware. Its not meant to reflect the structure of the hardware. Docs are here: http://tannewt-micropython.readthedocs.io/en/microcontroller/ It differs from upstream's machine in the following ways: * Python API is identical across ports due to code structure. (Lives in shared-bindings) * Focuses on abstracting common functionality (AnalogIn) and not representing structure (ADC). * Documentation lives with code making it easy to ensure they match. * Pin is split into references (board.D13 and microcontroller.pin.PA17) and functionality (DigitalInOut). * All nativeio classes claim underlying hardware resources when inited on construction, support Context Managers (aka with statements) and have deinit methods which release the claimed hardware. * All constructors take pin references rather than peripheral ids. Its up to the implementation to find hardware or throw and exception.
2016-11-21py: Add ability to manually mark blocks during collect.Scott Shawcroft
2016-08-26py/gc: Add MICROPY_GC_CONSERVATIVE_CLEAR option to always zero memory.Damien George
There can be stray pointers in memory blocks that are not properly zero'd after allocation. This patch adds a new config option to always zero all allocated memory (via gc_alloc and gc_realloc) and hence help to eliminate stray pointers. See issue #2195.
2016-07-21py/gc: Implement GC running by allocation threshold.Paul Sokolovsky
Currently, MicroPython runs GC when it could not allocate a block of memory, which happens when heap is exhausted. However, that policy can't work well with "inifinity" heaps, e.g. backed by a virtual memory - there will be a lot of swap thrashing long before VM will be exhausted. Instead, in such cases "allocation threshold" policy is used: a GC is run after some number of allocations have been made. Details vary, for example, number or total amount of allocations can be used, threshold may be self-adjusting based on GC outcome, etc. This change implements a simple variant of such policy for MicroPython. Amount of allocated memory so far is used for threshold, to make it useful to typical finite-size, and small, heaps as used with MicroPython ports. And such GC policy is indeed useful for such types of heaps too, as it allows to better control fragmentation. For example, if a threshold is set to half size of heap, then for an application which usually makes big number of small allocations, that will (try to) keep half of heap memory in a nice defragmented state for an occasional large allocation. For an application which doesn't exhibit such behavior, there won't be any visible effects, except for GC running more frequently, which however may affect performance. To address this, the GC threshold is configurable, and by default is off so far. It's configured with gc.threshold(amount_in_bytes) call (can be queries without an argument).
2016-07-01py/gc: Calculate (and report) maximum contiguous free block size.Paul Sokolovsky
Just as maximum allocated block size, it's reported in allocation units (not bytes).
2016-06-30py/gc: Be sure to count last allocated block at heap end in stats.Paul Sokolovsky
Previously, if there was chain of allocated blocks ending with the last block of heap, it wasn't included in number of 1/2-block or max block size stats.
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/gc: Fix GC+thread bug where ptr gets lost because it's not computed.Damien George
GC_EXIT() can cause a pending thread (waiting on the mutex) to be scheduled right away. This other thread may trigger a garbage collection. If the pointer to the newly-allocated block (allocated by the original thread) is not computed before the switch (so it's just left as a block number) then the block will be wrongly reclaimed. This patch makes sure the pointer is computed before allowing any thread switch to occur.
2016-06-28py/gc: Fix 2 cases of concurrent access to ATB and FTB.Damien George
2016-06-28py/gc: Make memory manager and garbage collector thread safe.Damien George
By using a single, global mutex, all memory-related functions (alloc, free, realloc, collect, etc) are made thread safe. This means that only one thread can be in such a function at any one time.
2016-06-28py: Add MP_STATE_THREAD to hold state specific to a given thread.Damien George
2016-05-13py/gc: gc_dump_alloc_table(): Dump heap offset instead of actual address.Paul Sokolovsky
Address printed was truncated anyway and in general confusing to outsider. A line which dumps it is still left in the source, commented, for peculiar cases when it may be needed (e.g. when running under debugger).
2016-05-13gc: gc_dump_alloc_table(): Use '=' char for tail blocks.Paul Sokolovsky
'=' is pretty natural character for tail, and gives less dense picture where it's easier to see what object types are actually there.
2016-05-11py/gc: Make (byte)array type dumping conditional on these types being enabled.Paul Sokolovsky
2016-05-11py/gc: gc_dump_alloc_table(): Show byte/str and (byte)array objects.Paul Sokolovsky
These are typical consumers of large chunks of memory, so it's useful to see at least their number (how much memory isn't clearly shown, as the data for these objects is allocated elsewhere).
2015-12-27py/gc: Improve mark/sweep debug output.Paul Sokolovsky
Previously, mark operation weren't logged at all, while it's quite useful to see cascade of marks in case of over-marking (and in other cases too). Previously, sweep was logged for each block of object in memory, but that doesn't make much sense and just lead to longer output, harder to parse by a human. Instead, log sweep only once per object. This is similar to other memory manager operations, e.g. an object is allocated, then freed. Or object is allocated, then marked, otherwise swept (one log entry per operation, with the same memory address in each case).
2015-12-18py/gc: When printing info, use %u instead of UINT_FMT for size_t args.Damien George
Ideally we'd use %zu for size_t args, but that's unlikely to be supported by all runtimes, and we would then need to implement it in mp_printf. So simplest and most portable option is to use %u and cast the argument to uint(=unsigned int). Note: reason for the change is that UINT_FMT can be %llu (size suitable for mp_uint_t) which is wider than size_t and prints incorrect results.