// File: /workspace/github_c_makefile_star2_O0/mflatt[P]gc-demo/gen2space/gen2space.c
// Function: collect_garbage
void collect_garbage()
{
  size_t need_size = space_end - space_start;
  if (need_size < (gen1_space_end - gen1_space_next)) {
    /* Minor collection, since we have room in the gen1 space */
    struct gc_node *alloc_pos;
    alloc_pos = (struct gc_node *)gen1_space_next;

    /* A minor collection (still) relies on having no references from
       old object to new objects; this is not a general-purpose GC. If
       such references were allowed, we'd have to add them as
       roots. */

    is_major = 0;
    copy_from_roots(&alloc_pos);

    /* Record updated allocation pointer */
    gen1_space_next = (uintptr_t)alloc_pos;
  } else {
    /* Major collection; make a space big enough for both the old and
       new generation: */
    size_t new_size = need_size + (gen1_space_next - gen1_space_start);
    if (new_size < (gen1_prev_size * 2))
      new_size = gen1_prev_size * 2;

    struct gc_node *alloc_pos;
    void *new_space = raw_malloc(new_size);
    alloc_pos = (struct gc_node *)new_space;
    
    is_major = 1;
    copy_from_roots(&alloc_pos);

    /* Clean up old space */
    if (gen1_space_start != 0)
      raw_free((void *)gen1_space_start, gen1_space_end - gen1_space_start);

    /* Continue allocating into new old-generation space */
    gen1_space_start = (uintptr_t)new_space;
    gen1_space_end = gen1_space_start + new_size;
    gen1_space_next = (uintptr_t)alloc_pos;

    gen1_prev_size = gen1_space_next - gen1_space_start;
  }

  /* Create a fresh new-generation space: */
  void *new_space = raw_malloc(GEN0_SIZE);

  /* Clean up old new-generation space */
  if (space_start != 0)
    raw_free((void *)space_start, GEN0_SIZE);

  /* Continue allocating into new space */
  space_start = (uintptr_t)new_space;
  space_end = space_start + GEN0_SIZE;
  space_next = space_start;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
leaq 0x2b69(%rip), %rax      # 0x4098
movq (%rax), %rax
leaq 0x2f77(%rip), %rcx      # 0x44b0
subq (%rcx), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq 0x2b1d(%rip), %rcx      # 0x4068
subq 0x2b1e(%rip), %rcx      # 0x4070
cmpq %rcx, %rax
jae 0x1585
movq 0x2b12(%rip), %rax      # 0x4070
movq %rax, -0x10(%rbp)
movl $0x0, 0x2b0c(%rip)      # 0x4078
leaq -0x10(%rbp), %rdi
callq 0x17a0
movq -0x10(%rbp), %rax
movq %rax, 0x2af0(%rip)      # 0x4070
jmp 0x1648
movq -0x8(%rbp), %rax
movq 0x2ae0(%rip), %rcx      # 0x4070
subq 0x2ae9(%rip), %rcx      # 0x4080
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq 0x2a97(%rip), %rcx      # 0x4040
shlq %rcx
cmpq %rcx, %rax
jae 0x15bf
movq 0x2a88(%rip), %rax      # 0x4040
shlq %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
callq 0x1490
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x1, 0x2a9a(%rip)      # 0x4078
leaq -0x20(%rbp), %rdi
callq 0x17a0
cmpq $0x0, 0x2a91(%rip)      # 0x4080
je 0x160b
movq 0x2a88(%rip), %rdi      # 0x4080
movq 0x2a69(%rip), %rsi      # 0x4068
subq 0x2a7a(%rip), %rsi      # 0x4080
callq 0x14e0
movq -0x28(%rbp), %rax
movq %rax, 0x2a6a(%rip)      # 0x4080
movq 0x2a63(%rip), %rax      # 0x4080
addq -0x18(%rbp), %rax
movq %rax, 0x2a40(%rip)      # 0x4068
movq -0x20(%rbp), %rax
movq %rax, 0x2a3d(%rip)      # 0x4070
movq 0x2a36(%rip), %rax      # 0x4070
subq 0x2a3f(%rip), %rax      # 0x4080
movq %rax, 0x29f8(%rip)      # 0x4040
movl $0x1000, %edi           # imm = 0x1000
callq 0x1490
movq %rax, -0x30(%rbp)
leaq 0x2e53(%rip), %rax      # 0x44b0
cmpq $0x0, (%rax)
je 0x1677
leaq 0x2e46(%rip), %rax      # 0x44b0
movq (%rax), %rdi
movl $0x1000, %esi           # imm = 0x1000
callq 0x14e0
movq -0x30(%rbp), %rcx
leaq 0x2e2e(%rip), %rax      # 0x44b0
movq %rcx, (%rax)
leaq 0x2e24(%rip), %rax      # 0x44b0
movq (%rax), %rcx
addq $0x1000, %rcx           # imm = 0x1000
leaq 0x29fb(%rip), %rax      # 0x4098
movq %rcx, (%rax)
leaq 0x2e09(%rip), %rax      # 0x44b0
movq (%rax), %rcx
leaq 0x29df(%rip), %rax      # 0x4090
movq %rcx, (%rax)
addq $0x30, %rsp
popq %rbp
retq
nopw (%rax,%rax)