// File: /workspace/github_c_makefile_star2_O2/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
movq %rax, -0x48(%rbp)
movq %rax, %r15
leaq 0x98(%rax), %rcx
movq %rcx, -0x50(%rbp)
movq 0x98(%rax), %rax
movq %rax, -0x40(%rbp)
movq %r15, -0x38(%rbp)
movq -0x40(%rbp), %r12
testq %r12, %r12
je 0x28e1b
movq 0x8(%r12), %rax
movq %rax, -0x40(%rbp)
movl (%r12), %ebx
testw $0x300, %bx             # imm = 0x300
je 0x28d16
movzbl %bl, %eax
cmpl $0x11, %eax
jne 0x28d7a
xorl %ebx, %ebx
movl 0x10(%r12), %eax
cmpq %rax, %rbx
jae 0x28d16
movq 0x18(%r12), %rax
movq (%rax,%rbx,8), %rdi
callq 0x29016
testl %eax, %eax
jne 0x28d75
movq 0x18(%r12), %r14
movabsq $-0x77fffffffffff, %rdi # imm = 0xFFF8800000000001
callq 0x4b313
movq %rax, (%r14,%rbx,8)
incq %rbx
jmp 0x28d41
addl $-0xf, %eax
movl %eax, -0x2c(%rbp)
movq 0x20(%r12), %r14
movslq 0x14(%r12), %r15
shlq $0x4, %r15
addq %r14, %r15
movzbl %bl, %eax
movl %eax, -0x30(%rbp)
cmpq %r15, %r14
jae 0x28e12
cmpb $0x10, %bl
je 0x28da7
cmpl $0xe, -0x30(%rbp)
jne 0x28dc1
movq (%r14), %rdi
callq 0x29016
testl %eax, %eax
setne %r13b
cmpl $0x2, -0x2c(%rbp)
jb 0x28dca
testl %eax, %eax
jne 0x28e0c
jmp 0x28ddd
movb $0x1, %r13b
cmpl $0x1, -0x2c(%rbp)
ja 0x28e0c
movq 0x8(%r14), %rdi
callq 0x29016
testl %eax, %eax
setne %al
testb %r13b, %al
jne 0x28e0c
decl 0x10(%r12)
incl 0x18(%r12)
movabsq $-0x77fffffffffff, %rdi # imm = 0xFFF8800000000001
callq 0x4b313
movq %rax, (%r14)
movabsq $-0x7000000000000, %rdi # imm = 0xFFF9000000000000
callq 0x4b313
movq %rax, 0x8(%r14)
addq $0x10, %r14
jmp 0x28d97
movq -0x38(%rbp), %r15
jmp 0x28d16
movq 0x98(%r15), %rbx
xorl %r12d, %r12d
leaq 0x8(%r12), %r14
testq %r12, %r12
cmoveq -0x50(%rbp), %r14
movq %rbx, %r12
testq %rbx, %rbx
je 0x28e70
movq 0x8(%r12), %rbx
movl (%r12), %eax
testw $0x300, %ax             # imm = 0x300
jne 0x28e65
decq 0xb0(%r15)
movq %r12, %rdi
callq 0x2907e
movq %rbx, (%r14)
movq %r12, %rdi
callq 0x120b0
jmp 0x28e32
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movl %eax, (%r12)
jmp 0x28e25
movq -0x48(%rbp), %rax
addq $0x90, %rax
movq 0x90(%r15), %rbx
xorl %r12d, %r12d
leaq 0x8(%r12), %r14
testq %r12, %r12
movq %rax, %r13
cmoveq %rax, %r14
movq %rbx, %r12
testq %rbx, %rbx
je 0x28ed4
movq 0x8(%r12), %rbx
movl (%r12), %eax
testw $0x300, %ax             # imm = 0x300
jne 0x28ec6
decq 0xb0(%r15)
movq %r12, %rdi
callq 0x2907e
movq %rbx, (%r14)
movq %r12, %rdi
callq 0x120b0
jmp 0x28e93
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movl %eax, (%r12)
movq %r13, %rax
jmp 0x28e84
movabsq $-0x800000000000, %r14  # imm = 0xFFFF800000000000
movq 0x288(%r15), %r12
addq $0x8, %r12
xorl %ebx, %ebx
movabsq $-0x1000000000000, %r13 # imm = 0xFFFF000000000000
movslq 0x27c(%r15), %rax
cmpq %rax, %rbx
jge 0x28fd7
movq -0x8(%r12), %rdi
movq %rdi, %rax
andq %r14, %rax
cmpq %r13, %rax
jne 0x28fcb
movq (%r12), %rax
movq %rax, %rcx
andq %r14, %rcx
movabsq $-0x7800000000000, %rdx # imm = 0xFFF8800000000000
cmpq %rdx, %rcx
je 0x28f45
movabsq $-0x7000000000000, %rdx # imm = 0xFFF9000000000000
cmpq %rdx, %rcx
jne 0x28fb8
testb $0x1, %al
jne 0x28fb8
callq 0x4b1f1
movq %rax, %r15
movq %rax, %rdi
callq 0x12f5a
testl %eax, %eax
jne 0x28f7f
movq -0x10(%r15), %rax
movq 0x8(%rax), %rax
testq %rax, %rax
je 0x28f73
movq -0x8(%r15), %rsi
movq %r15, %rdi
callq *%rax
testl %eax, %eax
jne 0x28fe6
addq $-0x20, %r15
movq %r15, %rdi
callq 0x120b0
movabsq $-0x77fffffffffff, %rdi # imm = 0xFFF8800000000001
callq 0x4b313
movq %rax, -0x8(%r12)
movabsq $-0x7000000000000, %rdi # imm = 0xFFF9000000000000
callq 0x4b313
movq %rax, (%r12)
movq -0x38(%rbp), %r15
incl 0x280(%r15)
decl 0x278(%r15)
movabsq $-0x7000000000000, %rdi # imm = 0xFFF9000000000000
callq 0x4b313
movq %rax, (%r12)
incq %rbx
addq $0x10, %r12
jmp 0x28ef5
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x57003(%rip), %rax     # 0x7fff0
movq (%rax), %rdi
leaq 0x27019(%rip), %rsi     # 0x50010
leaq 0x30d32(%rip), %rcx     # 0x59d30
leaq 0x30d39(%rip), %r8      # 0x59d3e
movl $0x1f8, %edx            # imm = 0x1F8
xorl %eax, %eax
callq 0x125e0
callq 0x12100