|
6 | 6 | * The MIT License (MIT)
|
7 | 7 | *
|
8 | 8 | * Copyright (c) 2014 Damien P. George
|
| 9 | + * Copyright (c) 2017 Pycom Limited |
9 | 10 | *
|
10 | 11 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
11 | 12 | * of this software and associated documentation files (the "Software"), to deal
|
|
28 | 29 |
|
29 | 30 | #include <stdio.h>
|
30 | 31 |
|
| 32 | +#include "py/mpconfig.h" |
| 33 | +#include "py/mpstate.h" |
31 | 34 | #include "py/gc.h"
|
| 35 | +#include "py/mpthread.h" |
32 | 36 | #include "gccollect.h"
|
| 37 | +#include "soc/cpu.h" |
| 38 | +#include "xtensa/hal.h" |
33 | 39 |
|
34 |
| -// As we do not have control over the application entry point, there is no way |
35 |
| -// to figure out the real stack base on runtime, so it needs to be hardcoded |
36 |
| -#define STACK_END 0x40000000 |
37 | 40 |
|
38 |
| -mp_uint_t gc_helper_get_regs_and_sp(mp_uint_t *regs) { |
39 |
| - // TODO properly |
40 |
| - return (mp_uint_t)regs; |
| 41 | +static void gc_collect_inner(int level) { |
| 42 | + if (level < XCHAL_NUM_AREGS / 8) { |
| 43 | + gc_collect_inner(level + 1); |
| 44 | + if (level != 0) { |
| 45 | + return; |
| 46 | + } |
| 47 | + } |
| 48 | + |
| 49 | + if (level == XCHAL_NUM_AREGS / 8) { |
| 50 | + // get the sp |
| 51 | + volatile uint32_t sp = (uint32_t)get_sp(); |
| 52 | + gc_collect_root((void**)sp, ((mp_uint_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t)); |
| 53 | + return; |
| 54 | + } |
| 55 | + |
| 56 | + // trace root pointers from any threads |
| 57 | + #if MICROPY_PY_THREAD |
| 58 | + mp_thread_gc_others(); |
| 59 | + #endif |
41 | 60 | }
|
42 | 61 |
|
43 | 62 | void gc_collect(void) {
|
44 |
| - // start the GC |
45 | 63 | gc_collect_start();
|
46 |
| - |
47 |
| - // get the registers and the sp |
48 |
| - mp_uint_t regs[8]; |
49 |
| - mp_uint_t sp = gc_helper_get_regs_and_sp(regs); |
50 |
| - |
51 |
| - // trace the stack, including the registers (since they live on the stack in this function) |
52 |
| - gc_collect_root((void**)sp, (STACK_END - sp) / sizeof(uint32_t)); |
53 |
| - |
54 |
| - // end the GC |
| 64 | + gc_collect_inner(0); |
55 | 65 | gc_collect_end();
|
56 | 66 | }
|
0 commit comments