// File: Alcaro[P]bridges/arlib/staticmap.cpp
// Function: staticmap::fsck()
void staticmap::fsck()
{
	array<uint64_t> objects_file;
	array<uint64_t> objects_reachable;
	uint64_t pos = 0;
	while (pos != mmap.size())
	{
		objects_file.append(pos);
		uint64_t head = rd64(pos);
		uint64_t size = head & ~t_typemask;
		if (size & (size-1)) abort(); // size must be power of two
		if ((size-1) & pos) abort(); // every object must be correctly aligned
		if (size < 32) abort(); // size must be at least 32
		pos += size;
	}
	
	objects_reachable.append(0);
	if (rd64(0) != off_r_objsize + t_meta) abort();
	if (rd64(off_r_sig) != sig_passive && rd64(off_r_sig) != sig_active) abort();
	
	uint64_t hashmap_pos = rd64(off_r_hm_ptr);
	uint64_t hashmap_head = rd64(hashmap_pos + off_header);
	objects_reachable.append(hashmap_pos);
	if ((hashmap_head & t_typemask) != t_meta) abort();
	uint64_t hashmap_size = hashmap_head & ~t_typemask;
	if (hashmap_size < 512) abort();
	
	set<bytesr> keys_seen;
	uint64_t hashmap_load = 0;
	uint64_t hashmap_items = 0;
	uint64_t hashmap_iter = 16;
	while (hashmap_iter < hashmap_size)
	{
		uint64_t ptr = rd64(hashmap_pos + hashmap_iter + off_h_ptr);
		uint64_t hash = rd64(hashmap_pos + hashmap_iter + off_h_hash);
		hashmap_iter += 16;
		
		if (ptr >= 1) hashmap_load++;
		if (ptr <= 1) continue;
		hashmap_items++;
		
		objects_reachable.append(ptr);
		uint64_t obj_head = rd64(ptr + off_header);
		if ((obj_head & t_typemask) != t_data) abort();
		uint64_t obj_size = obj_head & ~t_typemask;
		uint64_t key_size = rd64(ptr+off_d_keysz);
		uint64_t val_size = rd64(ptr+off_d_valsz);
		if (off_d_keystart+key_size+val_size > obj_size) abort();
		if (off_d_keystart+key_size+val_size <= obj_size/2) abort();
		
		bytesr by = mmap.slice(ptr+off_d_keystart, key_size);
		if (keys_seen.contains(by)) abort();
		keys_seen.add(by);
		if (hash != sm_hash(by)) abort();
	}
	
	if (hashmap_load != rd64(off_r_hm_load)) abort();
	if (hashmap_items != rd64(off_r_entries)) abort();
	
	bool last = false;
	for (int i=5;i<=63;i++)
	{
		uint64_t prev = off_r_freespace(i);
		uint64_t ptr = rd64(prev);
		if (ptr == 1) last = true;
		if (ptr == 0 && last) abort();
		if (ptr > 1)
		{
		again:
			objects_reachable.append(ptr);
			uint64_t size = uint64_t(1)<<i;
			uint64_t sibling = ptr ^ size;
			if (rd64(ptr + off_header) != size+t_free) abort();
			if (rd64(ptr + off_header) == rd64(sibling + off_header)) abort(); // should've been merged
			if (rd64(ptr + off_f_prevptr) != prev) abort();
			uint64_t next = rd64(ptr + off_f_nextobj);
			prev = ptr + off_f_nextobj;
			
			if (next != 0)
			{
				ptr = next;
				goto again;
			}
		}
	}
	
	objects_file.sort();
	objects_reachable.sort();
	if (objects_file != objects_reachable) abort();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x170, %rsp            # imm = 0x170
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x148(%rbp)
leaq -0x18(%rbp), %rdi
callq 0x23d20
leaq -0x28(%rbp), %rdi
callq 0x23d20
movq $0x0, -0x30(%rbp)
movq -0x148(%rbp), %rdi
movq -0x30(%rbp), %rax
movq %rax, -0x150(%rbp)
addq $0x8, %rdi
callq 0x6290
movq %rax, %rcx
movq -0x150(%rbp), %rax
cmpq %rcx, %rax
je 0x34c59
leaq -0x18(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x234d0
movq -0x148(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x353f0
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
andq $-0x10, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq -0x40(%rbp), %rcx
subq $0x1, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x34c25
callq 0x4180
movq -0x40(%rbp), %rax
subq $0x1, %rax
andq -0x30(%rbp), %rax
cmpq $0x0, %rax
je 0x34c3c
callq 0x4180
cmpq $0x20, -0x40(%rbp)
jae 0x34c48
callq 0x4180
movq -0x40(%rbp), %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
jmp 0x34bb4
movq $0x0, -0x48(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x234a0
movq -0x148(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x353f0
cmpq $0x202, %rax            # imm = 0x202
je 0x34c8b
callq 0x4180
movq -0x148(%rbp), %rdi
movl $0x8, %esi
callq 0x353f0
movabsq $0x70616d736c7261, %rcx # imm = 0x70616D736C7261
cmpq %rcx, %rax
je 0x34cd0
movq -0x148(%rbp), %rdi
movl $0x8, %esi
callq 0x353f0
movabsq $0x170616d736c7261, %rcx # imm = 0x170616D736C7261
cmpq %rcx, %rax
je 0x34cd0
callq 0x4180
movq -0x148(%rbp), %rdi
movl $0x10, %esi
callq 0x353f0
movq -0x148(%rbp), %rdi
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rsi
addq $0x0, %rsi
callq 0x353f0
movq %rax, -0x58(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0x50(%rbp), %rsi
callq 0x234d0
movq -0x58(%rbp), %rax
andq $0xf, %rax
cmpq $0x2, %rax
je 0x34d1d
callq 0x4180
movq -0x58(%rbp), %rax
andq $-0x10, %rax
movq %rax, -0x60(%rbp)
cmpq $0x200, -0x60(%rbp)     # imm = 0x200
jae 0x34d38
callq 0x4180
leaq -0x88(%rbp), %rdi
callq 0x35e40
movq $0x0, -0x90(%rbp)
movq $0x0, -0x98(%rbp)
movq $0x10, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
cmpq -0x60(%rbp), %rax
jae 0x34fad
movq -0x148(%rbp), %rdi
movq -0x50(%rbp), %rsi
addq -0xa0(%rbp), %rsi
addq $0x0, %rsi
callq 0x353f0
movq -0x148(%rbp), %rdi
movq %rax, -0xa8(%rbp)
movq -0x50(%rbp), %rsi
addq -0xa0(%rbp), %rsi
addq $0x8, %rsi
callq 0x353f0
movq %rax, -0xb0(%rbp)
movq -0xa0(%rbp), %rax
addq $0x10, %rax
movq %rax, -0xa0(%rbp)
cmpq $0x1, -0xa8(%rbp)
jb 0x34de8
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
cmpq $0x1, -0xa8(%rbp)
ja 0x34df7
jmp 0x34d65
movq -0x98(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x98(%rbp)
leaq -0x28(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x234d0
movq -0x148(%rbp), %rdi
movq -0xa8(%rbp), %rsi
addq $0x0, %rsi
callq 0x353f0
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
andq $0xf, %rax
cmpq $0x1, %rax
je 0x34e4d
callq 0x4180
movq -0x148(%rbp), %rdi
movq -0xb8(%rbp), %rax
andq $-0x10, %rax
movq %rax, -0xc0(%rbp)
movq -0xa8(%rbp), %rsi
addq $0x8, %rsi
callq 0x353f0
movq -0x148(%rbp), %rdi
movq %rax, -0xc8(%rbp)
movq -0xa8(%rbp), %rsi
addq $0x10, %rsi
callq 0x353f0
movq %rax, -0xd0(%rbp)
movq -0xc8(%rbp), %rax
addq $0x18, %rax
addq -0xd0(%rbp), %rax
cmpq -0xc0(%rbp), %rax
jbe 0x34ebb
callq 0x4180
movq -0xc8(%rbp), %rax
addq $0x18, %rax
addq -0xd0(%rbp), %rax
movq -0xc0(%rbp), %rcx
shrq %rcx
cmpq %rcx, %rax
ja 0x34ee1
callq 0x4180
movq -0x148(%rbp), %rsi
addq $0x8, %rsi
movq -0xa8(%rbp), %rdx
addq $0x18, %rdx
movq -0xc8(%rbp), %rcx
leaq -0xf0(%rbp), %rdi
callq 0xc4c0
movq -0xf0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe8(%rbp), %rax
movq %rax, -0xd8(%rbp)
leaq -0x88(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x35e70
testb $0x1, %al
jne 0x34f3f
jmp 0x34f44
callq 0x4180
leaq -0x88(%rbp), %rdi
leaq -0xe0(%rbp), %rsi
callq 0x35eb0
movq -0xb0(%rbp), %rax
movq %rax, -0x158(%rbp)
movq -0xe0(%rbp), %rax
movq %rax, -0x100(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0x100(%rbp), %rdi
movq -0xf8(%rbp), %rsi
callq 0x33710
movq %rax, %rcx
movq -0x158(%rbp), %rax
cmpq %rcx, %rax
je 0x34fa8
callq 0x4180
jmp 0x34d65
movq -0x148(%rbp), %rdi
movq -0x90(%rbp), %rax
movq %rax, -0x160(%rbp)
movl $0x18, %esi
callq 0x353f0
movq %rax, %rcx
movq -0x160(%rbp), %rax
cmpq %rcx, %rax
je 0x34fe0
callq 0x4180
movq -0x148(%rbp), %rdi
movq -0x98(%rbp), %rax
movq %rax, -0x168(%rbp)
movl $0x20, %esi
callq 0x353f0
movq %rax, %rcx
movq -0x168(%rbp), %rax
cmpq %rcx, %rax
je 0x35013
callq 0x4180
movb $0x0, -0x101(%rbp)
movl $0x5, -0x108(%rbp)
cmpl $0x3f, -0x108(%rbp)
jg 0x351d2
movslq -0x108(%rbp), %rdi
callq 0x336d0
movq -0x148(%rbp), %rdi
movq %rax, -0x110(%rbp)
movq -0x110(%rbp), %rsi
callq 0x353f0
movq %rax, -0x118(%rbp)
cmpq $0x1, -0x118(%rbp)
jne 0x3506f
movb $0x1, -0x101(%rbp)
cmpq $0x0, -0x118(%rbp)
jne 0x35087
testb $0x1, -0x101(%rbp)
je 0x35087
callq 0x4180
cmpq $0x1, -0x118(%rbp)
jbe 0x351bc
jmp 0x35097
leaq -0x28(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x234d0
movq -0x148(%rbp), %rdi
movl -0x108(%rbp), %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, -0x120(%rbp)
movq -0x118(%rbp), %rax
xorq -0x120(%rbp), %rax
movq %rax, -0x128(%rbp)
movq -0x118(%rbp), %rsi
addq $0x0, %rsi
callq 0x353f0
movq -0x120(%rbp), %rcx
addq $0x0, %rcx
cmpq %rcx, %rax
je 0x350ff
callq 0x4180
movq -0x148(%rbp), %rdi
movq -0x118(%rbp), %rsi
addq $0x0, %rsi
callq 0x353f0
movq -0x148(%rbp), %rdi
movq %rax, -0x170(%rbp)
movq -0x128(%rbp), %rsi
addq $0x0, %rsi
callq 0x353f0
movq %rax, %rcx
movq -0x170(%rbp), %rax
cmpq %rcx, %rax
jne 0x35148
callq 0x4180
movq -0x148(%rbp), %rdi
movq -0x118(%rbp), %rsi
addq $0x10, %rsi
callq 0x353f0
cmpq -0x110(%rbp), %rax
je 0x3516d
callq 0x4180
movq -0x148(%rbp), %rdi
movq -0x118(%rbp), %rsi
addq $0x8, %rsi
callq 0x353f0
movq %rax, -0x130(%rbp)
movq -0x118(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x110(%rbp)
cmpq $0x0, -0x130(%rbp)
je 0x351ba
movq -0x130(%rbp), %rax
movq %rax, -0x118(%rbp)
jmp 0x35097
jmp 0x351bc
jmp 0x351be
movl -0x108(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x108(%rbp)
jmp 0x35024
leaq -0x18(%rbp), %rdi
callq 0x35ee0
leaq -0x28(%rbp), %rdi
callq 0x35ee0
movq -0x28(%rbp), %rax
movq %rax, -0x140(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x138(%rbp)
movq -0x140(%rbp), %rsi
movq -0x138(%rbp), %rdx
leaq -0x18(%rbp), %rdi
callq 0x35f00
testb $0x1, %al
jne 0x35217
jmp 0x3521c
callq 0x4180
leaq -0x88(%rbp), %rdi
callq 0x35f40
leaq -0x28(%rbp), %rdi
callq 0x23c00
leaq -0x18(%rbp), %rdi
callq 0x23c00
addq $0x170, %rsp            # imm = 0x170
popq %rbp
retq
nopw %cs:(%rax,%rax)