// File: /workspace/github_c_makefile_star2_O0/pedro-onate[P]eva/eva.c
// Function: es_gc
void es_gc(es_ctx_t* ctx)
{
/* TODO: Ensure scan and next pointers respect alignment */
  //printf("running gc\n");
  //struct timeval t0, t1, dt;
  char* scan, *next, *tmp;

  //gettimeofday(&t0, NULL);

  es_heap_t* heap = &ctx->heap;
  scan = next = heap->to_space;

  es_mark_copy(heap, &ctx->env, &next);
  es_mark_copy(heap, &ctx->iport, &next);
  es_mark_copy(heap, &ctx->oport, &next);
  es_mark_copy(heap, &ctx->bytecode, &next);

  for(int i = 0; i < ctx->roots.top; i++) {
    es_mark_copy(heap, ctx->roots.stack[i], &next);
  }

  es_mark_copy(heap, &ctx->env, &next);
  for(int i = 0; i < ctx->sp - ctx->stack; i++) {
    es_mark_copy(heap, &ctx->stack[i], &next);
  }
  for(int i = 1; i < ctx->fp; i++) {
    es_mark_copy(heap, &ctx->frames[i].args, &next);
  }

  while(scan < next) {
    es_val_t obj = es_obj_to_val(scan);
    switch(es_type_of(obj)) {
    case ES_PAIR_TYPE:      es_pair_mark_copy(heap, obj, &next);     break;
    case ES_CLOSURE_TYPE:   es_closure_mark_copy(heap, obj, &next);  break;
    case ES_VECTOR_TYPE:    es_vector_mark_copy(heap, obj, &next);   break;
    case ES_ENV_TYPE:       es_env_mark_copy(heap, obj, &next);      break;
    case ES_ARGS_TYPE:      es_args_mark_copy(heap, obj, &next);     break;
    case ES_BYTECODE_TYPE:  es_bytecode_mark_copy(heap, obj, &next); break;
    case ES_MACRO_TYPE:     es_macro_mark_copy(heap, obj, &next);    break;
    default:                                                         break;
    }
    scan = alignp(scan + es_size_of(obj), ES_DEFAULT_ALIGNMENT);
  }

  tmp              = heap->from_space;
  heap->from_space = heap->to_space;
  heap->end        = heap->from_space + heap->size;
  heap->to_space   = tmp;
  heap->to_end     = heap->to_space + heap->size;
  heap->next       = next;

  //gettimeofday(&t1, NULL);
  //timeval_subtract(&dt, &t1, &t0);
  //printf("gc time: %f\n", dt.tv_sec * 1000.0 + dt.tv_usec / 1000.0);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x18(%rbp)
movq %rax, -0x10(%rbp)
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x42080, %rsi          # imm = 0x42080
leaq -0x18(%rbp), %rdx
callq 0x4040
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x42050, %rsi          # imm = 0x42050
leaq -0x18(%rbp), %rdx
callq 0x4040
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x42058, %rsi          # imm = 0x42058
leaq -0x18(%rbp), %rdx
callq 0x4040
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x42060, %rsi          # imm = 0x42060
leaq -0x18(%rbp), %rdx
callq 0x4040
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0x2040(%rcx), %eax
jge 0x3e1f
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movq 0x40(%rax,%rcx,8), %rsi
leaq -0x18(%rbp), %rdx
callq 0x4040
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x3deb
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x42080, %rsi          # imm = 0x42080
leaq -0x18(%rbp), %rdx
callq 0x4040
movl $0x0, -0x30(%rbp)
movslq -0x30(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x42070(%rcx), %rcx
movq -0x8(%rbp), %rdx
addq $0x42090, %rdx          # imm = 0x42090
subq %rdx, %rcx
sarq $0x3, %rcx
cmpq %rcx, %rax
jge 0x3e92
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x42090, %rsi          # imm = 0x42090
movslq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
leaq -0x18(%rbp), %rdx
callq 0x4040
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x3e3e
movl $0x1, -0x34(%rbp)
movl -0x34(%rbp), %eax
movq -0x8(%rbp), %rcx
cmpl 0x42078(%rcx), %eax
jge 0x3ed6
movq -0x28(%rbp), %rdi
movq -0x8(%rbp), %rsi
addq $0x4a090, %rsi          # imm = 0x4A090
movslq -0x34(%rbp), %rax
shlq $0x4, %rax
addq %rax, %rsi
leaq -0x18(%rbp), %rdx
callq 0x4040
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x3e99
jmp 0x3ed8
movq -0x10(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x3fd4
movq -0x10(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0x1560
addl $-0x6, %eax
movl %eax, %ecx
movq %rcx, -0x48(%rbp)
subl $0xe, %eax
ja 0x3fa2
movq -0x48(%rbp), %rax
leaq 0x6208(%rip), %rcx      # 0xa11c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x4150
jmp 0x3fa4
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x41b0
jmp 0x3fa4
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x4210
jmp 0x3fa4
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x4280
jmp 0x3fa4
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x42f0
jmp 0x3fa4
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x4370
jmp 0x3fa4
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
leaq -0x18(%rbp), %rdx
callq 0x43e0
jmp 0x3fa4
jmp 0x3fa4
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rdi
callq 0x3b80
movq %rax, %rcx
movq -0x50(%rbp), %rax
addq %rcx, %rax
addq $0x10, %rax
subq $0x1, %rax
andq $-0x10, %rax
movq %rax, -0x10(%rbp)
jmp 0x3ed8
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x28(%rbp), %rax
movq 0x20(%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x28(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x28(%rbp), %rax
addq 0x8(%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rax
movq 0x20(%rax), %rcx
movq -0x28(%rbp), %rax
addq 0x8(%rax), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x18(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
addq $0x50, %rsp
popq %rbp
retq
nop