// File: /workspace/github_cpp_makefile_star2_O3/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 $0x48, %rsp
movq %rdi, %rbx
bsrq %rsi, %r14
leaq 0x8(%rdi), %rax
movq %rax, 0x38(%rsp)
movq 0x8(%rdi), %rax
leal (,%r14,8), %r15d
movq (%rax,%r15), %rbp
cmpq $0x1, %rbp
jbe 0x17fab
movq %r14, 0x8(%rsp)
jmp 0x17fd1
movq %r14, %rdx
testq %rbp, %rbp
jne 0x1802a
movq %rdx, %rcx
incq %rdx
movq 0x8(%rax,%rcx,8), %rbp
cmpq $0x1, %rbp
jbe 0x17fae
movq %rdx, 0x8(%rsp)
leaq 0x8(,%rcx,8), %r15
movq 0x8(%rax,%rbp), %r12
testq %r12, %r12
je 0x18007
leaq 0x10(%r12), %rcx
leaq 0x10(%rsp), %r13
movq %r15, (%r13)
movl 0x4(%rbx), %edi
movl $0x8, %edx
movq %r13, %rsi
callq 0x30d0
movq %r12, (%r13)
movl 0x4(%rbx), %edi
leaq 0x10(%rsp), %rsi
jmp 0x18016
leaq 0x10(%rsp), %rsi
movq $0x0, (%rsi)
movl 0x4(%rbx), %edi
movl $0x8, %edx
movq %r15, %rcx
callq 0x30d0
movq 0x8(%rsp), %r15
jmp 0x1804c
movq 0x10(%rbx), %rbp
bsrq %rbp, %r15
leaq 0x4(%rbx), %rdi
leaq (,%rbp,2), %rsi
movzbl 0x18(%rbx), %ecx
movq 0x38(%rsp), %rdx
callq 0xa318
cmpq %r15, %r14
jae 0x1815c
leaq 0x10(%rsp), %r13
movq %rbp, 0x40(%rsp)
movq %r15, 0x8(%rsp)
movl $0x1, %eax
movl %r14d, %ecx
shll %cl, %eax
movslq %eax, %r12
leaq (%r12,%rbp), %rax
movq %rax, 0x30(%rsp)
leaq (,%r14,8), %rbp
movq 0x38(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r14,8), %r15
testq %r15, %r15
je 0x180c0
cmpq $0x1, %r15
jne 0x180e5
movq $0x0, 0x10(%rsp)
movl 0x4(%rbx), %edi
movl $0x8, %edx
movq %r13, %rsi
movq %rbp, %rcx
callq 0x30d0
movq 0x8(%rbx), %rax
cmpq $0x1, (%rax,%rbp)
je 0x18099
movq %r12, 0x10(%rsp)
movq $0x0, 0x18(%rsp)
movq %rbp, 0x20(%rsp)
movl 0x4(%rbx), %edi
movl $0x18, %edx
movq %r13, %rsi
movq 0x30(%rsp), %r15
jmp 0x18126
leaq 0x10(%r15), %rcx
movq 0x30(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x10(%rsp)
movl 0x4(%rbx), %edi
movl $0x8, %edx
movq %r13, %rsi
callq 0x30d0
movq %r12, 0x10(%rsp)
movq %r15, 0x18(%rsp)
movq 0x30(%rsp), %r15
movq %rbp, 0x20(%rsp)
movl 0x4(%rbx), %edi
movl $0x18, %edx
movq %r13, %rsi
movq %r15, %rcx
callq 0x30d0
movq %r15, 0x10(%rsp)
movl 0x4(%rbx), %edi
movl $0x8, %edx
movq %r13, %rsi
movq %rbp, %rcx
callq 0x30d0
incq %r14
movq 0x8(%rsp), %r15
cmpq %r15, %r14
movq 0x40(%rsp), %rbp
jne 0x18064
movq %rbp, %rax
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq