Merge pull request #2317 from babygrimes/frozen-mpy-bytes-gc_long_lived-crash

Only make objects long lived if they are on the GC heap
This commit is contained in:
Scott Shawcroft 2019-11-24 23:12:56 -08:00 committed by GitHub
commit 6e3b363f50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 10 deletions

10
py/gc.c
View File

@ -53,9 +53,6 @@
// detect untraced object still in use
#define CLEAR_ON_SWEEP (0)
#define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / BYTES_PER_WORD)
#define BYTES_PER_BLOCK (MICROPY_BYTES_PER_GC_BLOCK)
// ATB = allocation table byte
// 0b00 = FREE -- free block
// 0b01 = HEAD -- head of a chain of blocks
@ -209,13 +206,6 @@ bool gc_is_locked(void) {
return MP_STATE_MEM(gc_lock_depth) != 0;
}
// ptr should be of type void*
#define VERIFY_PTR(ptr) ( \
((uintptr_t)(ptr) & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \
&& ptr >= (void*)MP_STATE_MEM(gc_pool_start) /* must be above start of pool */ \
&& ptr < (void*)MP_STATE_MEM(gc_pool_end) /* must be below end of pool */ \
)
#ifndef TRACE_MARK
#if DEBUG_PRINT
#define TRACE_MARK(block, ptr) DEBUG_printf("gc_mark(%p)\n", ptr)

11
py/gc.h
View File

@ -29,8 +29,19 @@
#include <stdint.h>
#include "py/mpconfig.h"
#include "py/mpstate.h"
#include "py/misc.h"
#define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / BYTES_PER_WORD)
#define BYTES_PER_BLOCK (MICROPY_BYTES_PER_GC_BLOCK)
// ptr should be of type void*
#define VERIFY_PTR(ptr) ( \
((uintptr_t)(ptr) & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \
&& ptr >= (void*)MP_STATE_MEM(gc_pool_start) /* must be above start of pool */ \
&& ptr < (void*)MP_STATE_MEM(gc_pool_end) /* must be below end of pool */ \
)
void gc_init(void *start, void *end);
void gc_deinit(void);

View File

@ -126,6 +126,11 @@ mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth){
if (obj == NULL) {
return obj;
}
// If not in the GC pool, do nothing. This can happen (at least) when
// there are frozen mp_type_bytes objects in ROM.
if (!VERIFY_PTR((void *)obj)) {
return obj;
}
if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_bc)) {
mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(obj);
return MP_OBJ_FROM_PTR(make_fun_bc_long_lived(fun_bc, max_depth));