// File: /workspace/github_c_makefile_star2_O1/janet-lang[P]janet/src/core/gc.c
// Function: janet_sweep
void janet_sweep() {
    JanetGCObject *previous = NULL;
    JanetGCObject *current = janet_vm.weak_blocks;
    JanetGCObject *next;

    /* Sweep weak heap to drop weak refs */
    while (NULL != current) {
        next = current->data.next;
        if (current->flags & (JANET_MEM_REACHABLE | JANET_MEM_DISABLED)) {
            /* Check for dead references */
            enum JanetMemoryType type = janet_gc_type(current);
            if (type == JANET_MEMORY_ARRAY_WEAK) {
                JanetArray *array = (JanetArray *) current;
                for (uint32_t i = 0; i < (uint32_t) array->count; i++) {
                    if (!janet_check_liveref(array->data[i])) {
                        array->data[i] = janet_wrap_nil();
                    }
                }
            } else {
                JanetTable *table = (JanetTable *) current;
                int check_values = (type == JANET_MEMORY_TABLE_WEAKV) || (type == JANET_MEMORY_TABLE_WEAKKV);
                int check_keys = (type == JANET_MEMORY_TABLE_WEAKK) || (type == JANET_MEMORY_TABLE_WEAKKV);
                JanetKV *end = table->data + table->capacity;
                JanetKV *kvs = table->data;
                while (kvs < end) {
                    int drop = 0;
                    if (check_keys && !janet_check_liveref(kvs->key)) drop = 1;
                    if (check_values && !janet_check_liveref(kvs->value)) drop = 1;
                    if (drop) {
                        /* Inlined from janet_table_remove without search */
                        table->count--;
                        table->deleted++;
                        kvs->key = janet_wrap_nil();
                        kvs->value = janet_wrap_false();
                    }
                    kvs++;
                }
            }
        }
        current = next;
    }

    /* Sweep weak heap to free blocks */
    previous = NULL;
    current = janet_vm.weak_blocks;
    while (NULL != current) {
        next = current->data.next;
        if (current->flags & (JANET_MEM_REACHABLE | JANET_MEM_DISABLED)) {
            previous = current;
            current->flags &= ~JANET_MEM_REACHABLE;
        } else {
            janet_vm.block_count--;
            janet_deinit_block(current);
            if (NULL != previous) {
                previous->data.next = next;
            } else {
                janet_vm.weak_blocks = next;
            }
            janet_free(current);
        }
        current = next;
    }

    /* Sweep main heap to free blocks */
    previous = NULL;
    current = janet_vm.blocks;
    while (NULL != current) {
        next = current->data.next;
        if (current->flags & (JANET_MEM_REACHABLE | JANET_MEM_DISABLED)) {
            previous = current;
            current->flags &= ~JANET_MEM_REACHABLE;
        } else {
            janet_vm.block_count--;
            janet_deinit_block(current);
            if (NULL != previous) {
                previous->data.next = next;
            } else {
                janet_vm.blocks = next;
            }
            janet_free(current);
        }
        current = next;
    }

#ifdef JANET_EV
    /* Sweep threaded abstract types for references to decrement */
    JanetKV *items = janet_vm.threaded_abstracts.data;
    for (int32_t i = 0; i < janet_vm.threaded_abstracts.capacity; i++) {
        if (janet_checktype(items[i].key, JANET_ABSTRACT)) {

            /* If item was not visited during the mark phase, then this
             * abstract type isn't present in the heap and needs its refcount
             * decremented, and shouuld be removed from table. If the refcount is
             * then 0, the item will be collected. This ensures that only one interpreter
             * will clean up the threaded abstract. */

            /* If not visited... */
            if (!janet_truthy(items[i].value)) {
                void *abst = janet_unwrap_abstract(items[i].key);
                if (0 == janet_abstract_decref(abst)) {
                    /* Run finalizer */
                    JanetAbstractHead *head = janet_abstract_head(abst);
                    if (head->type->gc) {
                        janet_assert(!head->type->gc(head->data, head->size), "finalizer failed");
                    }
                    /* Free memory */
                    janet_free(janet_abstract_head(abst));
                }

                /* Mark as tombstone in place */
                items[i].key = janet_wrap_nil();
                items[i].value = janet_wrap_false();
                janet_vm.threaded_abstracts.deleted++;
                janet_vm.threaded_abstracts.count--;
            }

            /* Reset for next sweep */
            items[i].value = janet_wrap_false();
        }
    }
#endif
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %fs:0x0, %rax
leaq -0x348(%rax), %rax
leaq 0x98(%rax), %rcx
movq %rcx, -0x48(%rbp)
movq %rax, -0x38(%rbp)
movq 0x98(%rax), %r12
testq %r12, %r12
je 0x2b7c0
movq 0x8(%r12), %rax
movq %rax, -0x50(%rbp)
movl (%r12), %r15d
testl $0x300, %r15d           # imm = 0x300
je 0x2b7b7
movzbl %r15b, %eax
movl %eax, -0x2c(%rbp)
cmpl $0x11, %eax
jne 0x2b71b
cmpl $0x0, 0x10(%r12)
je 0x2b7b7
xorl %ebx, %ebx
movq 0x18(%r12), %rax
movq (%rax,%rbx,8), %rdi
callq 0x2b9b7
testl %eax, %eax
jne 0x2b709
movq 0x18(%r12), %r14
movabsq $-0x77fffffffffff, %rdi # imm = 0xFFF8800000000001
callq 0x4f95a
movq %rax, (%r14,%rbx,8)
incq %rbx
movl 0x10(%r12), %eax
cmpq %rax, %rbx
jb 0x2b6df
jmp 0x2b7b7
movslq 0x14(%r12), %r13
testq %r13, %r13
jle 0x2b7b7
addl $-0xf, -0x2c(%rbp)
movq 0x20(%r12), %rbx
shlq $0x4, %r13
addq %rbx, %r13
movzbl %r15b, %eax
movl %eax, -0x3c(%rbp)
cmpb $0x10, %r15b
je 0x2b74f
xorl %r14d, %r14d
cmpl $0xe, -0x3c(%rbp)
jne 0x2b760
movq (%rbx), %rdi
callq 0x2b9b7
xorl %r14d, %r14d
testl %eax, %eax
sete %r14b
cmpl $0x1, -0x2c(%rbp)
ja 0x2b77a
movq 0x8(%rbx), %rdi
callq 0x2b9b7
testl %eax, %eax
movl $0x1, %eax
cmovel %eax, %r14d
testl %r14d, %r14d
je 0x2b7ae
decl 0x10(%r12)
incl 0x18(%r12)
movabsq $-0x77fffffffffff, %rdi # imm = 0xFFF8800000000001
callq 0x4f95a
movq %rax, (%rbx)
movabsq $-0x7000000000000, %rdi # imm = 0xFFF9000000000000
callq 0x4f95a
movq %rax, 0x8(%rbx)
addq $0x10, %rbx
cmpq %r13, %rbx
jb 0x2b740
movq -0x50(%rbp), %r12
jmp 0x2b6a2
movq -0x48(%rbp), %r13
movq (%r13), %r12
testq %r12, %r12
movq -0x38(%rbp), %r15
je 0x2b81e
xorl %ebx, %ebx
movq 0x8(%r12), %r14
movl (%r12), %eax
testl $0x300, %eax            # imm = 0x300
je 0x2b7f1
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movl %eax, (%r12)
movq %r12, %rbx
jmp 0x2b816
decq 0xb0(%r15)
movq %r12, %rdi
callq 0x2ba21
leaq 0x8(%rbx), %rax
testq %rbx, %rbx
cmoveq %r13, %rax
movq %r14, (%rax)
movq %r12, %rdi
callq 0x120b0
movq %r14, %r12
testq %r14, %r14
jne 0x2b7d3
movq 0x90(%r15), %r12
testq %r12, %r12
je 0x2b887
movq -0x38(%rbp), %rbx
addq $0x90, %rbx
xorl %r14d, %r14d
movq 0x8(%r12), %r15
movl (%r12), %eax
testl $0x300, %eax            # imm = 0x300
je 0x2b856
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movl %eax, (%r12)
movq %r12, %r14
jmp 0x2b87f
movq -0x38(%rbp), %rax
decq 0xb0(%rax)
movq %r12, %rdi
callq 0x2ba21
leaq 0x8(%r14), %rax
testq %r14, %r14
cmoveq %rbx, %rax
movq %r15, (%rax)
movq %r12, %rdi
callq 0x120b0
movq %r15, %r12
testq %r15, %r15
jne 0x2b838
movq -0x38(%rbp), %r14
cmpl $0x0, 0x27c(%r14)
jle 0x2b9a3
movq 0x288(%r14), %rbx
movabsq $-0x800000000000, %r12  # imm = 0xFFFF800000000000
addq $0x8, %rbx
xorl %r13d, %r13d
movabsq $-0x1000000000000, %r15 # imm = 0xFFFF000000000000
movq -0x8(%rbx), %rdi
movq %rdi, %rax
andq %r12, %rax
cmpq %r15, %rax
jne 0x2b98c
movq (%rbx), %rax
movq %rax, %rcx
andq %r12, %rcx
movabsq $-0x7800000000000, %rdx # imm = 0xFFF8800000000000
cmpq %rdx, %rcx
je 0x2b8fd
movabsq $-0x7000000000000, %rdx # imm = 0xFFF9000000000000
cmpq %rdx, %rcx
jne 0x2b97a
testb $0x1, %al
jne 0x2b97a
callq 0x4f838
movq %rax, %r12
movq %rax, %rdi
callq 0x14691
testl %eax, %eax
jne 0x2b93d
movq -0x10(%r12), %rax
movq 0x8(%rax), %rax
testq %rax, %rax
je 0x2b931
movq -0x8(%r12), %rsi
movq %r12, %rdi
callq *%rax
testl %eax, %eax
jne 0x2b9b2
addq $-0x20, %r12
movq %r12, %rdi
callq 0x120b0
movabsq $-0x77fffffffffff, %rdi # imm = 0xFFF8800000000001
callq 0x4f95a
movq %rax, -0x8(%rbx)
movabsq $-0x7000000000000, %rdi # imm = 0xFFF9000000000000
callq 0x4f95a
movq %rax, (%rbx)
incl 0x280(%r14)
decl 0x278(%r14)
movabsq $-0x800000000000, %r12  # imm = 0xFFFF800000000000
movabsq $-0x7000000000000, %rdi # imm = 0xFFF9000000000000
callq 0x4f95a
movq %rax, (%rbx)
incq %r13
movslq 0x27c(%r14), %rax
addq $0x10, %rbx
cmpq %rax, %r13
jl 0x2b8bb
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x13854