// File: wichtounet[P]articles/plf_colony_alpha/plf_colony.h
// Function: plf::colony<Trivial<8>, std::allocator<Trivial<8>>, unsigned short>::consolidate_erased_locations(plf::colony<Trivial<8>, std::allocator<Trivial<8>>, unsigned short>::group*)
void consolidate_erased_locations(const group_pointer_type the_group_pointer)
	{
		// Function: Remove all entries in the stack containing memory locations from the supplied colony group, and incidentally remove unused trailing groups from the stack.

		// Process explanation:
		// First, remove any trailing unused groups from the stack. These may be present if a stack has pushed then popped a lot, as plf::stack never deallocates.
		// If there're no pointers to memory locations from the supplied colony group within stack groups, preserve those particular stack groups with no alterations in the new chain.
		// If there are pointers to memory locations from the supplied colony group in any stack group, copy these locations to the new stack group and remove the old group.
		// If a stack group is at the end of the old stack but is partial, and there have been some copies of memory locations made from old groups (see sentence immediately above this one), copy the locations from this group to the new group and remove it (otherwise you would end up with two partially-full groups at the end of the new chain - a new partially-full group following a partially-full old group). If there're no copies of memory locations (just old groups), then preserve the old end group.
		// At the end, if the new group has copies in it, add it to the new chain. Alternatively if the stack is now empty, reinitialize it. Or if there're no old groups remaining make the new group the first group. Or if there are only old groups, link the new chain (of old groups) into the stack.
		// Complicated but faster than any other alternative.

		typedef typename reduced_stack::stack_group_pointer_type stack_group_pointer;
		typedef typename reduced_stack::stack_element_pointer_type stack_element_pointer;

		#ifdef PLF_COLONY_ALLOCATOR_TRAITS_SUPPORT
			typedef typename reduced_stack::stack_group_allocator_type stack_group_allocator_type; // Not used by PLF_COLONY_DESTROY etc when std::allocator_traits not supported
		#endif

		// Remove trailing stack groups (not removed in general 'pop' usage in reduced_stack for performance reasons)
		{
			stack_group_pointer temp_group = erased_locations.current_group->next_group, temp_group2;
			erased_locations.current_group->next_group = NULL; // Set to NULL regardless of whether it is already NULL (avoids branching). Cuts off rest of groups from this group.

			while (temp_group != NULL)
			{
				temp_group2 = temp_group;
				temp_group = temp_group->next_group;
				PLF_COLONY_DESTROY(stack_group_allocator_type, erased_locations.group_allocator_pair, temp_group2);
				PLF_COLONY_DEALLOCATE(stack_group_allocator_type, erased_locations.group_allocator_pair, temp_group2, 1);
			}
		}

		// Determine what the size of the first new group in erased_locations should be, based on the size of the first colony group:
		const size_type temp_size = (min_elements_per_group < 8) ? min_elements_per_group : (min_elements_per_group >> 7) + 8;

		// Note: All groups from here onwards refer to erased_location's stack groups, not colony groups, unless stated otherwise

		// Use either the size determined above or the current total number of elements in stack as an estimate of how large the first group in it should be:
		// The current total number of elements in the stack is a good estimate for how large it might become in future, but if it's smaller than the first_group determination, we should probably use the first_group determination.
		const size_type new_group_size = (erased_locations.total_number_of_elements < temp_size) ? temp_size : erased_locations.total_number_of_elements;

		stack_group_pointer current_old_group = erased_locations.first_group,
							new_group = PLF_COLONY_ALLOCATE(stack_group_allocator_type, erased_locations.group_allocator_pair, 1, erased_locations.current_group),
							first_new_chain = NULL,
							current_new_chain = NULL;

		try
		{
			#ifdef PLF_COLONY_VARIADICS_SUPPORT
				PLF_COLONY_CONSTRUCT(stack_group_allocator_type, erased_locations.group_allocator_pair, new_group, new_group_size, erased_locations.current_group);
			#else
				PLF_COLONY_CONSTRUCT(stack_group_allocator_type, erased_locations.group_allocator_pair, new_group, typename reduced_stack::group(new_group_size, erased_locations.current_group));
			#endif
		}
		catch (...)
		{
			PLF_COLONY_DEALLOCATE(stack_group_allocator_type, erased_locations.group_allocator_pair, new_group, 1);
			throw;
		}


		stack_element_pointer iterator_pointer, source_end, destination_begin = new_group->elements, the_end = NULL;
		const stack_element_pointer destination_start = destination_begin;
		const element_pointer_type group_elements_start = the_group_pointer->elements, group_elements_end = reinterpret_cast<element_pointer_type>(the_group_pointer->skipfield);
		size_type total_number_of_copies = 0, number_to_be_copied = 0;

		do // per old group of stack
		{
			if (current_old_group->next_group != NULL)
			{
				source_end = current_old_group->end + 1;
			}
			else
			{
				source_end = erased_locations.top_element + 1;
			}

			iterator_pointer = current_old_group->elements;
			const size_type number_of_group_elements = static_cast<const size_type>(source_end - iterator_pointer);

			for (; iterator_pointer != source_end; ++iterator_pointer) // per old group element
			{
				if (*iterator_pointer < group_elements_start || *iterator_pointer >= group_elements_end) // ie. this stack element doesn't match the skipfield)) // ie. this stack element doesn't match the group pointer, doesn't need to be removed
				{
					++number_to_be_copied;
				}
				else if (number_to_be_copied != 0) // Indicates a break in a run of elements matching the group_pointer, so copy time:
				{
					// Use the fastest method for moving iterators, while perserving values if allocator provides non-trivial pointers - unused if/else branches will be optimised out by any decent compiler:
					#ifdef PLF_COLONY_TYPE_TRAITS_SUPPORT
						if (std::is_trivially_copyable<element_pointer_type>::value && std::is_trivially_destructible<element_pointer_type>::value) // Avoid iteration for trivially-destructible iterators ie. all iterators, unless allocator returns non-trivial pointers
						{
							std::memcpy(&*destination_begin, &*(iterator_pointer - number_to_be_copied), number_to_be_copied * sizeof(element_pointer_type)); // &* to avoid problems with non-trivial pointers that are trivially-copyable
						}
						#ifdef PLF_COLONY_MOVE_SEMANTICS_SUPPORT
							else if (std::is_move_constructible<element_pointer_type>::value)
							{
								std::uninitialized_copy(std::make_move_iterator(iterator_pointer - number_to_be_copied), std::make_move_iterator(iterator_pointer), destination_begin);
							}
						#endif
						else
					#endif
					{
						std::uninitialized_copy(iterator_pointer - number_to_be_copied, iterator_pointer, destination_begin);

						// The following loop is necessary because the allocator may return non-trivially-destructible pointer types, making iterator a non-trivially-destructible type:
						for (stack_element_pointer element_pointer = iterator_pointer - number_to_be_copied; element_pointer != iterator_pointer; ++element_pointer)
						{
							PLF_COLONY_DESTROY(element_pointer_allocator_type, erased_locations, element_pointer);
						}
					}

					destination_begin += number_to_be_copied;
					total_number_of_copies += number_to_be_copied;
					number_to_be_copied = 0;
				}
			}

			const bool test = (number_to_be_copied == static_cast<const size_type>((current_old_group->end + 1) - current_old_group->elements));

			if (test || (number_to_be_copied == number_of_group_elements && destination_begin == destination_start))
			{
				if (test)
				{
					the_end = current_old_group->end;
				}
				else
				{
					the_end = source_end - 1;
				}

				// No deletions, preserve group
				if (current_new_chain == NULL)
				{
					// First in chain
					current_new_chain = first_new_chain = current_old_group;
					current_old_group->previous_group = NULL;
				}
				else
				{
					// Add to chain
					current_new_chain->next_group = current_old_group;
					current_old_group->previous_group = current_new_chain;
					current_new_chain = current_old_group;
				}

				total_number_of_copies += number_to_be_copied;
				number_to_be_copied = 0;
				current_old_group = current_old_group->next_group;
			}
			else
			{
				if (number_to_be_copied != 0)
				{
					// move remainder:
					#ifdef PLF_COLONY_TYPE_TRAITS_SUPPORT
						if (std::is_trivially_copyable<element_pointer_type>::value && std::is_trivially_destructible<element_pointer_type>::value)
						{ // Dereferencing here in order to deal with smart pointer situations ie. obtaining the raw pointer from the smart pointer
							std::memcpy(&*destination_begin, &*(iterator_pointer - number_to_be_copied), number_to_be_copied * sizeof(element_pointer_type));
						}
						#ifdef PLF_COLONY_MOVE_SEMANTICS_SUPPORT
							else if (std::is_move_constructible<element_pointer_type>::value)
							{
								std::uninitialized_copy(std::make_move_iterator(iterator_pointer - number_to_be_copied), std::make_move_iterator(iterator_pointer), destination_begin);
							}
						#endif
						else
					#endif
					{
						std::uninitialized_copy(iterator_pointer - number_to_be_copied, iterator_pointer, destination_begin);

						// The following loop is necessary because the allocator may return non-trivially-destructible pointer types, making iterator a non-trivially-destructible type:
						for (stack_element_pointer element_pointer = iterator_pointer - number_to_be_copied; element_pointer != iterator_pointer; ++element_pointer)
						{
							PLF_COLONY_DESTROY(element_pointer_allocator_type, erased_locations, element_pointer);
						}
					}

					destination_begin += number_to_be_copied;
					total_number_of_copies += number_to_be_copied;
					number_to_be_copied = 0;
				}

				// Remove old group:
				const stack_group_pointer prev_group = current_old_group;
				current_old_group = current_old_group->next_group;
				PLF_COLONY_DESTROY(stack_group_allocator_type, erased_locations.group_allocator_pair, prev_group);
				PLF_COLONY_DEALLOCATE(stack_group_allocator_type, erased_locations.group_allocator_pair, prev_group, 1);
			}
		} while (current_old_group != NULL);


		switch((current_new_chain != NULL) | ((destination_begin == destination_start) << 1))
		{
			case 0: // if (current_new_chain == NULL && destination_begin != destination_start) - No old groups remaining, some copies
			{
				new_group->previous_group = NULL;
				erased_locations.first_group = erased_locations.current_group = new_group;
				erased_locations.top_element = destination_begin - 1;
				erased_locations.start_element = new_group->elements;
				erased_locations.end_element = new_group->end;
				erased_locations.total_number_of_elements = total_number_of_copies;
				break;
			}
			case 1: // else if (current_new_chain != NULL && destination_begin != destination_start) - Some deletions occured ie. some elements copied, some old groups remaining - current_new_chain != NULL implied by previous if
			{
				new_group->previous_group = current_new_chain;
				erased_locations.current_group = current_new_chain->next_group = new_group;
				erased_locations.first_group = first_new_chain;
				erased_locations.top_element = destination_begin - 1;
				erased_locations.start_element = new_group->elements;
				erased_locations.end_element = new_group->end;
				erased_locations.total_number_of_elements = total_number_of_copies;
				break;
			}
			case 3: // else if (current_new_chain != NULL && destination_begin == destination_start) - No copies, some old groups - destination_begin == destination_start implied by previous if's
			{
				PLF_COLONY_DESTROY(stack_group_allocator_type, erased_locations.group_allocator_pair, new_group);
				PLF_COLONY_DEALLOCATE(stack_group_allocator_type, erased_locations.group_allocator_pair, new_group, 1);

				current_new_chain->next_group = NULL;
				erased_locations.current_group = current_new_chain;
				erased_locations.first_group = first_new_chain;
				erased_locations.top_element = the_end;
				erased_locations.start_element = current_new_chain->elements;
				erased_locations.end_element = current_new_chain->end;
				erased_locations.total_number_of_elements = total_number_of_copies;
				break;
			}
			default: // else (current_new_chain == NULL && destination_begin == destination_start) - No elements remaining - least likely
			{
				// Instead of removing the newly-constructed group and returning to zero,
				// we bank on the idea that if an element has been removed, more elements are likely to be removed later, and so keep the group rather than deleting it.

				erased_locations.current_group = new_group;
				erased_locations.first_group = new_group;
				erased_locations.top_element = new_group->elements - 1;
				erased_locations.start_element = new_group->elements;
				erased_locations.end_element = new_group->end;
				erased_locations.total_number_of_elements = 0;
				break;
			}
		}
	}

