Skip to content

Add selective collect to memory allocations #10264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion extmod/modasyncio.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ mp_obj_t mp_asyncio_context = MP_OBJ_NULL;

static mp_obj_t task_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
mp_arg_check_num(n_args, n_kw, 1, 2, false);
mp_obj_task_t *self = m_new_obj(mp_obj_task_t);
// CIRCUITPY-CHANGE: Task holds onto core and data so collect it.
mp_obj_task_t *self = m_malloc_with_collect(sizeof(mp_obj_task_t));
self->pairheap.base.type = type;
mp_pairheap_init_node(task_lt, &self->pairheap);
self->coro = args[0];
Expand Down
3 changes: 2 additions & 1 deletion extmod/vfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,8 @@ mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args
}

// create new object
mp_vfs_mount_t *vfs = m_new_obj(mp_vfs_mount_t);
// CIRCUITPY-CHANGE: Collect the mount object because it references others
mp_vfs_mount_t *vfs = m_malloc_with_collect(sizeof(mp_vfs_mount_t));
vfs->str = mnt_str;
vfs->len = mnt_len;
vfs->obj = vfs_obj;
Expand Down
12 changes: 9 additions & 3 deletions ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ"
LONGINT_IMPL = MPZ

CIRCUITPY_AESIO = 0
CIRCUITPY_JPEGIO = 0
CIRCUITPY_SYNTHIO = 0
CIRCUITPY_TILEPALETTEMAPPER = 0
CIRCUITPY_CODEOP = 0
CIRCUITPY_EPAPERDISPLAY = 0
CIRCUITPY_FLOPPYIO = 0
CIRCUITPY_I2CDISPLAYBUS = 0
CIRCUITPY_I2CTARGET = 0
CIRCUITPY_PARALLELDISPLAYBUS = 0
CIRCUITPY_RGBMATRIX = 0
CIRCUITPY_SHARPDISPLAY = 0
CIRCUITPY_SPITARGET = 0
2 changes: 2 additions & 0 deletions ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ CHIP_FAMILY = samd51
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ"
LONGINT_IMPL = MPZ

CIRCUITPY_I2CTARGET = 0
CIRCUITPY_SPITARGET = 0
CIRCUITPY_SYNTHIO = 0
CIRCUITPY_JPEGIO = 0
Expand Down
4 changes: 2 additions & 2 deletions ports/raspberrypi/boards/adafruit_fruit_jam/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@

#define I2S_RESET_PIN_NUMBER 22

