Skip to content

minicpgc mallocとfree

2023年9月24日

ソースコードはここ

今日はmallocとfreeに当たる処理を書いた。

mini_cpgc_malloc

void *mini_cpgc_malloc(size_t req_size) {
  Object_Header *p;

  req_size = ALIGN(req_size, PTRSIZE);
  if (req_size <= 0) {
    return NULL;
  }

  p = (Object_Header *)from_start->current;
  p->size = req_size;
  from_start->current = from_start->current + req_size;

  return (void *)(p + 1);
}

mallocするにあたってヒープ領域上で使用されている部分とそうでない部分の境界を表すcurrentメンバを追加した。 なので動作としてはヒープの先頭から順番にアロケートしていく感じだ。ブロックに関してもALIGNしている。

mini_cpgc_free

void mini_cpgc_free(void *ptr) {
  Object_Header *target, *hit;

  target = (Object_Header *)ptr - 1;

  if (free_list == NULL) {
    free_list = target;
    target->next_free = target;

    return;
  }

  /* search join point of target to free_list */
  for (hit = free_list; !(target > hit && target < hit->next_free);
       hit = hit->next_free)
    /* heap end? And hit(search)? */
    if (hit >= hit->next_free && (target > hit || target < hit->next_free))
      break;

  if (NEXT_HEADER(target) == hit->next_free) {
    /* merge */
    target->size += (hit->next_free->size + OBJECT_HEADER_SIZE);
    target->next_free = hit->next_free->next_free;
  } else {
    /* join next free block */
    target->next_free = hit->next_free;
  }
  if (NEXT_HEADER(hit) == target) {
    /* merge */
    hit->size += (target->size + OBJECT_HEADER_SIZE);
    hit->next_free = target->next_free;
  } else {
    /* join before free block */
    hit->next_free = target;
  }
  free_list = hit;
}

本家のminigcとほとんど同じである。 free_listに連結されたブロックは解放されたものとみなすやり方だ。 ただ今の所のコードだとfree_listを初期化する部分がなかったのでfree_list == NULLだった場合はtargetをそのまま入れる処理を追加している。

まだまだ全然機能が足りてないような気がするが練習なのでとりあえず動くことが大事。 この記事を書いてる時に気づいたけど、ObjectとBlockが混同しているな。Blockに揃えるべき。 せっかくfree_listを作っているのでmalloc時に活用できるようにしたい。

最低限の機能で進んでとりあえずGC部分まで辿り着きたい。