mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
[python] Fix gc_collect to be sure to get unaligned pointers
This commit is contained in:
@@ -8,7 +8,12 @@ static Turtle sTurtle;
|
||||
|
||||
void modturtle_gc_collect() {
|
||||
// Mark the shared sTurtle object as a GC root
|
||||
gc_collect_root((void **)&sTurtle, sizeof(Turtle)/sizeof(void *));
|
||||
for (size_t i = 0; i < sizeof(void *); i++) {
|
||||
// See comment in port.cpp: gc_collect implementation
|
||||
char * turtleWithOffset = (char *)&sTurtle + i;
|
||||
size_t turtleLengthInAddressSize = (sizeof(Turtle) - i + sizeof(void *) - 1)/sizeof(void *);
|
||||
gc_collect_root((void **)turtleWithOffset, turtleLengthInAddressSize);
|
||||
}
|
||||
}
|
||||
|
||||
void modturtle_view_did_disappear() {
|
||||
|
||||
@@ -156,7 +156,7 @@ void gc_collect(void) {
|
||||
/* To compute the stack length:
|
||||
* regs
|
||||
* <----------->
|
||||
* STACK -> ...| | | | | |--|--|--|--| | | | | | |
|
||||
* STACK <- ...| | | | | |--|--|--|--| | | | | | |
|
||||
* ^®s ^python_stack_top
|
||||
* */
|
||||
|
||||
@@ -178,7 +178,22 @@ void gc_collect(void) {
|
||||
}
|
||||
/* Memory error detectors might find an error here as they might split regs
|
||||
* and stack memory zones. */
|
||||
gc_collect_root(scanStart, stackLengthInByte/sizeof(void *));
|
||||
for (size_t i = 0; i < sizeof(void *); i++) {
|
||||
/* Objects on the stack are not necessarily aligned on sizeof(void *),
|
||||
* which is also true for pointers refering to the heap. MicroPython
|
||||
* gc_collect_root expects a table of void * that will be scanned every
|
||||
* sizeof(void *) step. So we have to scan the stack repetitively with a
|
||||
* increasing offset to be sure to check every byte for a heap address.
|
||||
* If some memory can be reinterpreted as a pointer in the heap, gc_collect_root
|
||||
* will prevent the destruction of the pointed heap memory. At worst (if
|
||||
* the interpreted pointer was in fact an unaligned object or uninitialized
|
||||
* memory), we will just keep extra objects in the heap which is not optimal
|
||||
* but does not cause any crash. */
|
||||
char * scanStartWithOffset = (char *)scanStart + i;
|
||||
// Ensure to round the length to the ceiling
|
||||
size_t stackLengthInAddressSize = (stackLengthInByte - i + sizeof(void *) - 1)/sizeof(void *);
|
||||
gc_collect_root((void **)scanStartWithOffset, stackLengthInAddressSize);
|
||||
}
|
||||
|
||||
gc_collect_end();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user