// File: /workspace/github_cpp_makefile_star2_O1/Alcaro[P]bridges/arlib/staticmap.cpp
// Function: staticmap::alloc(unsigned long)
uint64_t staticmap::alloc(size_t bytes)
{
//printf("alloc %lu", bytes);
	uint64_t wanted_bucket = ilog2(bytes);
	
	uint64_t current_bucket = wanted_bucket;
	
again:
	uint64_t ptr = rd64(off_r_freespace(current_bucket));
	if (ptr > 1)
	{
		{
			// remove from freelist
			uint64_t next_free = rd64(ptr+off_f_nextobj);
			if (next_free)
				wr64(next_free+off_f_prevptr, off_r_freespace(current_bucket));
			wr64(off_r_freespace(current_bucket), next_free);
		}
		
	split:
		// split it, add new freespaces to their respective buckets
		uint64_t split = wanted_bucket;
		while (split < current_bucket)
		{
			uint64_t ptr_new_free = ptr+(1<<split);
			uint64_t prev_obj = rd64(off_r_freespace(split));
			if (prev_obj == 1)
			{
				for (uint64_t n=split;rd64(off_r_freespace(split))==1;n--)
					wr64(off_r_freespace(split), 0);
				prev_obj = 0;
			}
			if (prev_obj) // if freelist[n]
				wr64(rd64(off_r_freespace(split))+off_f_prevptr, ptr_new_free+off_f_nextobj); // set freelist[n]->prev to new object
			wr64(ptr_new_free, (1<<split)+t_free, prev_obj, off_r_freespace(split)); // create object
			wr64(off_r_freespace(split), ptr_new_free); // add to freelist
			split++;
		}
		// TODO: batch up writes to freelist
		
//printf(" -> %lu\n", ptr);
		return ptr;
	}
	else if (ptr == 0)
	{
		current_bucket++;
		goto again;
	}
	else // else equals 1, every future bucket is empty
	{
		current_bucket = ilog2(mmap.size());
		ptr = mmap.size();
		f.resize(mmap.size()*2, mmap, map_writable);
		goto split;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdi, %rbx
bsrq %rsi, %r14
leaq 0x8(%rdi), %rax
movq %rax, 0x8(%rsp)
leaq 0x4(%rdi), %rax
movq %rax, 0x40(%rsp)
leaq 0x10(%rsp), %r12
movq %r14, %rbp
movq %r14, 0x30(%rsp)
movq 0x8(%rsp), %rcx
movq (%rcx), %rcx
movq (%rcx,%rbp,8), %rdx
cmpq $0x2, %rdx
jb 0x17d15
leaq (,%rbp,8), %r15
movq %rdx, %r13
movq 0x8(%rcx,%rdx), %r14
testq %r14, %r14
je 0x17cf6
leaq 0x10(%r14), %rcx
movq %r15, 0x10(%rsp)
movl 0x4(%rbx), %edi
movl $0x8, %edx
movq %r12, %rsi
callq 0x30d0
movq %r14, 0x10(%rsp)
movl 0x4(%rbx), %edi
movl $0x8, %edx
movq %r12, %rsi
movq %r15, %rcx
callq 0x30d0
movq 0x30(%rsp), %r14
jmp 0x17d41
testq %rdx, %rdx
je 0x17e54
movq 0x10(%rbx), %r13
bsrq %r13, %rbp
leaq (,%r13,2), %rsi
movzbl 0x18(%rbx), %ecx
movq 0x40(%rsp), %rdi
movq 0x8(%rsp), %rdx
callq 0x9e2c
cmpq %rbp, %r14
jae 0x17e50
movq %r13, 0x38(%rsp)
movq %r14, %r13
movq %rbp, 0x48(%rsp)
movl $0x1, %r15d
movl %r13d, %ecx
shll %cl, %r15d
leaq (,%r13,8), %rbp
movq 0x8(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r13,8), %r14
cmpq $0x1, %r14
jne 0x17db1
movq 0x8(%rsp), %rax
movq (%rax), %rax
cmpq $0x1, (%rax,%rbp)
jne 0x17dae
movq $0x0, 0x10(%rsp)
movl 0x4(%rbx), %edi
movl $0x8, %edx
movq %r12, %rsi
movq %rbp, %rcx
callq 0x30d0
movq 0x8(%rbx), %rax
jmp 0x17d85
xorl %r14d, %r14d
movq %r12, %rsi
movslq %r15d, %r12
movq 0x38(%rsp), %rax
leaq (%rax,%r12), %r15
testq %r14, %r14
je 0x17df7
movq 0x8(%rbx), %rax
movq (%rax,%rbp), %rcx
addq $0x10, %rcx
leaq 0x8(%r15), %rax
movq %rax, 0x10(%rsp)
movl 0x4(%rbx), %edi
movl $0x8, %edx
movq %r15, 0x50(%rsp)
movq %rsi, %r15
callq 0x30d0
movq %r15, %rsi
movq 0x50(%rsp), %r15
movq %r12, 0x10(%rsp)
movq %r14, 0x18(%rsp)
movq %rbp, 0x20(%rsp)
movl 0x4(%rbx), %edi
movl $0x18, %edx
movq %rsi, %r12
movq %r15, %rcx
callq 0x30d0
movq %r15, 0x10(%rsp)
movl 0x4(%rbx), %edi
movl $0x8, %edx
movq %r12, %rsi
movq %rbp, %rcx
callq 0x30d0
incq %r13
movq 0x48(%rsp), %rbp
cmpq %rbp, %r13
jne 0x17d57
xorl %ecx, %ecx
movq 0x38(%rsp), %r13
movq 0x30(%rsp), %r14
jmp 0x17e59
xorl %ecx, %ecx
jmp 0x17e59
incq %rbp
movb $0x1, %cl
testb %cl, %cl
jne 0x17cb6
movq %r13, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop