// File: /workspace/github_c_makefile_star2_O0/mflatt[P]gc-demo/gengc/gengc.c
// Function: collect_garbage
void collect_garbage()
{
  if (!chunks) return;
  
  /* minor collection: */
  mark_and_sweep_from_roots();

  /* The minor collection above 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. */
  
  /* move non-empty chunks to old generation: */
  if (chunks) {
    struct gc_chunk *prev_c = NULL, *next;

    for (struct gc_chunk *c = chunks; c; c = next) {
      next = c->next;
      if (c->num_marked_nodes == 0) {
        /* This chunk is empty, so free it */
        raw_free(c->mem, NODES_PER_CHUNK * sizeof(struct gc_node));
        raw_free(c, sizeof(struct gc_chunk));
        if (!prev_c)
          chunks = next;
      } else {
        /* Keep this chunk, now as an old-generation chunk */
        num_gen1_chunks++;
        if (prev_c)
          prev_c->next = c;
        prev_c = c;
      }
    }

    if (prev_c) {
      prev_c->next = gen1_chunks;
      gen1_chunks = chunks;
    }

    chunks = NULL;
    free_list = NULL;
  }

  if (num_gen1_chunks >= (last_major_gen1_chunks * 2)) {
    /* perform major collection by moving all old-generation
       chunks back to the "new" generation, and GC again */
    // printf("Major GC\n");
    last_major_gen1_chunks = num_gen1_chunks;
    chunks = gen1_chunks;
    gen1_chunks = NULL;
    num_gen1_chunks = 0;
    collect_garbage();
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
leaq 0x2b51(%rip), %rax      # 0x4080
cmpq $0x0, (%rax)
jne 0x153a
jmp 0x1682
movb $0x0, %al
callq 0x16f0
leaq 0x2b38(%rip), %rax      # 0x4080
cmpq $0x0, (%rax)
je 0x1639
movq $0x0, -0x8(%rbp)
leaq 0x2b1f(%rip), %rax      # 0x4080
movq (%rax), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x15f7
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x10(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x0, 0x10(%rax)
jne 0x15bf
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rdi
movl $0xc0000, %esi          # imm = 0xC0000
callq 0x14e0
movq -0x18(%rbp), %rdi
movl $0x18, %esi
callq 0x14e0
cmpq $0x0, -0x8(%rbp)
jne 0x15bd
movq -0x10(%rbp), %rcx
leaq 0x2ac6(%rip), %rax      # 0x4080
movq %rcx, (%rax)
jmp 0x15e8
movl 0x2a93(%rip), %eax      # 0x4058
addl $0x1, %eax
movl %eax, 0x2a8a(%rip)      # 0x4058
cmpq $0x0, -0x8(%rbp)
je 0x15e0
movq -0x18(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x15ea
movq -0x10(%rbp), %rax
movq %rax, -0x18(%rbp)
jmp 0x1568
cmpq $0x0, -0x8(%rbp)
je 0x161d
movq 0x2a5b(%rip), %rcx      # 0x4060
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
leaq 0x2a6d(%rip), %rax      # 0x4080
movq (%rax), %rax
movq %rax, 0x2a43(%rip)      # 0x4060
leaq 0x2a5c(%rip), %rax      # 0x4080
movq $0x0, (%rax)
leaq 0x2a3e(%rip), %rax      # 0x4070
movq $0x0, (%rax)
movl 0x2a19(%rip), %eax      # 0x4058
movl 0x2a23(%rip), %ecx      # 0x4068
shll %ecx
cmpl %ecx, %eax
jl 0x1682
movl 0x2a07(%rip), %eax      # 0x4058
movl %eax, 0x2a11(%rip)      # 0x4068
movq 0x2a02(%rip), %rcx      # 0x4060
leaq 0x2a1b(%rip), %rax      # 0x4080
movq %rcx, (%rax)
movq $0x0, 0x29ed(%rip) # 0x4060
movl $0x0, 0x29db(%rip)      # 0x4058
callq 0x1520
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax,%rax)