Skip to content

Commit cb34939

Browse files
authored
Merge pull request #140 from DrXiao/fix-build
Speed up malloc/free routines
2 parents 7e49741 + 05945e4 commit cb34939

File tree

4 files changed

+38
-24
lines changed

4 files changed

+38
-24
lines changed

lib/c.c

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -529,13 +529,27 @@ int fputc(int c, FILE *stream)
529529
/* Non-portable: Assume page size is 4KiB */
530530
#define PAGESIZE 4096
531531

532+
#define CHUNK_SIZE_FREED_MASK 1
533+
#define CHUNK_SIZE_SZ_MASK 0xFFFFFFFE
534+
#define CHUNK_GET_SIZE(size) (size & CHUNK_SIZE_SZ_MASK)
535+
#define IS_CHUNK_GET_FREED(size) (size & CHUNK_SIZE_FREED_MASK)
536+
532537
typedef struct chunk {
533538
struct chunk *next;
534539
struct chunk *prev;
535540
int size;
536-
void *ptr;
537541
} chunk_t;
538542

543+
void chunk_set_freed(chunk_t *chunk)
544+
{
545+
chunk->size |= CHUNK_SIZE_FREED_MASK;
546+
}
547+
548+
void chunk_clear_freed(chunk_t *chunk)
549+
{
550+
chunk->size &= CHUNK_SIZE_SZ_MASK;
551+
}
552+
539553
int __align_up(int size)
540554
{
541555
int mask = PAGESIZE - 1;
@@ -562,7 +576,6 @@ void *malloc(int size)
562576
__alloc_tail = tmp;
563577
__alloc_head->next = NULL;
564578
__alloc_head->prev = NULL;
565-
__alloc_head->ptr = NULL;
566579
__alloc_head->size = 0;
567580
}
568581

@@ -573,7 +586,6 @@ void *malloc(int size)
573586
__freelist_head = tmp;
574587
__freelist_head->next = NULL;
575588
__freelist_head->prev = NULL;
576-
__freelist_head->ptr = NULL;
577589
__freelist_head->size = -1;
578590
}
579591

@@ -591,15 +603,16 @@ void *malloc(int size)
591603
int bsize = 0;
592604

593605
for (chunk_t *fh = __freelist_head; fh->next; fh = fh->next) {
594-
if (fh->size >= size && !best_fit_chunk) {
606+
int fh_size = CHUNK_GET_SIZE(fh->size);
607+
if (fh_size >= size && !best_fit_chunk) {
595608
/* first time setting fh as best_fit_chunk */
596609
best_fit_chunk = fh;
597-
bsize = fh->size;
598-
} else if ((fh->size >= size) && best_fit_chunk &&
599-
(fh->size < bsize)) {
610+
bsize = fh_size;
611+
} else if ((fh_size >= size) && best_fit_chunk &&
612+
(fh_size < bsize)) {
600613
/* If there is a smaller chunk available, replace it. */
601614
best_fit_chunk = fh;
602-
bsize = fh->size;
615+
bsize = fh_size;
603616
}
604617
}
605618

@@ -633,9 +646,9 @@ void *malloc(int size)
633646
__alloc_tail = allocated;
634647
__alloc_tail->next = NULL;
635648
__alloc_tail->size = allocated->size;
636-
int offset = sizeof(chunk_t) - 4;
637-
__alloc_tail->ptr = __alloc_tail + offset;
638-
return __alloc_tail->ptr;
649+
chunk_clear_freed(__alloc_tail);
650+
void *ptr = __alloc_tail + 1;
651+
return ptr;
639652
}
640653

641654
void *calloc(int n, int size)
@@ -660,14 +673,16 @@ int __free_all()
660673

661674
chunk_t *cur = __freelist_head;
662675
chunk_t *rel;
676+
int size;
663677

664678
/* release freelist */
665679
while (cur->next) {
666680
rel = cur;
667681
cur = cur->next;
668682
rel->next = NULL;
669683
rel->prev = NULL;
670-
__rfree(rel, rel->size);
684+
size = CHUNK_GET_SIZE(rel->size);
685+
__rfree(rel, size);
671686
}
672687

673688
if (__alloc_head->next) {
@@ -678,7 +693,8 @@ int __free_all()
678693
cur = cur->next;
679694
rel->next = NULL;
680695
rel->prev = NULL;
681-
__rfree(rel, rel->size);
696+
size = CHUNK_GET_SIZE(rel->size);
697+
__rfree(rel, size);
682698
}
683699
}
684700
return 0;
@@ -689,14 +705,11 @@ void free(void *ptr)
689705
if (!ptr)
690706
return;
691707

692-
/* FIXME: it takes long time to search in chuncks */
693-
chunk_t *cur = __alloc_head;
694-
while (cur->ptr != ptr) {
695-
cur = cur->next;
696-
if (!cur) {
697-
printf("free(): double free detected\n");
698-
abort();
699-
}
708+
char *__ptr = ptr;
709+
chunk_t *cur = __ptr - sizeof(chunk_t);
710+
if (IS_CHUNK_GET_FREED(cur->size)) {
711+
printf("free(): double free detected\n");
712+
abort();
700713
}
701714

702715
chunk_t *prev;
@@ -717,6 +730,7 @@ void free(void *ptr)
717730
/* Insert head in __freelist_head */
718731
cur->next = __freelist_head;
719732
cur->prev = NULL;
733+
chunk_set_freed(cur);
720734
__freelist_head->prev = cur;
721735
__freelist_head = cur;
722736
}

src/defs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#define MAX_VAR_LEN 32
1515
#define MAX_TYPE_LEN 32
1616
#define MAX_PARAMS 8
17-
#define MAX_LOCALS 1450
17+
#define MAX_LOCALS 1500
1818
#define MAX_FIELDS 32
1919
#define MAX_FUNCS 512
2020
#define MAX_FUNC_TRIES 2160

tests/snapshots/fib.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

tests/snapshots/hello.json

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)