LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: bonetblai[P]mdp-engine/wet/./wet.h
// Function: problem_t::problem_t(unsigned long, float, state_t const&, state_t const&)
problem_t(size_t size, float p, const state_t &init = state_t(0,0), const state_t &goal = state_t(0,0))
     : size_(size), init_(init), goal_(goal), p_(p) {
        state_t::size_ = size_;
        water_ = new char[size_ * size_];
        for( size_t x = 0; x < size_; ++x )
            for( size_t y = 0; y < size_; ++y )
                if( Random::real() < p_ )
                    water_[(x * size_) + y] = 1 + (lrand48() % (XVER ? 2 : 3));
    }

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movss %xmm0, 0x64(%rsp)
movq %rdx, 0x58(%rsp)
movq %rcx, 0x50(%rsp)
movq 0x70(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movss 0x48e98(%rip), %xmm0    # 0x51008
movss 0x48e94(%rip), %xmm1    # 0x5100c
callq 0xbcb0
movq 0x10(%rsp), %rax
leaq 0x67a8f(%rip), %rcx     # 0x6fc18
movq %rcx, (%rax)
movq 0x68(%rsp), %rcx
movq %rcx, 0x18(%rax)
movq %rax, %rcx
addq $0x20, %rcx
movq %rcx, 0x18(%rsp)
movq 0x58(%rsp), %rcx
movl (%rcx), %ecx
movl %ecx, 0x20(%rax)
movq %rax, %rcx
addq $0x24, %rcx
movq %rcx, 0x20(%rsp)
movq 0x50(%rsp), %rcx
movl (%rcx), %ecx
movl %ecx, 0x24(%rax)
movss 0x64(%rsp), %xmm0
movss %xmm0, 0x30(%rax)
movq 0x18(%rax), %rcx
movq %rcx, 0x69121(%rip)     # 0x712f8
movq 0x18(%rax), %rdi
imulq %rdi, %rdi
callq 0x6030
movq %rax, 0x28(%rsp)
jmp 0x81eb
movq 0x10(%rsp), %rax
movq 0x28(%rsp), %rcx
movq %rcx, 0x28(%rax)
movq $0x0, 0x38(%rsp)
movq 0x10(%rsp), %rcx
movq 0x38(%rsp), %rax
cmpq 0x18(%rcx), %rax
jae 0x82f4
movq $0x0, 0x30(%rsp)
movq 0x10(%rsp), %rcx
movq 0x30(%rsp), %rax
cmpq 0x18(%rcx), %rax
jae 0x82df
callq 0xbd00
movss %xmm0, 0xc(%rsp)
jmp 0x8240
movss 0xc(%rsp), %xmm1
movq 0x10(%rsp), %rax
movss 0x30(%rax), %xmm0
ucomiss %xmm1, %xmm0
jbe 0x82ca
callq 0x6210
movq 0x10(%rsp), %rsi
movl 0x6908f(%rip), %edi     # 0x712f4
andl $0x1, %edi
movl $0x3, %ecx
movl $0x2, %edx
cmpl $0x0, %edi
cmovnel %edx, %ecx
movslq %ecx, %rcx
cqto
idivq %rcx
addq $0x1, %rdx
movq 0x28(%rsi), %rax
movq 0x38(%rsp), %rcx
imulq 0x18(%rsi), %rcx
addq 0x30(%rsp), %rcx
movb %dl, (%rax,%rcx)
jmp 0x82ca
movq 0x20(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
callq 0xba80
movq 0x18(%rsp), %rdi
callq 0xba80
movq 0x10(%rsp), %rdi
callq 0xd270
jmp 0x82f9
jmp 0x82cc
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x30(%rsp)
jmp 0x821f
jmp 0x82e1
movq 0x38(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x38(%rsp)
jmp 0x8202
addq $0x78, %rsp
retq
movq 0x48(%rsp), %rdi
callq 0x64a0
nopw %cs:(%rax,%rax)
nopl (%rax)
// File: bonetblai[P]mdp-engine/wet/./wet.h
// Function: problem_t::print(std::ostream&) const
virtual void print(std::ostream &os) const {
        os << "size = " << size_ << std::endl
           << "init = " << init_ << std::endl
           << "goal = " << goal_ << std::endl;
        for( size_t x = 0; x < size_; ++x ) os << "--";
        os << "---" << std::endl;
        for( size_t y = 0; y < size_; ++y ) {
            os << "|";
            for( size_t x = 0; x < size_; ++x ) {
                os << " " << water(x,y);
            }
            os << " |" << std::endl;
        }
        for( size_t x = 0; x < size_; ++x ) os << "--";
        os << "---" << std::endl;
    }

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x38(%rsp), %rdi
leaq 0x44283(%rip), %rsi     # 0x512f7
callq 0x62c0
movq %rax, %rdi
movq 0x10(%rsp), %rax
movq 0x18(%rax), %rsi
callq 0x60a0
movq %rax, %rdi
movq 0x63f24(%rip), %rsi     # 0x70fb8
callq 0x6300
movq %rax, %rdi
leaq 0x4425c(%rip), %rsi     # 0x512ff
callq 0x62c0
movq 0x10(%rsp), %rsi
movq %rax, %rdi
addq $0x20, %rsi
callq 0xe290
movq %rax, %rdi
movq 0x63ef5(%rip), %rsi     # 0x70fb8
callq 0x6300
movq %rax, %rdi
leaq 0x44235(%rip), %rsi     # 0x51307
callq 0x62c0
movq 0x10(%rsp), %rsi
movq %rax, %rdi
addq $0x24, %rsi
callq 0xe290
movq %rax, %rdi
movq 0x63ec6(%rip), %rsi     # 0x70fb8
callq 0x6300
movq $0x0, 0x30(%rsp)
movq 0x10(%rsp), %rcx
movq 0x30(%rsp), %rax
cmpq 0x18(%rcx), %rax
jae 0xd131
movq 0x38(%rsp), %rdi
leaq 0x441f4(%rip), %rsi     # 0x51310
callq 0x62c0
movq 0x30(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x30(%rsp)
jmp 0xd100
movq 0x38(%rsp), %rdi
leaq 0x441d2(%rip), %rsi     # 0x5130f
callq 0x62c0
movq %rax, %rdi
movq 0x63e6c(%rip), %rsi     # 0x70fb8
callq 0x6300
movq $0x0, 0x28(%rsp)
movq 0x10(%rsp), %rcx
movq 0x28(%rsp), %rax
cmpq 0x18(%rcx), %rax
jae 0xd211
movq 0x38(%rsp), %rdi
leaq 0x4419a(%rip), %rsi     # 0x51314
callq 0x62c0
movq $0x0, 0x20(%rsp)
movq 0x10(%rsp), %rcx
movq 0x20(%rsp), %rax
cmpq 0x18(%rcx), %rax
jae 0xd1de
movq 0x38(%rsp), %rdi
leaq 0x44173(%rip), %rsi     # 0x51317
callq 0x62c0
movq 0x10(%rsp), %rdi
movq %rax, 0x8(%rsp)
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rdx
callq 0xd2f0
movq 0x8(%rsp), %rdi
movl %eax, %esi
callq 0x63c0
movq 0x20(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x20(%rsp)
jmp 0xd188
movq 0x38(%rsp), %rdi
leaq 0x44129(%rip), %rsi     # 0x51313
callq 0x62c0
movq %rax, %rdi
movq 0x63dbf(%rip), %rsi     # 0x70fb8
callq 0x6300
movq 0x28(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x28(%rsp)
jmp 0xd15a
movq $0x0, 0x18(%rsp)
movq 0x10(%rsp), %rcx
movq 0x18(%rsp), %rax
cmpq 0x18(%rcx), %rax
jae 0xd24b
movq 0x38(%rsp), %rdi
leaq 0x440da(%rip), %rsi     # 0x51310
callq 0x62c0
movq 0x18(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x18(%rsp)
jmp 0xd21a
movq 0x38(%rsp), %rdi
leaq 0x440b8(%rip), %rsi     # 0x5130f
callq 0x62c0
movq %rax, %rdi
movq 0x63d52(%rip), %rsi     # 0x70fb8
callq 0x6300
addq $0x48, %rsp
retq
// File: bonetblai[P]mdp-engine/wet/./wet.h
// Function: state_t::move(int) const
state_t move(Problem::action_t a) const {
        switch( a ) {
            case 1:
                if( y() == 0 ) return s();
                return state_t(x(), y() - 1);
                break;
            case 2:
                if( x() == size_ - 1 ) return s();
                return state_t(x() + 1, y());
                break;
            case 3:
                if( y() == size_ - 1 ) return s();
                return state_t(x(), y() + 1);
                break;
            case 4:
                if( x() == 0 ) return s();
                return state_t(x() - 1, y());
                break;
        }
        return s_;
    }

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x10(%rsp)
movq %rdi, %rax
movq %rax, 0x18(%rsp)
movq %rdi, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movl %edx, 0x34(%rsp)
movq 0x38(%rsp), %rax
movq %rax, 0x20(%rsp)
movl 0x34(%rsp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, 0x28(%rsp)
subl $0x3, %eax
ja 0xd6ab
movq 0x28(%rsp), %rax
leaq 0x43b0d(%rip), %rcx     # 0x51038
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x20(%rsp), %rdi
callq 0xd340
cmpl $0x0, %eax
jne 0xd55e
movq 0x20(%rsp), %rdi
callq 0xe230
movq 0x10(%rsp), %rdi
movl %eax, %esi
callq 0xe240
jmp 0xd6bc
movq 0x20(%rsp), %rdi
callq 0xd320
movq 0x20(%rsp), %rdi
movl %eax, 0xc(%rsp)
callq 0xd340
movq 0x10(%rsp), %rdi
movl 0xc(%rsp), %esi
movl %eax, %edx
subl $0x1, %edx
callq 0x8110
jmp 0xd6bc
movq 0x20(%rsp), %rdi
callq 0xd320
movl %eax, %eax
movq 0x63d57(%rip), %rcx     # 0x712f8
subq $0x1, %rcx
cmpq %rcx, %rax
jne 0xd5c5
movq 0x20(%rsp), %rdi
callq 0xe230
movq 0x10(%rsp), %rdi
movl %eax, %esi
callq 0xe240
jmp 0xd6bc
movq 0x20(%rsp), %rdi
callq 0xd320
movq 0x20(%rsp), %rdi
addl $0x1, %eax
movl %eax, 0x8(%rsp)
callq 0xd340
movq 0x10(%rsp), %rdi
movl 0x8(%rsp), %esi
movl %eax, %edx
callq 0x8110
jmp 0xd6bc
movq 0x20(%rsp), %rdi
callq 0xd340
movl %eax, %eax
movq 0x63cf0(%rip), %rcx     # 0x712f8
subq $0x1, %rcx
cmpq %rcx, %rax
jne 0xd62c
movq 0x20(%rsp), %rdi
callq 0xe230
movq 0x10(%rsp), %rdi
movl %eax, %esi
callq 0xe240
jmp 0xd6bc
movq 0x20(%rsp), %rdi
callq 0xd320
movq 0x20(%rsp), %rdi
movl %eax, 0x4(%rsp)
callq 0xd340
movq 0x10(%rsp), %rdi
movl 0x4(%rsp), %esi
movl %eax, %edx
addl $0x1, %edx
callq 0x8110
jmp 0xd6bc
movq 0x20(%rsp), %rdi
callq 0xd320
cmpl $0x0, %eax
jne 0xd680
movq 0x20(%rsp), %rdi
callq 0xe230
movq 0x10(%rsp), %rdi
movl %eax, %esi
callq 0xe240
jmp 0xd6bc
movq 0x20(%rsp), %rdi
callq 0xd320
movq 0x20(%rsp), %rdi
subl $0x1, %eax
movl %eax, (%rsp)
callq 0xd340
movq 0x10(%rsp), %rdi
movl (%rsp), %esi
movl %eax, %edx
callq 0x8110
jmp 0xd6bc
movq 0x10(%rsp), %rdi
movq 0x20(%rsp), %rax
movl (%rax), %esi
callq 0xe240
movq 0x18(%rsp), %rax
addq $0x48, %rsp
retq
nopw %cs:(%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::aligned_malloc(unsigned long, unsigned long)
void *GC::aligned_malloc(std::size_t size, std::size_t align)
{
	// calling with 0 yields nullptr
	if (size == 0) return nullptr;

	// allocate enough space for a void*, padding, and the array
	size += sizeof(void*) + align - 1;

	// grab that much space - if that fails, return null
	void *raw = std::malloc(size);
	if (!raw) return nullptr;

	// get the pointer to return (before alignment)
	void *ret = (char*)raw + sizeof(void*);

	// align the return pointer
	ret = (char*)ret + (-(std::intptr_t)ret & (align - 1));

	// store the raw pointer before start of ret array
	*(void**)((char*)ret - sizeof(void*)) = raw;

	// return ret pointer
	return ret;
}

// Assembly:
subq $0x28, %rsp
movq %rdi, 0x18(%rsp)
movq %rsi, 0x10(%rsp)
cmpq $0x0, 0x18(%rsp)
jne 0x58c1
movq $0x0, 0x20(%rsp)
jmp 0x593d
movq 0x10(%rsp), %rax
addq $0x8, %rax
subq $0x1, %rax
addq 0x18(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rdi
callq 0x5420
movq %rax, 0x8(%rsp)
cmpq $0x0, 0x8(%rsp)
jne 0x58fa
movq $0x0, 0x20(%rsp)
jmp 0x593d
movq 0x8(%rsp), %rax
addq $0x8, %rax
movq %rax, (%rsp)
movq (%rsp), %rax
movq (%rsp), %rdx
xorl %ecx, %ecx
subq %rdx, %rcx
movq 0x10(%rsp), %rdx
subq $0x1, %rdx
andq %rdx, %rcx
addq %rcx, %rax
movq %rax, (%rsp)
movq 0x8(%rsp), %rcx
movq (%rsp), %rax
movq %rcx, -0x8(%rax)
movq (%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
addq $0x28, %rsp
retq
nopw (%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::obj_list::add(GC::info*)
void GC::obj_list::add(info *obj)
{
	// put it at the end of the list
	obj->prev = last;
	obj->next = nullptr;

	// link the other way as well - account for edge cases
	if (last) last = last->next = obj;
	else first = last = obj;
}

// Assembly:
movq %rdi, -0x8(%rsp)
movq %rsi, -0x10(%rsp)
movq -0x8(%rsp), %rax
movq %rax, -0x18(%rsp)
movq 0x8(%rax), %rdx
movq -0x10(%rsp), %rcx
movq %rdx, 0x30(%rcx)
movq -0x10(%rsp), %rcx
movq $0x0, 0x38(%rcx)
cmpq $0x0, 0x8(%rax)
je 0x59dd
movq -0x18(%rsp), %rax
movq -0x10(%rsp), %rcx
movq 0x8(%rax), %rdx
movq %rcx, 0x38(%rdx)
movq %rcx, 0x8(%rax)
jmp 0x59ee
movq -0x18(%rsp), %rax
movq -0x10(%rsp), %rcx
movq %rcx, 0x8(%rax)
movq %rcx, (%rax)
retq
nop
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::obj_list::remove(GC::info*)
void GC::obj_list::remove(info *obj)
{
	// not using first == last for the first case because in the (illegal) case where
	// handle is not in the gc database this would unlink an unrelated object.
	if (obj == first && obj == last) first = last = nullptr;
	else if (obj == first) (first = first->next)->prev = nullptr;
	else if (obj == last) (last = last->prev)->next = nullptr;
	else
	{
		obj->prev->next = obj->next;
		obj->next->prev = obj->prev;
	}
}

// Assembly:
movq %rdi, -0x8(%rsp)
movq %rsi, -0x10(%rsp)
movq -0x8(%rsp), %rcx
movq %rcx, -0x18(%rsp)
movq -0x10(%rsp), %rax
cmpq (%rcx), %rax
jne 0x5a37
movq -0x18(%rsp), %rcx
movq -0x10(%rsp), %rax
cmpq 0x8(%rcx), %rax
jne 0x5a37
movq -0x18(%rsp), %rax
movq $0x0, 0x8(%rax)
movq $0x0, (%rax)
jmp 0x5aba
movq -0x18(%rsp), %rcx
movq -0x10(%rsp), %rax
cmpq (%rcx), %rax
jne 0x5a5f
movq -0x18(%rsp), %rcx
movq (%rcx), %rax
movq 0x38(%rax), %rax
movq %rax, (%rcx)
movq $0x0, 0x30(%rax)
jmp 0x5ab8
movq -0x18(%rsp), %rcx
movq -0x10(%rsp), %rax
cmpq 0x8(%rcx), %rax
jne 0x5a8a
movq -0x18(%rsp), %rcx
movq 0x8(%rcx), %rax
movq 0x30(%rax), %rax
movq %rax, 0x8(%rcx)
movq $0x0, 0x38(%rax)
jmp 0x5ab6
movq -0x10(%rsp), %rax
movq 0x38(%rax), %rcx
movq -0x10(%rsp), %rax
movq 0x30(%rax), %rax
movq %rcx, 0x38(%rax)
movq -0x10(%rsp), %rax
movq 0x30(%rax), %rcx
movq -0x10(%rsp), %rax
movq 0x38(%rax), %rax
movq %rcx, 0x30(%rax)
jmp 0x5ab8
jmp 0x5aba
retq
nopl (%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::obj_list::merge(GC::obj_list&&)
void GC::obj_list::merge(obj_list &&other)
{
	// don't do anything if other is us
	if (&other == this) return;

	// if we're empty
	if (!first)
	{
		// just take other's stuff
		first = other.first;
		last = other.last;
	}
	// otherwise if other isn't empty
	else if (other.first)
	{
		// do an actual splice
		last->next = other.first;
		other.first->prev = last;

		// repoint the last pointer
		last = other.last;
	}

	// empty other
	other.first = other.last = nullptr;
}

// Assembly:
movq %rdi, -0x8(%rsp)
movq %rsi, -0x10(%rsp)
movq -0x8(%rsp), %rax
movq %rax, -0x18(%rsp)
cmpq %rax, -0x10(%rsp)
jne 0x5ae0
jmp 0x5b62
movq -0x18(%rsp), %rax
cmpq $0x0, (%rax)
jne 0x5b0a
movq -0x18(%rsp), %rax
movq -0x10(%rsp), %rcx
movq (%rcx), %rcx
movq %rcx, (%rax)
movq -0x10(%rsp), %rcx
movq 0x8(%rcx), %rcx
movq %rcx, 0x8(%rax)
jmp 0x5b49
movq -0x10(%rsp), %rax
cmpq $0x0, (%rax)
je 0x5b47
movq -0x18(%rsp), %rax
movq -0x10(%rsp), %rcx
movq (%rcx), %rdx
movq 0x8(%rax), %rcx
movq %rdx, 0x38(%rcx)
movq 0x8(%rax), %rdx
movq -0x10(%rsp), %rcx
movq (%rcx), %rcx
movq %rdx, 0x30(%rcx)
movq -0x10(%rsp), %rcx
movq 0x8(%rcx), %rcx
movq %rcx, 0x8(%rax)
jmp 0x5b49
movq -0x10(%rsp), %rax
movq $0x0, 0x8(%rax)
movq -0x10(%rsp), %rax
movq $0x0, (%rax)
retq
nopw %cs:(%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::__schedule_handle_root(GC::smart_handle const&)
void GC::disjoint_module::__schedule_handle_root(const smart_handle &handle)
{
	// if there's no collector thread, we MUST apply the change immediately
	if (collector_thread == std::thread::id())
	{
		// if this branch was selected, the caches should be empty
		assert(roots_add_cache.empty());
		assert(roots_remove_cache.empty());

		roots.insert(&handle.raw_handle());
	}
	// otherwise we need to cache the request
	else
	{
		roots_add_cache.insert(&handle.raw);
		roots_remove_cache.erase(&handle.raw); // ensure the sets are disjoint
	}
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x28(%rax), %rax
movq %rax, 0x50(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x9620
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0x9640
testb $0x1, %al
jne 0x6d93
jmp 0x6e38
movq 0x8(%rsp), %rdi
addq $0x140, %rdi            # imm = 0x140
callq 0x94b0
testb $0x1, %al
jne 0x6daa
jmp 0x6dac
jmp 0x6dcb
leaq 0x5d3e4(%rip), %rdi     # 0x64197
leaq 0x5d3a3(%rip), %rsi     # 0x6415d
movl $0x274, %edx            # imm = 0x274
leaq 0x5d52b(%rip), %rcx     # 0x642f1
callq 0x51e0
movq 0x8(%rsp), %rdi
addq $0x178, %rdi            # imm = 0x178
callq 0x94b0
testb $0x1, %al
jne 0x6de2
jmp 0x6de4
jmp 0x6e03
leaq 0x5d3c4(%rip), %rdi     # 0x641af
leaq 0x5d36b(%rip), %rsi     # 0x6415d
movl $0x275, %edx            # imm = 0x275
leaq 0x5d4f3(%rip), %rcx     # 0x642f1
callq 0x51e0
movq 0x8(%rsp), %rax
addq $0x48, %rax
movq %rax, (%rsp)
movq 0x58(%rsp), %rdi
callq 0x9c90
movq (%rsp), %rdi
movq %rax, 0x40(%rsp)
leaq 0x40(%rsp), %rsi
callq 0x9c40
movq %rax, 0x30(%rsp)
movb %dl, 0x38(%rsp)
jmp 0x6e81
movq 0x8(%rsp), %rdi
addq $0x140, %rdi            # imm = 0x140
movq 0x58(%rsp), %rax
movq %rax, 0x28(%rsp)
leaq 0x28(%rsp), %rsi
callq 0x9c40
movq 0x8(%rsp), %rdi
movq %rax, 0x18(%rsp)
movb %dl, 0x20(%rsp)
addq $0x178, %rdi            # imm = 0x178
movq 0x58(%rsp), %rax
movq %rax, 0x10(%rsp)
leaq 0x10(%rsp), %rsi
callq 0x9910
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::schedule_handle_create_bind_new_obj(GC::smart_handle&, GC::info*)
void GC::disjoint_module::schedule_handle_create_bind_new_obj(smart_handle &handle, info *new_obj)
{
	std::lock_guard<std::mutex> internal_lock(internal_mutex);

	// point it at the object
	handle.raw = new_obj;

	// root it
	__schedule_handle_root(handle);

	// -- add the object -- //

	// set its reference count to 1
	new_obj->ref_count = 1;

	// if there's no collector thread, we MUST apply the change immediately
	if (collector_thread == std::thread::id())
	{
		// if this branch was selected, the caches should be empty
		assert(objs_add_cache.empty());

		objs.add(new_obj);
	}
	// otherwise we need to cache the request
	else objs_add_cache.insert(new_obj);
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq %rdx, 0x50(%rsp)
movq 0x60(%rsp), %rsi
movq %rsi, 0x10(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x95b0
movq 0x10(%rsp), %rdi
movq 0x50(%rsp), %rcx
movq 0x58(%rsp), %rax
movq %rcx, (%rax)
movq 0x58(%rsp), %rsi
callq 0x6d50
jmp 0x6ed5
movq 0x10(%rsp), %rax
movq 0x50(%rsp), %rcx
movq $0x1, 0x20(%rcx)
movq 0x28(%rax), %rax
movq %rax, 0x30(%rsp)
leaq 0x28(%rsp), %rdi
callq 0x9620
movq 0x30(%rsp), %rdi
movq 0x28(%rsp), %rsi
callq 0x9640
testb $0x1, %al
jne 0x6f0f
jmp 0x6f76
movq 0x10(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0x9690
testb $0x1, %al
jne 0x6f26
jmp 0x6f28
jmp 0x6f61
leaq 0x5d217(%rip), %rdi     # 0x64146
leaq 0x5d227(%rip), %rsi     # 0x6415d
movl $0x1dd, %edx            # imm = 0x1DD
leaq 0x5d2d2(%rip), %rcx     # 0x64214
callq 0x51e0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x40(%rsp)
movl %eax, 0x3c(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x96d0
jmp 0x6fb8
movq 0x10(%rsp), %rdi
addq $0x38, %rdi
movq 0x50(%rsp), %rsi
callq 0x5990
jmp 0x6fa9
movq 0x10(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
leaq 0x50(%rsp), %rsi
callq 0x9a20
movb %dl, 0x7(%rsp)
movq %rax, 0x8(%rsp)
jmp 0x6f97
movb 0x7(%rsp), %al
movq 0x8(%rsp), %rcx
movq %rcx, 0x18(%rsp)
movb %al, 0x20(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x96d0
addq $0x68, %rsp
retq
movq 0x40(%rsp), %rdi
callq 0x5510
nopw %cs:(%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::schedule_handle_create_alias(GC::smart_handle&, GC::smart_handle const&)
void GC::disjoint_module::schedule_handle_create_alias(smart_handle &handle, const smart_handle &src_handle)
{
	std::lock_guard<std::mutex> internal_lock(internal_mutex);

	// get the target
	info *target = __get_current_target(src_handle);

	#if DRAGAZO_GARBAGE_COLLECT_DISJUNCTION_SAFETY_CHECKS

	// if we're going to repoint outside the disjunction of the handle, that's a disjunction violation
	if (target && handle.disjunction != target->disjunction)
	{
		throw GC::disjunction_error("attempt to repoint GC::ptr outside of the current disjunction");
	}

	#endif

	// point it at the source handle's current target
	handle.raw = target;

	// increment the target reference count
	if (handle.raw) ++handle.raw->ref_count;

	// root it
	__schedule_handle_root(handle);
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movq %rsi, 0x48(%rsp)
movq %rdx, 0x40(%rsp)
movq 0x50(%rsp), %rsi
movq %rsi, 0x10(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x95b0
movq 0x10(%rsp), %rdi
movq 0x40(%rsp), %rsi
callq 0x7100
movq %rax, 0x18(%rsp)
jmp 0x700d
movq 0x18(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
je 0x709d
movq 0x48(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x30(%rsp), %rcx
cmpq 0x18(%rcx), %rax
je 0x709d
movl $0x10, %edi
callq 0x5160
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x8(%rsp)
leaq 0x5d21b(%rip), %rsi     # 0x6426a
callq 0x9b00
jmp 0x7056
movq 0x8(%rsp), %rdi
leaq 0x921f6(%rip), %rsi     # 0x99258
leaq 0x2ad7(%rip), %rdx      # 0x9b40
callq 0x54d0
jmp 0x70fd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
jmp 0x70e9
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
callq 0x5250
jmp 0x70e9
movq 0x30(%rsp), %rcx
movq 0x48(%rsp), %rax
movq %rcx, (%rax)
movq 0x48(%rsp), %rax
cmpq $0x0, (%rax)
je 0x70c9
movq 0x48(%rsp), %rax
movq (%rax), %rax
movq 0x20(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x20(%rax)
movq 0x10(%rsp), %rdi
movq 0x48(%rsp), %rsi
callq 0x6d50
jmp 0x70da
leaq 0x38(%rsp), %rdi
callq 0x96d0
addq $0x58, %rsp
retq
leaq 0x38(%rsp), %rdi
callq 0x96d0
movq 0x28(%rsp), %rdi
callq 0x5510
nopl (%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::schedule_handle_destroy(GC::smart_handle const&)
void GC::disjoint_module::schedule_handle_destroy(const smart_handle &handle)
{
	std::unique_lock<std::mutex> internal_lock(internal_mutex);

	// get the old target
	info *old_target = __get_current_target(handle);

	// unroot the handle
	__schedule_handle_unroot(handle);

	// purge the handle from the repoint cache so we don't dereference undefined memory.
	// the const cast is ok because we won't be modifying it - just for lookup.
	handle_repoint_cache.erase(const_cast<info**>(&handle.raw));

	// dec the reference count
	__MUST_BE_LAST_ref_count_dec(old_target, std::move(internal_lock));
}

// Assembly:
subq $0x78, %rsp
movq %rdi, 0x70(%rsp)
movq %rsi, 0x68(%rsp)
movq 0x70(%rsp), %rsi
movq %rsi, 0x18(%rsp)
leaq 0x58(%rsp), %rdi
callq 0x9b50
movq 0x18(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0x7100
movq %rax, 0x20(%rsp)
jmp 0x71c8
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rax
movq %rax, 0x50(%rsp)
movq 0x68(%rsp), %rsi
callq 0x7290
jmp 0x71e3
movq 0x18(%rsp), %rdi
addq $0x1b0, %rdi            # imm = 0x1B0
movq 0x68(%rsp), %rax
movq %rax, 0x38(%rsp)
leaq 0x38(%rsp), %rsi
callq 0x9b90
jmp 0x7205
movq 0x50(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x28(%rsp), %rdi
movq %rdi, 0x10(%rsp)
leaq 0x58(%rsp), %rsi
callq 0x9bc0
movq 0x18(%rsp), %rdi
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
callq 0x73b0
jmp 0x7239
leaq 0x28(%rsp), %rdi
callq 0x9c00
leaq 0x58(%rsp), %rdi
callq 0x9c00
addq $0x78, %rsp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
jmp 0x727a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x48(%rsp)
movl %eax, 0x44(%rsp)
leaq 0x28(%rsp), %rdi
callq 0x9c00
leaq 0x58(%rsp), %rdi
callq 0x9c00
movq 0x48(%rsp), %rdi
callq 0x5510
nop
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::__schedule_handle_unroot(GC::smart_handle const&)
void GC::disjoint_module::__schedule_handle_unroot(const smart_handle &handle)
{
	// if there's no collector thread, we MUST apply the change immediately
	if (collector_thread == std::thread::id())
	{
		// if this branch was selected, the caches should be empty
		assert(roots_add_cache.empty());
		assert(roots_remove_cache.empty());

		roots.erase(&handle.raw);
	}
	// otherwise we need to cache the request
	else
	{
		roots_remove_cache.insert(&handle.raw);
		roots_add_cache.erase(&handle.raw); // ensure the sets are disjoint
	}
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movq %rsi, 0x48(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x28(%rax), %rax
movq %rax, 0x40(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x9620
movq 0x40(%rsp), %rdi
movq 0x38(%rsp), %rsi
callq 0x9640
testb $0x1, %al
jne 0x72d3
jmp 0x7362
movq 0x8(%rsp), %rdi
addq $0x140, %rdi            # imm = 0x140
callq 0x94b0
testb $0x1, %al
jne 0x72ea
jmp 0x72ec
jmp 0x730b
leaq 0x5cea4(%rip), %rdi     # 0x64197
leaq 0x5ce63(%rip), %rsi     # 0x6415d
movl $0x286, %edx            # imm = 0x286
leaq 0x5d032(%rip), %rcx     # 0x64338
callq 0x51e0
movq 0x8(%rsp), %rdi
addq $0x178, %rdi            # imm = 0x178
callq 0x94b0
testb $0x1, %al
jne 0x7322
jmp 0x7324
jmp 0x7343
leaq 0x5ce84(%rip), %rdi     # 0x641af
leaq 0x5ce2b(%rip), %rsi     # 0x6415d
movl $0x287, %edx            # imm = 0x287
leaq 0x5cffa(%rip), %rcx     # 0x64338
callq 0x51e0
movq 0x8(%rsp), %rdi
addq $0x48, %rdi
movq 0x48(%rsp), %rax
movq %rax, 0x30(%rsp)
leaq 0x30(%rsp), %rsi
callq 0x9910
jmp 0x73ab
movq 0x8(%rsp), %rdi
addq $0x178, %rdi            # imm = 0x178
movq 0x48(%rsp), %rax
movq %rax, 0x28(%rsp)
leaq 0x28(%rsp), %rsi
callq 0x9c40
movq 0x8(%rsp), %rdi
movq %rax, 0x18(%rsp)
movb %dl, 0x20(%rsp)
addq $0x140, %rdi            # imm = 0x140
movq 0x48(%rsp), %rax
movq %rax, 0x10(%rsp)
leaq 0x10(%rsp), %rsi
callq 0x9910
addq $0x58, %rsp
retq
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::__MUST_BE_LAST_ref_count_dec(GC::info*, std::unique_lock<std::mutex>)
void GC::disjoint_module::__MUST_BE_LAST_ref_count_dec(info *target, std::unique_lock<std::mutex> internal_lock)
{
	// decrement the reference count
	// if it falls to zero we need to perform ref count deletion logic
	if (target && --target->ref_count == 0)
	{
		// if it's in the obj add cache we can delete it immediately regardless of what's going on.
		// this is because it being in the obj add cache means it's not in the obj list, and is thus not under gc consideration.
		if (objs_add_cache.find(target) != objs_add_cache.end())
		{
			// remove it from the obj add cache
			objs_add_cache.erase(target);

			// unlock the mutex so we can call arbitrary code
			internal_lock.unlock();

			target->destroy();
			target->dealloc();
		}
		// otherwise we know it exists and isn't in the add cache, therefore it's in the obj list.
		// if we're not suppoed to cache ref count deletions, handle it immediately
		else if (!cache_ref_count_del_actions)
		{
			// remove it from the obj list
			objs.remove(target);
			
			// unlock the mutex so we can call arbitrary code
			internal_lock.unlock();

			target->destroy();
			target->dealloc();
		}
		// otherwise we're supposed to cache the ref count deletion action.
		// this also implies we're in a collection action.
		else
		{
			assert(collector_thread != std::thread::id());

			ref_count_del_cache.insert(target);
		}
	}
}

// Assembly:
subq $0x58, %rsp
movq %rdx, (%rsp)
movq %rdi, 0x50(%rsp)
movq %rsi, 0x48(%rsp)
movq %rdx, 0x40(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, 0x48(%rsp)
je 0x7527
movq 0x48(%rsp), %rcx
movq 0x20(%rcx), %rax
addq $-0x1, %rax
movq %rax, 0x20(%rcx)
cmpq $0x0, %rax
jne 0x7527
movq 0x8(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
leaq 0x48(%rsp), %rsi
callq 0x9d20
movq 0x8(%rsp), %rdi
movq %rax, 0x38(%rsp)
addq $0x108, %rdi            # imm = 0x108
callq 0x9790
movq %rax, 0x30(%rsp)
leaq 0x38(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x97c0
testb $0x1, %al
jne 0x743e
jmp 0x7476
movq 0x8(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
leaq 0x48(%rsp), %rsi
callq 0x9a90
movq (%rsp), %rdi
callq 0x9d50
movq 0x48(%rsp), %rdi
callq 0x9a70
movq 0x48(%rsp), %rdi
callq 0x9ac0
jmp 0x7525
movq 0x8(%rsp), %rax
testb $0x1, 0xc8(%rax)
jne 0x74b6
movq 0x8(%rsp), %rdi
addq $0x38, %rdi
movq 0x48(%rsp), %rsi
callq 0x59f0
movq (%rsp), %rdi
callq 0x9d50
movq 0x48(%rsp), %rdi
callq 0x9a70
movq 0x48(%rsp), %rdi
callq 0x9ac0
jmp 0x7523
movq 0x8(%rsp), %rax
movq 0x28(%rax), %rax
movq %rax, 0x28(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x9620
movq 0x28(%rsp), %rdi
movq 0x20(%rsp), %rsi
callq 0x95e0
testb $0x1, %al
jne 0x74e3
jmp 0x74e5
jmp 0x7504
leaq 0x5cee5(%rip), %rdi     # 0x643d1
leaq 0x5cc6a(%rip), %rsi     # 0x6415d
movl $0x2d1, %edx            # imm = 0x2D1
leaq 0x5cef8(%rip), %rcx     # 0x643f7
callq 0x51e0
movq 0x8(%rsp), %rdi
addq $0xd0, %rdi
leaq 0x48(%rsp), %rsi
callq 0x9a20
movq %rax, 0x10(%rsp)
movb %dl, 0x18(%rsp)
jmp 0x7525
jmp 0x7527
addq $0x58, %rsp
retq
nopl (%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::schedule_handle_repoint_null(GC::smart_handle&)
void GC::disjoint_module::schedule_handle_repoint_null(smart_handle &handle)
{
	std::unique_lock<std::mutex> internal_lock(internal_mutex);

	// get the old target
	info *old_target = __get_current_target(handle);

	// repoint handle to null
	__raw_schedule_handle_repoint(handle, nullptr);

	// decrement old target reference count
	__MUST_BE_LAST_ref_count_dec(old_target, std::move(internal_lock));
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq 0x60(%rsp), %rsi
movq %rsi, 0x10(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x9b50
movq 0x10(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x7100
movq %rax, 0x18(%rsp)
jmp 0x75d8
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x58(%rsp), %rsi
xorl %eax, %eax
movl %eax, %edx
callq 0x7680
jmp 0x75f7
movq 0x40(%rsp), %rax
movq %rax, (%rsp)
leaq 0x20(%rsp), %rdi
movq %rdi, 0x8(%rsp)
leaq 0x48(%rsp), %rsi
callq 0x9bc0
movq 0x10(%rsp), %rdi
movq (%rsp), %rsi
movq 0x8(%rsp), %rdx
callq 0x73b0
jmp 0x7629
leaq 0x20(%rsp), %rdi
callq 0x9c00
leaq 0x48(%rsp), %rdi
callq 0x9c00
addq $0x68, %rsp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
jmp 0x766a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x9c00
leaq 0x48(%rsp), %rdi
callq 0x9c00
movq 0x38(%rsp), %rdi
callq 0x5510
nop
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::__raw_schedule_handle_repoint(GC::smart_handle&, GC::info*)
void GC::disjoint_module::__raw_schedule_handle_repoint(smart_handle &handle, info *target)
{
	// if there's no collector thread, we MUST apply the change immediately
	if (collector_thread == std::thread::id())
	{
		// if this branch was selected, the caches should be empty
		assert(handle_repoint_cache.empty());

		// immediately repoint handle to target
		handle.raw = target;
	}
	// otherwise we need to cache the request
	else handle_repoint_cache[&handle.raw] = target;
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movq %rdx, 0x30(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x28(%rax), %rax
movq %rax, 0x28(%rsp)
leaq 0x20(%rsp), %rdi
callq 0x9620
movq 0x28(%rsp), %rdi
movq 0x20(%rsp), %rsi
callq 0x9640
testb $0x1, %al
jne 0x76c5
jmp 0x770c
movq 0x10(%rsp), %rdi
addq $0x1b0, %rdi            # imm = 0x1B0
callq 0x96b0
testb $0x1, %al
jne 0x76dc
jmp 0x76de
jmp 0x76fd
leaq 0x5cae5(%rip), %rdi     # 0x641ca
leaq 0x5ca71(%rip), %rsi     # 0x6415d
movl $0x299, %edx            # imm = 0x299
leaq 0x5cc89(%rip), %rcx     # 0x64381
callq 0x51e0
movq 0x30(%rsp), %rcx
movq 0x38(%rsp), %rax
movq %rcx, (%rax)
jmp 0x773e
movq 0x10(%rsp), %rdi
movq 0x30(%rsp), %rax
movq %rax, 0x8(%rsp)
addq $0x1b0, %rdi            # imm = 0x1B0
movq 0x38(%rsp), %rax
movq %rax, 0x18(%rsp)
leaq 0x18(%rsp), %rsi
callq 0x9ca0
movq 0x8(%rsp), %rcx
movq %rcx, (%rax)
addq $0x48, %rsp
retq
nopw %cs:(%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::schedule_handle_repoint(GC::smart_handle&, GC::smart_handle const&)
void GC::disjoint_module::schedule_handle_repoint(smart_handle &handle, const smart_handle &new_value)
{
	std::unique_lock<std::mutex> internal_lock(internal_mutex);
	
	// get the old/new targets
	info *old_target = __get_current_target(handle);
	info *new_target = __get_current_target(new_value);

	#if DRAGAZO_GARBAGE_COLLECT_DISJUNCTION_SAFETY_CHECKS

	// if we're going to repoint outside the disjunction of the handle, that's a disjunction violation
	if (new_target && handle.disjunction != new_target->disjunction)
	{
		throw GC::disjunction_error("attempt to repoint GC::ptr outside of the current disjunction");
	}

	#endif

	// only do the remaining logic if it's an actual repoint
	if (old_target != new_target)
	{
		// repoint handle to the new target
		__raw_schedule_handle_repoint(handle, new_target);

		// increment new target reference count
		if (new_target) ++new_target->ref_count;

		// decrement old target reference count
		__MUST_BE_LAST_ref_count_dec(old_target, std::move(internal_lock));
	}
}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x80(%rsp)
movq %rsi, 0x78(%rsp)
movq %rdx, 0x70(%rsp)
movq 0x80(%rsp), %rsi
movq %rsi, 0x20(%rsp)
leaq 0x60(%rsp), %rdi
callq 0x9b50
movq 0x20(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x7100
movq %rax, 0x28(%rsp)
jmp 0x7796
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rax
movq %rax, 0x58(%rsp)
movq 0x70(%rsp), %rsi
callq 0x7100
movq %rax, 0x18(%rsp)
jmp 0x77b6
movq 0x18(%rsp), %rax
movq %rax, 0x40(%rsp)
cmpq $0x0, 0x40(%rsp)
je 0x7850
movq 0x78(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x40(%rsp), %rcx
cmpq 0x18(%rcx), %rax
je 0x7850
movl $0x10, %edi
callq 0x5160
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x10(%rsp)
leaq 0x5ca6e(%rip), %rsi     # 0x6426a
callq 0x9b00
jmp 0x7803
movq 0x10(%rsp), %rdi
leaq 0x91a49(%rip), %rsi     # 0x99258
leaq 0x232a(%rip), %rdx      # 0x9b40
callq 0x54d0
jmp 0x790d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
jmp 0x78f9
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
callq 0x5250
jmp 0x78f9
movq 0x58(%rsp), %rax
cmpq 0x40(%rsp), %rax
je 0x78e7
movq 0x20(%rsp), %rdi
movq 0x78(%rsp), %rsi
movq 0x40(%rsp), %rdx
callq 0x7680
jmp 0x7876
cmpq $0x0, 0x40(%rsp)
je 0x788f
movq 0x40(%rsp), %rax
movq 0x20(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x20(%rax)
movq 0x58(%rsp), %rax
movq %rax, (%rsp)
leaq 0x30(%rsp), %rdi
movq %rdi, 0x8(%rsp)
leaq 0x60(%rsp), %rsi
callq 0x9bc0
movq 0x20(%rsp), %rdi
movq (%rsp), %rsi
movq 0x8(%rsp), %rdx
callq 0x73b0
jmp 0x78c1
leaq 0x30(%rsp), %rdi
callq 0x9c00
jmp 0x78e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
leaq 0x30(%rsp), %rdi
callq 0x9c00
jmp 0x78f9
leaq 0x60(%rsp), %rdi
callq 0x9c00
addq $0x88, %rsp
retq
leaq 0x60(%rsp), %rdi
callq 0x9c00
movq 0x50(%rsp), %rdi
callq 0x5510
nopl (%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::schedule_handle_repoint_swap(GC::smart_handle&, GC::smart_handle&)
void GC::disjoint_module::schedule_handle_repoint_swap(smart_handle &handle_a, smart_handle &handle_b)
{
	std::lock_guard<std::mutex> internal_lock(internal_mutex);

	// get their current repoint targets
	info *target_a = __get_current_target(handle_a);
	info *target_b = __get_current_target(handle_b);

	#if DRAGAZO_GARBAGE_COLLECT_DISJUNCTION_SAFETY_CHECKS

	// if we're going to repoint outside the disjunction of either handle, that's a disjunction violation
	if ((target_b && handle_a.disjunction != target_b->disjunction) || (target_a && handle_b.disjunction != target_a->disjunction))
	{
		throw GC::disjunction_error("attempt to repoint GC::ptr outside of the current disjunction");
	}

	#endif

	// only perform the swap if they point to different things
	if (target_a != target_b)
	{
		// schedule repoint actions to swap them
		__raw_schedule_handle_repoint(handle_a, target_b);
		__raw_schedule_handle_repoint(handle_b, target_a);

		// there's no need for reference counting logic in a swap operation
	}
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq %rdx, 0x50(%rsp)
movq 0x60(%rsp), %rsi
movq %rsi, 0x18(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x95b0
movq 0x18(%rsp), %rdi
movq 0x58(%rsp), %rsi
callq 0x7100
movq %rax, 0x20(%rsp)
jmp 0x794d
movq 0x18(%rsp), %rdi
movq 0x20(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x50(%rsp), %rsi
callq 0x7100
movq %rax, 0x10(%rsp)
jmp 0x796d
movq 0x10(%rsp), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, 0x28(%rsp)
je 0x7993
movq 0x58(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x28(%rsp), %rcx
cmpq 0x18(%rcx), %rax
jne 0x79af
cmpq $0x0, 0x40(%rsp)
je 0x7a19
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x40(%rsp), %rcx
cmpq 0x18(%rcx), %rax
je 0x7a19
movl $0x10, %edi
callq 0x5160
movq %rax, %rdi
movq %rdi, %rax
movq %rax, 0x8(%rsp)
leaq 0x5c89f(%rip), %rsi     # 0x6426a
callq 0x9b00
jmp 0x79d2
movq 0x8(%rsp), %rdi
leaq 0x9187a(%rip), %rsi     # 0x99258
leaq 0x215b(%rip), %rdx      # 0x9b40
callq 0x54d0
jmp 0x7a76
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
jmp 0x7a62
movq 0x8(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
callq 0x5250
jmp 0x7a62
movq 0x40(%rsp), %rax
cmpq 0x28(%rsp), %rax
je 0x7a53
movq 0x18(%rsp), %rdi
movq 0x58(%rsp), %rsi
movq 0x28(%rsp), %rdx
callq 0x7680
jmp 0x7a3b
movq 0x18(%rsp), %rdi
movq 0x50(%rsp), %rsi
movq 0x40(%rsp), %rdx
callq 0x7680
jmp 0x7a51
jmp 0x7a53
leaq 0x48(%rsp), %rdi
callq 0x96d0
addq $0x68, %rsp
retq
leaq 0x48(%rsp), %rdi
callq 0x96d0
movq 0x38(%rsp), %rdi
callq 0x5510
nopw %cs:(%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module::local_handle()
GC::shared_disjoint_handle &GC::disjoint_module::local_handle()
{
	// thread_local because this is a thread-specific owning handle.
	// the default value points the current thread to use the primary disjunction.
	thread_local struct local_handle_t
	{
		shared_disjoint_handle m = primary_handle();

		#if DRAGAZO_GARBAGE_COLLECT_DISJUNCTION_HANDLE_LOGGING
		struct _
		{
			_() { std::cerr << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ctor local handle " << std::this_thread::get_id() << '\n'; }
			~_() { std::cerr << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dtor local handle " << std::this_thread::get_id() << '\n'; }
		} __;
		#endif
	} local_handle;

	#if DRAGAZO_GARBAGE_COLLECT_DISJUNCTION_HANDLE_LOGGING
	std::cerr << "                                ~~~~ local handle access " << std::this_thread::get_id() << '\n';
	#endif

	// if local detour is non-null it means we're in the static dtors (from primary() dtor handler), which means the thread_local handle has already been destroyed.
	// this would be und access of a destroyed object, but would theoretically only happen if a static dtor tried to make a thread for some reason.
	assert(local_detour == nullptr);

	return local_handle.m;
}

// Assembly:
pushq %rax
movb %fs:-0x58, %al
cmpb $0x0, %al
jne 0x7cb6
movq %fs:0x0, %rax
leaq -0x68(%rax), %rdi
movq %rdi, (%rsp)
callq 0x7d00
movq (%rsp), %rsi
leaq 0x8f(%rip), %rdi        # 0x7d30
leaq 0x92638(%rip), %rdx     # 0x9a2e0
callq 0x54f0
movb $0x1, %fs:-0x58
cmpq $0x0, 0x9266a(%rip)     # 0x9a328
jne 0x7cc2
jmp 0x7ce1
leaq 0x5c78b(%rip), %rdi     # 0x64454
leaq 0x5c48d(%rip), %rsi     # 0x6415d
movl $0x323, %edx            # imm = 0x323
leaq 0x5c790(%rip), %rcx     # 0x6446c
callq 0x51e0
movq %fs:0x0, %rax
leaq -0x68(%rax), %rax
popq %rcx
retq
nopw %cs:(%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::disjoint_module_container::create_new_disjunction(GC::shared_disjoint_handle&)
void GC::disjoint_module_container::create_new_disjunction(shared_disjoint_handle &dest)
{
	// create a new disjoint module handle data block
	auto m = std::make_unique<handle_data>();
	// and construct its module in-place
	new (m->get()) disjoint_module;

	// repoint dest to the new disjunction
	dest.reset(m.release());

	// add it to the disjunction database
	{
		std::lock_guard<std::mutex> internal_lock(internal_mutex);

		// if we're not collecting, we need to put it immediately in the disjunction list
		if (!collecting) disjunctions.emplace_back(dest);
		// otherwise we need to cache the add action
		else disjunction_add_cache.emplace_back(dest);
	}
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x30(%rsp), %rdi
movq %rdi, 0x10(%rsp)
callq 0x9db0
movq 0x10(%rsp), %rdi
callq 0x9e10
movq %rax, %rdi
callq 0x9e20
movq %rax, %rdi
callq 0x9e30
jmp 0x7dd3
movq 0x38(%rsp), %rax
movq %rax, (%rsp)
leaq 0x30(%rsp), %rdi
callq 0x9f40
movq (%rsp), %rdi
movq %rax, %rsi
callq 0x7ea0
jmp 0x7df4
movq 0x8(%rsp), %rsi
leaq 0x18(%rsp), %rdi
callq 0x95b0
jmp 0x7e05
movq 0x8(%rsp), %rax
testb $0x1, 0x28(%rax)
jne 0x7e51
movq 0x8(%rsp), %rdi
addq $0x30, %rdi
movq 0x38(%rsp), %rsi
callq 0x9f50
jmp 0x7e25
jmp 0x7e68
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
jmp 0x7e81
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x28(%rsp)
movl %eax, 0x24(%rsp)
leaq 0x18(%rsp), %rdi
callq 0x96d0
jmp 0x7e81
movq 0x8(%rsp), %rdi
addq $0x48, %rdi
movq 0x38(%rsp), %rsi
callq 0x9f50
jmp 0x7e66
jmp 0x7e68
leaq 0x18(%rsp), %rdi
callq 0x96d0
leaq 0x30(%rsp), %rdi
callq 0x9fa0
addq $0x48, %rsp
retq
leaq 0x30(%rsp), %rdi
callq 0x9fa0
movq 0x28(%rsp), %rdi
callq 0x5510
nopw %cs:(%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::shared_disjoint_handle::reset(GC::handle_data*)
void GC::shared_disjoint_handle::reset(handle_data *other)
{
	// handle redundant assignment as no-op
	if (data == other) return;

	// if we pointed at something
	if (data)
	{
		// drop a strong reference and get the previous tag
		auto prev = data->tag_sub(handle_data::strong_1, std::memory_order_acq_rel);

		// if we were the last strong reference, there are no longer any strong references - destroy the object
		// we include the lock strong refs because those locks succeeded - i.e. our very existence as a non-lock strong owner proves those locks succeeded.
		if ((prev & handle_data::strong_mask) == handle_data::strong_1)
		{
			__module->blocking_collect(); // perform one final collection to make sure everything's collected
			__module->~disjoint_module(); // then destroy the module itself - its dtor asserts that all objects were collected

			// if there were also no more weak references, delete the handle
			if ((prev & handle_data::weak_mask) == 0) delete data;
			// otherwise we're not deleting it but the weak ref count might have fallen to zero in the meantime and could be waiting - alert that we're done destroying
			else data->destroyed_flag.store(true, std::memory_order_release);
		}
	}

	// repoint and test for null - must come after destruction logic to ensure the collection can potentially alias this handle
	data = other;
	if (data)
	{
		__module = data->get(); // cache the module pointer
		data->tag_add(handle_data::strong_1, std::memory_order_acq_rel); // bump up the strong ref count
	}
	else __module = nullptr; // cache the module pointer (in this case null)
}

// Assembly:
subq $0x28, %rsp
movq %rdi, 0x20(%rsp)
movq %rsi, 0x18(%rsp)
movq 0x20(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rax), %rax
cmpq 0x18(%rsp), %rax
jne 0x7ec8
jmp 0x7fce
movq 0x8(%rsp), %rax
cmpq $0x0, 0x8(%rax)
je 0x7f7f
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rdi
movl $0x1, %esi
movl $0x4, %edx
callq 0x85c0
movq %rax, 0x10(%rsp)
movabsq $0xffffffffffffff, %rax # imm = 0xFFFFFFFFFFFFFF
andq 0x10(%rsp), %rax
cmpq $0x1, %rax
jne 0x7f7d
movq 0x8(%rsp), %rax
movq (%rax), %rdi
callq 0x6c50
movq 0x8(%rsp), %rax
movq (%rax), %rdi
callq 0x5bc0
movabsq $0xf00000000000000, %rax # imm = 0xF00000000000000
andq 0x10(%rsp), %rax
cmpq $0x0, %rax
jne 0x7f5c
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x7f5a
movq (%rsp), %rdi
movl $0x1f8, %esi            # imm = 0x1F8
callq 0x5310
jmp 0x7f7b
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rdi
addq $0x1f0, %rdi            # imm = 0x1F0
movl $0x1, %esi
movl $0x3, %edx
callq 0xa1e0
jmp 0x7f7d
jmp 0x7f7f
movq 0x8(%rsp), %rax
movq 0x18(%rsp), %rcx
movq %rcx, 0x8(%rax)
cmpq $0x0, 0x8(%rax)
je 0x7fc2
movq 0x8(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x9e20
movq %rax, %rcx
movq 0x8(%rsp), %rax
movq %rcx, (%rax)
movq 0x8(%rax), %rdi
movl $0x1, %esi
movl $0x4, %edx
callq 0x83f0
jmp 0x7fce
movq 0x8(%rsp), %rax
movq $0x0, (%rax)
addq $0x28, %rsp
retq
nopw %cs:(%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::weak_disjoint_handle::expired() const
bool GC::weak_disjoint_handle::expired() const noexcept
{
	// get the current tag
	auto tag = data ? data->tag.load(std::memory_order_acq_rel) : 0;

	// this weak ptr is expired if there are no strong refs remaining.
	// we include lock strong refs because otherwise it's possible for a series of atomic steps to result in a successful lock but intermediately no non-lock strong refs.
	// due to locking, however, this approach could report false negatives (but never false positives).
	return (tag & handle_data::strong_mask) == 0;
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x28(%rsp)
movq 0x28(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, (%rax)
je 0x83b6
movq 0x18(%rsp), %rax
movq (%rax), %rax
addq $0x1e8, %rax            # imm = 0x1E8
movq %rax, 0x40(%rsp)
movl $0x4, 0x3c(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x8(%rsp)
movl 0x3c(%rsp), %edi
movl $0xffff, %esi           # imm = 0xFFFF
callq 0xbaa0
movl %eax, 0x38(%rsp)
movl 0x3c(%rsp), %eax
movl %eax, 0x14(%rsp)
decl %eax
subl $0x2, %eax
jb 0x838f
jmp 0x8375
movl 0x14(%rsp), %eax
subl $0x5, %eax
je 0x839e
jmp 0x8380
movq 0x8(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x30(%rsp)
jmp 0x83ab
movq 0x8(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x30(%rsp)
jmp 0x83ab
movq 0x8(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
movq %rax, (%rsp)
jmp 0x83be
xorl %eax, %eax
movq %rax, (%rsp)
jmp 0x83be
movq (%rsp), %rax
movq %rax, 0x20(%rsp)
movabsq $0xffffffffffffff, %rax # imm = 0xFFFFFFFFFFFFFF
andq 0x20(%rsp), %rax
cmpq $0x0, %rax
sete %al
andb $0x1, %al
addq $0x48, %rsp
retq
nopw %cs:(%rax,%rax)
// File: dragazo[P]cpp-gc/GarbageCollection.cpp
// Function: GC::handle_data::tag_add(unsigned long, std::memory_order)
GC::handle_data::tag_t GC::handle_data::tag_add(tag_t v, std::memory_order order)
{
	const auto prev = tag.fetch_add(v, order);

	#if DRAGAZO_GARBAGE_COLLECT_DISJUNCTION_HANDLE_DATA_UND_SAFETY

	const auto cur = prev + v; // compute current value from previous

	// make sure we didn't overflow any of the fields
	assert((cur & strong_mask) >= (prev & strong_mask));
	assert((cur & weak_mask) >= (prev & weak_mask));
	assert((cur & lock_mask) >= (prev & lock_mask));

	#endif

	return prev;
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x38(%rsp)
movq %rsi, 0x30(%rsp)
movl %edx, 0x2c(%rsp)
movq 0x38(%rsp), %rdx
addq $0x1e8, %rdx            # imm = 0x1E8
movq 0x30(%rsp), %rcx
movl 0x2c(%rsp), %eax
movq %rdx, 0x60(%rsp)
movq %rcx, 0x58(%rsp)
movl %eax, 0x54(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x8(%rsp)
movl 0x54(%rsp), %eax
movq 0x58(%rsp), %rcx
movq %rcx, 0x48(%rsp)
decl %eax
movl %eax, %ecx
movq %rcx, 0x10(%rsp)
subl $0x4, %eax
ja 0x8460
movq 0x10(%rsp), %rax
leaq 0x5bbad(%rip), %rcx     # 0x64004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x8(%rsp), %rcx
movq 0x48(%rsp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, 0x40(%rsp)
jmp 0x84cc
movq 0x8(%rsp), %rcx
movq 0x48(%rsp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, 0x40(%rsp)
jmp 0x84cc
movq 0x8(%rsp), %rcx
movq 0x48(%rsp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, 0x40(%rsp)
jmp 0x84cc
movq 0x8(%rsp), %rcx
movq 0x48(%rsp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, 0x40(%rsp)
jmp 0x84cc
movq 0x8(%rsp), %rcx
movq 0x48(%rsp), %rax
lock
xaddq %rax, (%rcx)
movq %rax, 0x40(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rax
addq 0x30(%rsp), %rax
movq %rax, 0x18(%rsp)
movabsq $0xffffffffffffff, %rax # imm = 0xFFFFFFFFFFFFFF
andq 0x18(%rsp), %rax
movabsq $0xffffffffffffff, %rcx # imm = 0xFFFFFFFFFFFFFF
andq 0x20(%rsp), %rcx
cmpq %rcx, %rax
jb 0x850a
jmp 0x8529
leaq 0x5c01a(%rip), %rdi     # 0x6452b
leaq 0x5bc45(%rip), %rsi     # 0x6415d
movl $0x39b, %edx            # imm = 0x39B
leaq 0x5c033(%rip), %rcx     # 0x64557
callq 0x51e0
movabsq $0xf00000000000000, %rax # imm = 0xF00000000000000
andq 0x18(%rsp), %rax
movabsq $0xf00000000000000, %rcx # imm = 0xF00000000000000
andq 0x20(%rsp), %rcx
cmpq %rcx, %rax
jb 0x854e
jmp 0x856d
leaq 0x5c04c(%rip), %rdi     # 0x645a1
leaq 0x5bc01(%rip), %rsi     # 0x6415d
movl $0x39c, %edx            # imm = 0x39C
leaq 0x5bfef(%rip), %rcx     # 0x64557
callq 0x51e0
movabsq $-0x1000000000000000, %rax # imm = 0xF000000000000000
andq 0x18(%rsp), %rax
movabsq $-0x1000000000000000, %rcx # imm = 0xF000000000000000
andq 0x20(%rsp), %rcx
cmpq %rcx, %rax
jb 0x8592
jmp 0x85b1
leaq 0x5c030(%rip), %rdi     # 0x645c9
leaq 0x5bbbd(%rip), %rsi     # 0x6415d
movl $0x39d, %edx            # imm = 0x39D
leaq 0x5bfab(%rip), %rcx     # 0x64557
callq 0x51e0
movq 0x20(%rsp), %rax
addq $0x68, %rsp
retq
nopl (%rax,%rax)