Skip to content

Some flash size optimizations related to string0.c (implementation of str/mem functions) #6397

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

Merged
merged 4 commits into from
Oct 13, 2022
Merged
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
17 changes: 7 additions & 10 deletions py/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ void gc_init(void *start, void *end) {
MP_STATE_MEM(gc_alloc_table_start) = (byte *)start;

#if MICROPY_ENABLE_FINALISER
size_t gc_finaliser_table_byte_len = (MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB;
MP_STATE_MEM(gc_finaliser_table_start) = MP_STATE_MEM(gc_alloc_table_start) + MP_STATE_MEM(gc_alloc_table_byte_len) + 1;
#endif

Expand All @@ -147,18 +146,16 @@ void gc_init(void *start, void *end) {
MP_STATE_MEM(gc_pool_end) = end;

#if MICROPY_ENABLE_FINALISER
size_t gc_finaliser_table_byte_len = (MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB;
(void)gc_finaliser_table_byte_len; // avoid unused variable diagnostic if asserts are disabled
assert(MP_STATE_MEM(gc_pool_start) >= MP_STATE_MEM(gc_finaliser_table_start) + gc_finaliser_table_byte_len);
#endif

// Clear ATBs plus one more byte. The extra byte might be read when we read the final ATB and
// then try to count its tail. Clearing the byte ensures it is 0 and ends the chain. Without an
// FTB, it'll just clear the pool byte early.
memset(MP_STATE_MEM(gc_alloc_table_start), 0, MP_STATE_MEM(gc_alloc_table_byte_len) + 1);

#if MICROPY_ENABLE_FINALISER
// clear FTBs
memset(MP_STATE_MEM(gc_finaliser_table_start), 0, gc_finaliser_table_byte_len);
#endif
// Clear ATBs & finalisers (if enabled). This also clears the extra byte
// which appears between ATBs and finalisers that ensures every chain in
// the ATB terminates, rather than erroneously using bits from the
// finalisers.
memset(MP_STATE_MEM(gc_alloc_table_start), 0, MP_STATE_MEM(gc_pool_start) - MP_STATE_MEM(gc_alloc_table_start));

// Set first free ATB index to the start of the heap.
for (size_t i = 0; i < MICROPY_ATB_INDICES; i++) {
Expand Down
12 changes: 10 additions & 2 deletions shared/libc/string0.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@
#include <stddef.h>
#include <string.h>

#include "py/mpconfig.h"

#ifndef likely
#define likely(x) __builtin_expect((x), 1)
#endif

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-align"
void *memcpy(void *dst, const void *src, size_t n) {
#if CIRCUITPY_FULL_BUILD
if (likely(!(((uintptr_t)dst) & 3) && !(((uintptr_t)src) & 3))) {
// pointers aligned
uint32_t *d = dst;
Expand All @@ -56,7 +59,9 @@ void *memcpy(void *dst, const void *src, size_t n) {
// copy byte
*((uint8_t*)d) = *((const uint8_t*)s);
}
} else {
} else
#endif
{
// unaligned access, copy bytes
uint8_t *d = dst;
const uint8_t *s = src;
Expand Down Expand Up @@ -93,6 +98,7 @@ void *memmove(void *dest, const void *src, size_t n) {
}

void *memset(void *s, int c, size_t n) {
#if CIRCUITPY_FULL_BUILD
if (c == 0 && ((uintptr_t)s & 3) == 0) {
// aligned store of 0
uint32_t *s32 = s;
Expand All @@ -106,7 +112,9 @@ void *memset(void *s, int c, size_t n) {
if (n & 1) {
*((uint8_t*)s32) = 0;
}
} else {
} else
#endif
{
uint8_t *s2 = s;
for (; n > 0; n--) {
*s2++ = c;
Expand Down