// Assembly:
subq $0xf8, %rsp
movq %rdi, 0xf0(%rsp)
movq %rsi, 0xe8(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0x48(%rax), %rcx
movq 0x8(%rcx), %rcx
movq %rcx, 0xe0(%rsp)
movq 0x48(%rax), %rax
movq $0x0, 0x8(%rax)
cmpq $0x0, 0xe0(%rsp)
je 0xad32a
movq 0x30(%rsp), %rdi
movq 0xe0(%rsp), %rax
movq %rax, 0xd8(%rsp)
movq 0xe0(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0xe0(%rsp)
addq $0x48, %rdi
addq $0x30, %rdi
movq 0xd8(%rsp), %rsi
callq 0x17ab0
movq 0x30(%rsp), %rdi
addq $0x48, %rdi
addq $0x30, %rdi
movq 0xd8(%rsp), %rsi
movl $0x1, %edx
callq 0x17ae0
jmp 0xad2c0
movq 0x30(%rsp), %rax
movzwl 0x40(%rax), %eax
cmpl $0x8, %eax
jge 0xad347
movq 0x30(%rsp), %rax
movzwl 0x40(%rax), %eax
movl %eax, 0x2c(%rsp)
jmp 0xad35a
movq 0x30(%rsp), %rax
movzwl 0x40(%rax), %eax
sarl $0x7, %eax
addl $0x8, %eax
movl %eax, 0x2c(%rsp)
movq 0x30(%rsp), %rax
movl 0x2c(%rsp), %ecx
movslq %ecx, %rcx
movq %rcx, 0xd0(%rsp)
movq 0x70(%rax), %rax
cmpq 0xd0(%rsp), %rax
jae 0xad38b
movq 0xd0(%rsp), %rax
movq %rax, 0x20(%rsp)
jmp 0xad399
movq 0x30(%rsp), %rax
movq 0x70(%rax), %rax
movq %rax, 0x20(%rsp)
movq 0x30(%rsp), %rax
movq 0x20(%rsp), %rcx
movq %rcx, 0xc8(%rsp)
movq %rax, %rcx
addq $0x48, %rcx
movq %rcx, 0x18(%rsp)
movq 0x50(%rax), %rcx
movq %rcx, 0xc0(%rsp)
movq %rax, %rdi
addq $0x78, %rdi
movq %rdi, 0x10(%rsp)
movq 0x48(%rax), %rdx
movl $0x1, %esi
callq 0xada80
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rcx
movq %rax, 0xb8(%rsp)
movq $0x0, 0xb0(%rsp)
movq $0x0, 0xa8(%rsp)
movq 0xb8(%rsp), %rsi
leaq 0xc8(%rsp), %rdx
callq 0xade20
jmp 0xad41e
jmp 0xad488
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xa0(%rsp)
movl %eax, 0x9c(%rsp)
movq 0xa0(%rsp), %rdi
callq 0x50b0
movq 0x30(%rsp), %rdi
addq $0x78, %rdi
movq 0xb8(%rsp), %rsi
movl $0x1, %edx
callq 0x17ae0
jmp 0xad45e
callq 0x52d0
jmp 0xada47
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xa0(%rsp)
movl %eax, 0x9c(%rsp)
callq 0x5350
jmp 0xad483
jmp 0xada32
movq 0xb8(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x80(%rsp)
movq $0x0, 0x78(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0xe8(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x68(%rsp)
movq 0xe8(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x60(%rsp)
movq $0x0, 0x58(%rsp)
movq $0x0, 0x50(%rsp)
movq 0xc0(%rsp), %rax
cmpq $0x0, 0x8(%rax)
je 0xad50e
movq 0xc0(%rsp), %rax
movq 0x18(%rax), %rax
addq $0x8, %rax
movq %rax, 0x88(%rsp)
jmp 0xad523
movq 0x30(%rsp), %rax
movq 0x58(%rax), %rax
addq $0x8, %rax
movq %rax, 0x88(%rsp)
movq 0xc0(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x90(%rsp)
movq 0x88(%rsp), %rax
movq 0x90(%rsp), %rcx
subq %rcx, %rax
sarq $0x3, %rax
movq %rax, 0x48(%rsp)
movq 0x90(%rsp), %rax
cmpq 0x88(%rsp), %rax
je 0xad61e
movq 0x90(%rsp), %rax
movq (%rax), %rax
cmpq 0x68(%rsp), %rax
jb 0xad58c
movq 0x90(%rsp), %rax
movq (%rax), %rax
cmpq 0x60(%rsp), %rax
jb 0xad59c
movq 0x50(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x50(%rsp)
jmp 0xad603
cmpq $0x0, 0x50(%rsp)
je 0xad601
movq 0x80(%rsp), %rdi
movq 0x90(%rsp), %rsi
xorl %eax, %eax
subq 0x50(%rsp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq 0x50(%rsp), %rdx
shlq $0x3, %rdx
callq 0x51a0
movq 0x50(%rsp), %rax
shlq $0x3, %rax
addq 0x80(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x50(%rsp), %rax
addq 0x58(%rsp), %rax
movq %rax, 0x58(%rsp)
movq $0x0, 0x50(%rsp)
jmp 0xad603
jmp 0xad605
movq 0x90(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x90(%rsp)
jmp 0xad552
movq 0x50(%rsp), %rax
movq 0xc0(%rsp), %rcx
movq 0x18(%rcx), %rcx
addq $0x8, %rcx
movq 0xc0(%rsp), %rdx
movq (%rdx), %rdx
subq %rdx, %rcx
sarq $0x3, %rcx
cmpq %rcx, %rax
sete %al
andb $0x1, %al
movb %al, 0x47(%rsp)
testb $0x1, 0x47(%rsp)
jne 0xad67b
movq 0x50(%rsp), %rax
cmpq 0x48(%rsp), %rax
jne 0xad744
movq 0x80(%rsp), %rax
cmpq 0x70(%rsp), %rax
jne 0xad744
testb $0x1, 0x47(%rsp)
je 0xad695
movq 0xc0(%rsp), %rax
movq 0x18(%rax), %rax
movq %rax, 0x78(%rsp)
jmp 0xad6a6
movq 0x88(%rsp), %rax
addq $-0x8, %rax
movq %rax, 0x78(%rsp)
cmpq $0x0, 0xa8(%rsp)
jne 0xad6db
movq 0xc0(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq %rax, 0xa8(%rsp)
movq 0xc0(%rsp), %rax
movq $0x0, 0x10(%rax)
jmp 0xad713
movq 0xc0(%rsp), %rcx
movq 0xa8(%rsp), %rax
movq %rcx, 0x8(%rax)
movq 0xa8(%rsp), %rcx
movq 0xc0(%rsp), %rax
movq %rcx, 0x10(%rax)
movq 0xc0(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq 0x50(%rsp), %rax
addq 0x58(%rsp), %rax
movq %rax, 0x58(%rsp)
movq $0x0, 0x50(%rsp)
movq 0xc0(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0xc0(%rsp)
jmp 0xad7fd
cmpq $0x0, 0x50(%rsp)
je 0xad7a9
movq 0x80(%rsp), %rdi
movq 0x90(%rsp), %rsi
xorl %eax, %eax
subq 0x50(%rsp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq 0x50(%rsp), %rdx
shlq $0x3, %rdx
callq 0x51a0
movq 0x50(%rsp), %rax
shlq $0x3, %rax
addq 0x80(%rsp), %rax
movq %rax, 0x80(%rsp)
movq 0x50(%rsp), %rax
addq 0x58(%rsp), %rax
movq %rax, 0x58(%rsp)
movq $0x0, 0x50(%rsp)
movq 0x30(%rsp), %rdi
movq 0xc0(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0xc0(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0xc0(%rsp)
addq $0x48, %rdi
addq $0x30, %rdi
movq 0x38(%rsp), %rsi
callq 0x17ab0
movq 0x30(%rsp), %rdi
addq $0x48, %rdi
addq $0x30, %rdi
movq 0x38(%rsp), %rsi
movl $0x1, %edx
callq 0x17ae0
jmp 0xad7ff
cmpq $0x0, 0xc0(%rsp)
jne 0xad4e5
movq 0xa8(%rsp), %rax
testq %rax, %rax
setne %al
movzbl %al, %eax
movq 0x80(%rsp), %rcx
movq 0x70(%rsp), %rdx
subq %rdx, %rcx
sete %cl
movzbl %cl, %ecx
addl %ecx, %ecx
orl %ecx, %eax
movl %eax, 0xc(%rsp)
je 0xad85e
jmp 0xad841
movl 0xc(%rsp), %eax
subl $0x1, %eax
je 0xad8c0
jmp 0xad84c
movl 0xc(%rsp), %eax
subl $0x3, %eax
je 0xad93a
jmp 0xad9d3
movq 0x30(%rsp), %rax
movq 0xb8(%rsp), %rcx
movq $0x0, 0x10(%rcx)
movq 0xb8(%rsp), %rcx
movq %rcx, 0x48(%rax)
movq %rcx, 0x50(%rax)
movq 0x80(%rsp), %rcx
addq $-0x8, %rcx
movq %rcx, 0x58(%rax)
movq 0xb8(%rsp), %rcx
movq (%rcx), %rcx
movq %rcx, 0x60(%rax)
movq 0xb8(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq %rcx, 0x68(%rax)
movq 0x58(%rsp), %rcx
movq %rcx, 0x70(%rax)
jmp 0xada2a
movq 0x30(%rsp), %rax
movq 0xa8(%rsp), %rdx
movq 0xb8(%rsp), %rcx
movq %rdx, 0x10(%rcx)
movq 0xb8(%rsp), %rcx
movq 0xa8(%rsp), %rdx
movq %rcx, 0x8(%rdx)
movq %rcx, 0x48(%rax)
movq 0xb0(%rsp), %rcx
movq %rcx, 0x50(%rax)
movq 0x80(%rsp), %rcx
addq $-0x8, %rcx
movq %rcx, 0x58(%rax)
movq 0xb8(%rsp), %rcx
movq (%rcx), %rcx
movq %rcx, 0x60(%rax)
movq 0xb8(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq %rcx, 0x68(%rax)
movq 0x58(%rsp), %rcx
movq %rcx, 0x70(%rax)
jmp 0xada2a
movq 0x30(%rsp), %rdi
addq $0x48, %rdi
addq $0x30, %rdi
movq 0xb8(%rsp), %rsi
callq 0x17ab0
movq 0x30(%rsp), %rdi
addq $0x48, %rdi
addq $0x30, %rdi
movq 0xb8(%rsp), %rsi
movl $0x1, %edx
callq 0x17ae0
movq 0x30(%rsp), %rax
movq 0xa8(%rsp), %rcx
movq $0x0, 0x8(%rcx)
movq 0xa8(%rsp), %rcx
movq %rcx, 0x48(%rax)
movq 0xb0(%rsp), %rcx
movq %rcx, 0x50(%rax)
movq 0x78(%rsp), %rcx
movq %rcx, 0x58(%rax)
movq 0xa8(%rsp), %rcx
movq (%rcx), %rcx
movq %rcx, 0x60(%rax)
movq 0xa8(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq %rcx, 0x68(%rax)
movq 0x58(%rsp), %rcx
movq %rcx, 0x70(%rax)
jmp 0xada2a
movq 0x30(%rsp), %rax
movq 0xb8(%rsp), %rcx
movq %rcx, 0x48(%rax)
movq 0xb8(%rsp), %rcx
movq %rcx, 0x50(%rax)
movq 0xb8(%rsp), %rcx
movq (%rcx), %rcx
addq $-0x8, %rcx
movq %rcx, 0x58(%rax)
movq 0xb8(%rsp), %rcx
movq (%rcx), %rcx
movq %rcx, 0x60(%rax)
movq 0xb8(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq %rcx, 0x68(%rax)
movq $0x0, 0x70(%rax)
addq $0xf8, %rsp
retq
movq 0xa0(%rsp), %rdi
callq 0x5360
movq %rax, %rdi
callq 0x14670
nopw (%rax,%rax)