// File: /workspace/github_c_makefile_star2_O0/masyagin1998[P]GCI/src/garbage-collector/garbage-collector.c
// Function: run_gc_inner
static void run_gc_inner(garbage_collector_type_t gc, void**ptr)
{
    struct VALUE*stack = (*(gc->stack));
    struct VALUE*stack_top = (*(gc->stack_top));
    
    struct VALUE*val;
    void*unscanned_ptr;

    allocator_clean_pool(&(gc->b));

    /* Cheneys GC from Aho-Ullman. */

    /* 2) for (All o in FROM) NewLocation(o) = NULL; */
    ptrs_map_conf(&(gc->ptrs_map), gc->a.busy_list.count);

    /* 3) unscanned = free = start TO address. */
    /* Nothing to do */

    /* 4-5) for (every link R in root subset) R = LookupNewLocation(r) */
    for (val = stack; val != stack_top; val++) {
        if (val->type == VALUE_TYPE_OBJ) {
            val->obj_val = lookup_new_location(gc, val->obj_val);
        } else if (val->type == VALUE_TYPE_ARR) {
            val->arr_val = lookup_new_location(gc, val->arr_val);
        }
    }

    /* 6-7-8-9-10) */
    unscanned_ptr = gc->b.busy_list.first;
    while (unscanned_ptr != NULL) {
        char*ptr = BLOCK_DATA(unscanned_ptr);
        if (ptr[0] == VALUE_TYPE_OBJ) {
            size_t i;
            struct OBJECT*obj = (struct OBJECT*) (ptr + 1);
            for (i = 0; i < obj->properties_len; i++) {
                if (obj->properties[i].val.type == VALUE_TYPE_OBJ) {
                    obj->properties[i].val.obj_val = lookup_new_location(gc, obj->properties[i].val.obj_val);
                } else if (obj->properties[i].val.type == VALUE_TYPE_ARR) {
                    obj->properties[i].val.arr_val = lookup_new_location(gc, obj->properties[i].val.arr_val);
                }
            }
        } else if (ptr[0] == VALUE_TYPE_ARR) {
            size_t i;
            struct ARRAY*arr = (struct ARRAY*) (ptr + 1);
            for (i = 0; i < arr->len; i++) {
                if (arr->values[i].type == VALUE_TYPE_OBJ) {
                    arr->values[i].obj_val = lookup_new_location(gc, arr->values[i].obj_val);
                } else if (arr->values[i].type == VALUE_TYPE_ARR) {
                    arr->values[i].arr_val = lookup_new_location(gc, arr->values[i].arr_val);
                }
            }
        }
        unscanned_ptr = BLOCK_LIST_NEXT(unscanned_ptr);
    }

    if (ptr != NULL) {
        (*ptr) = lookup_new_location(gc, *ptr);
    }

    ptrs_map_free(&(gc->ptrs_map));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
addq $0x60, %rdi
callq 0x16d90
movq -0x8(%rbp), %rdi
addq $0xb0, %rdi
movq -0x8(%rbp), %rax
movq 0x50(%rax), %rsi
callq 0x16a20
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x20(%rbp), %rax
je 0x164d4
movq -0x28(%rbp), %rax
cmpl $0x2, 0x10(%rax)
jne 0x1649c
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x16730
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x164c4
movq -0x28(%rbp), %rax
cmpl $0x3, 0x10(%rax)
jne 0x164c2
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x16730
movq %rax, %rcx
movq -0x28(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x164c4
jmp 0x164c6
movq -0x28(%rbp), %rax
addq $0x18, %rax
movq %rax, -0x28(%rbp)
jmp 0x1646a
movq -0x8(%rbp), %rax
movq 0x90(%rax), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x166f2
movq -0x30(%rbp), %rax
addq $0x1, %rax
addq $0x8, %rax
addq $0x8, %rax
addq $0x8, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x2, %eax
jne 0x165fd
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq -0x48(%rbp), %rcx
cmpq (%rcx), %rax
jae 0x165f8
movq -0x48(%rbp), %rax
addq $0x10, %rax
movq -0x40(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
cmpl $0x2, 0x18(%rax)
jne 0x16590
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rax
addq $0x10, %rax
movq -0x40(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rsi
callq 0x16730
movq %rax, %rcx
movq -0x48(%rbp), %rax
addq $0x10, %rax
movq -0x40(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
jmp 0x165e5
movq -0x48(%rbp), %rax
addq $0x10, %rax
movq -0x40(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
cmpl $0x3, 0x18(%rax)
jne 0x165e3
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rax
addq $0x10, %rax
movq -0x40(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rsi
callq 0x16730
movq %rax, %rcx
movq -0x48(%rbp), %rax
addq $0x10, %rax
movq -0x40(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
jmp 0x165e5
jmp 0x165e7
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x1652a
jmp 0x166e1
movq -0x38(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x3, %eax
jne 0x166df
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
movq -0x58(%rbp), %rcx
cmpq (%rcx), %rax
jae 0x166dd
movq -0x58(%rbp), %rax
addq $0x10, %rax
imulq $0x18, -0x50(%rbp), %rcx
addq %rcx, %rax
cmpl $0x2, 0x10(%rax)
jne 0x1667e
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rax
addq $0x10, %rax
imulq $0x18, -0x50(%rbp), %rcx
addq %rcx, %rax
movq 0x8(%rax), %rsi
callq 0x16730
movq %rax, %rcx
movq -0x58(%rbp), %rax
addq $0x10, %rax
imulq $0x18, -0x50(%rbp), %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
jmp 0x166ca
movq -0x58(%rbp), %rax
addq $0x10, %rax
imulq $0x18, -0x50(%rbp), %rcx
addq %rcx, %rax
cmpl $0x3, 0x10(%rax)
jne 0x166c8
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rax
addq $0x10, %rax
imulq $0x18, -0x50(%rbp), %rcx
addq %rcx, %rax
movq 0x8(%rax), %rsi
callq 0x16730
movq %rax, %rcx
movq -0x58(%rbp), %rax
addq $0x10, %rax
imulq $0x18, -0x50(%rbp), %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
jmp 0x166ca
jmp 0x166cc
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x16621
jmp 0x166df
jmp 0x166e1
movq -0x30(%rbp), %rax
movq 0x11(%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x164e3
cmpq $0x0, -0x10(%rbp)
je 0x16713
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rsi
callq 0x16730
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x8(%rbp), %rdi
addq $0xb0, %rdi
callq 0x16c50
addq $0x60, %rsp
popq %rbp
retq
nopl (%rax)