#if defined(DEFAULT_USB_HOST_5V_POWER)
bool board_reset_pin_number(uint8_t pin_number) {
#if defined(DEFAULT_USB_HOST_5V_POWER)
if (pin_number == DEFAULT_USB_HOST_5V_POWER->number) {
// doing this (rather than gpio_init) in this specific order ensures no
// glitch if pin was already configured as a high output. gpio_init() temporarily
Expand All @@ -29,6 +29,7 @@ bool board_reset_pin_number(uint8_t pin_number) {

return true;
}
#endif
// Set I2S out of reset.
if (pin_number == I2S_RESET_PIN_NUMBER) {
gpio_put(pin_number, 1);
Expand All @@ -39,7 +40,6 @@ bool board_reset_pin_number(uint8_t pin_number) {
}
return false;
}
#endif

void board_init(void) {
// Reset the DAC to put it in a known state.
Expand Down
3 changes: 2 additions & 1 deletion ports/unix/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ void mp_unix_alloc_exec(size_t min_size, void **ptr, size_t *size) {
}

// add new link to the list of mmap'd regions
mmap_region_t *rg = m_new_obj(mmap_region_t);
// CIRCUITPY-CHANGE: Collect the mmap region because it points to others.
mmap_region_t *rg = m_malloc_with_collect(sizeof(mmap_region_t));
rg->ptr = *ptr;
rg->len = min_size;
rg->next = MP_STATE_VM(mmap_region_head);
Expand Down
1 change: 1 addition & 0 deletions ports/unix/mpconfigport.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ typedef long mp_off_t;

// Always enable GC.
#define MICROPY_ENABLE_GC (1)
#define MICROPY_ENABLE_SELECTIVE_COLLECT (1)

#if !(defined(MICROPY_GCREGS_SETJMP) || defined(__x86_64__) || defined(__i386__) || defined(__thumb2__) || defined(__thumb__) || defined(__arm__))
// Fall back to setjmp() implementation for discovery of GC pointers in registers.
Expand Down
4 changes: 2 additions & 2 deletions py/bc.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,14 +302,14 @@ static inline void mp_module_context_alloc_tables(mp_module_context_t *context,
#if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE
size_t nq = (n_qstr * sizeof(qstr_short_t) + sizeof(mp_uint_t) - 1) / sizeof(mp_uint_t);
size_t no = n_obj;
mp_uint_t *mem = m_new(mp_uint_t, nq + no);
mp_uint_t *mem = m_malloc_items(nq + no);
context->constants.qstr_table = (qstr_short_t *)mem;
context->constants.obj_table = (mp_obj_t *)(mem + nq);
#else
if (n_obj == 0) {
context->constants.obj_table = NULL;
} else {
context->constants.obj_table = m_new(mp_obj_t, n_obj);
context->constants.obj_table = m_malloc_items(n_obj);
}
#endif
}
Expand Down
1 change: 1 addition & 0 deletions py/circuitpy_mpconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ extern void common_hal_mcu_enable_interrupts(void);
#define MICROPY_EMIT_X64 (0)
#define MICROPY_ENABLE_DOC_STRING (0)
#define MICROPY_ENABLE_FINALISER (1)
#define MICROPY_ENABLE_SELECTIVE_COLLECT (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_ENABLE_PYSTACK (1)
#define MICROPY_TRACKED_ALLOC (CIRCUITPY_SSL_MBEDTLS)
Expand Down
5 changes: 3 additions & 2 deletions py/compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,8 @@ static void mp_emit_common_start_pass(mp_emit_common_t *emit, pass_kind_t pass)
if (emit->ct_cur_child == 0) {
emit->children = NULL;
} else {
emit->children = m_new0(mp_raw_code_t *, emit->ct_cur_child);
// CIRCUITPY-CHANGE: Use m_malloc_helper with collect flag to support selective collection
emit->children = m_malloc_helper(sizeof(mp_raw_code_t *) * (emit->ct_cur_child), M_MALLOC_ENSURE_ZEROED | M_MALLOC_RAISE_ERROR | M_MALLOC_COLLECT);
}
}
emit->ct_cur_child = 0;
Expand Down Expand Up @@ -3688,7 +3689,7 @@ void mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool

mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl) {
mp_compiled_module_t cm;
cm.context = m_new_obj(mp_module_context_t);
cm.context = m_malloc_with_collect(sizeof(mp_module_context_t));
cm.context->module.globals = mp_globals_get();
mp_compile_to_raw_code(parse_tree, source_file, is_repl, &cm);
// return function that executes the outer module
Expand Down
2 changes: 1 addition & 1 deletion py/emitbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ struct _emit_t {
};

emit_t *emit_bc_new(mp_emit_common_t *emit_common) {
emit_t *emit = m_new0(emit_t, 1);
emit_t *emit = m_new_struct_with_collect(emit_t, 1);
emit->emit_common = emit_common;
return emit;
}
Expand Down
3 changes: 2 additions & 1 deletion py/emitglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ mp_uint_t mp_verbose_flag = 0;
#endif

mp_raw_code_t *mp_emit_glue_new_raw_code(void) {
mp_raw_code_t *rc = m_new0(mp_raw_code_t, 1);
// CIRCUITPY-CHANGE: Use m_malloc_helper with collect flag because raw code children are allocations too.
mp_raw_code_t *rc = m_malloc_helper(sizeof(mp_raw_code_t), M_MALLOC_ENSURE_ZEROED | M_MALLOC_RAISE_ERROR | M_MALLOC_COLLECT);
rc->kind = MP_CODE_RESERVED;
#if MICROPY_PY_SYS_SETTRACE
rc->line_of_definition = 0;
Expand Down
Loading
Loading