// File: UTSASRG[P]Guarder/./bibopheap.hh
// Function: BibopHeap::BibopObjCache::getRandomObject(bool)
uintptr_t getRandomObject(bool doReplacement = false) {
					unsigned index;
					//unsigned numTries = 1;
					void * object;

					// Obtain a random number between [0, opts.bibop_cache_size)
					index = getRandomNumber() & BIBOP_CACHE_SIZE_MASK;
					object = _objects[index];

					PRDBG("trying object %p at index %d...", object, index);
					// Find the next sequential cache region with objects available for use
					if(!object) {
							int i;
							unsigned cacheRegionNumber = index >> CACHE_REGION_SIZE_SHIFT_BITS;
							unsigned tryRegionNumber;

							PRDBG(" ... didn't work, current region = %d, searching regions...", cacheRegionNumber);
							for(i = cacheRegionNumber; i < cacheRegionNumber + NUM_CACHE_REGIONS; i++) {
									tryRegionNumber = i & NUM_CACHE_REGIONS_MASK;
									//numTries++;
									if(_regionCounters[tryRegionNumber] == UNINITIALIZED_CACHE_REGION) {
											initialPopulate();
											break;
									} else if(_regionCounters[tryRegionNumber] > 0) {
											PRDBG(" ... using region = %d, has %d objects", tryRegionNumber, _regionCounters[tryRegionNumber]);
											break;
									} else {
											PRDBG(" ... region %d has no objects, moving on...", tryRegionNumber);
									}
							}

							// Attempt to use a "random" object from this region
							// (add +1 to index in order to avoid rehecking the same object if the
							// same cache region is chosen by the for-loop above).
							index = (tryRegionNumber << CACHE_REGION_SIZE_SHIFT_BITS) + ((index + 1) & CACHE_REGION_SIZE_MASK);
							object = _objects[index];
							PRDBG("	...trying first object (%p) in region %d, has index %d...", object, tryRegionNumber, index);

							// Now walk through the region's objects to find an available one
							// (that is, if the first object is unavailable)...
							//numTries++;
							while(!object) {
									PRDBG("cache conflict on index %u (object = %p, num used=%d); trying next item...",
													index, object, _numUsedObjects);

									// Try the next adjacent index, wrapping around if necessary...
									index++;
									if((index & CACHE_REGION_SIZE_MASK) == 0) {
											index = tryRegionNumber << CACHE_REGION_SIZE_SHIFT_BITS;
									}

									object = _objects[index];
									//numTries++;
							}
					}
					unsigned currentRegion = index >> CACHE_REGION_SIZE_SHIFT_BITS;
					//PRINT("numTries %u numAvailObjs %u curRegion %d regionObjects %d",
					//				numTries, (BibopHeap::_cacheSize - _numUsedObjects), currentRegion, _regionCounters[currentRegion]);

					// If desired, we will replace the randomly selected object with a
					// fresh object from the free cache, if one is available to use.
					if(doReplacement && (_freeCache->getNumObjects() > 0)) {
							PRDBG("freecache has free objects, doing replacement of cache index %u", index);
							_objects[index] = _freeCache->getNext();
					} else {
							// mark the object as NULL in _objects array to indicate
							// it is no longer available
							PRDBG("writing NULL to used cache index: cache @ %p, entry @ %p equals %p; index=%u",
											_objects, &_objects[index], _objects[index], index);
							_objects[index] = NULL;
							_numUsedObjects++;
							
							PRDBG("_regionCounters[%d]-- (index = %d)", currentRegion, index);
							_regionCounters[currentRegion]--;
							assert(_regionCounters[currentRegion] >= 0);
					}

					PRDBG("getRandomObject() returning %p", object);
					return (uintptr_t)object;
			}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
subq $0xf8, %rsp
movb %sil, %al
movq %rdi, -0x10(%rbp)
andb $0x1, %al
movb %al, -0x11(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x48(%rbp)
callq 0x5520
movl %eax, %ecx
movq -0x48(%rbp), %rax
movq 0x6ce6(%rip), %rdx      # 0x10f18
movl 0x8(%rdx), %edx
subl $0x1, %edx
andl %edx, %ecx
movl %ecx, -0x18(%rbp)
movq 0x58(%rax), %rax
movl -0x18(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
callq 0x52d0
movq %rax, -0x40(%rbp)
callq 0x5400
movq -0x40(%rbp), %rdi
movq %rax, %rcx
movq -0x20(%rbp), %r10
movl -0x18(%rbp), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2d6b(%rip), %rdx      # 0xcfdf
leaq 0x22e7(%rip), %r8       # 0xc562
movl $0x25c, %r9d            # imm = 0x25C
movq %r10, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x38(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x38(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
cmpq $0x0, -0x20(%rbp)
jne 0xa65e
movl -0x18(%rbp), %eax
movq 0x6c4c(%rip), %rcx      # 0x10f18
movl 0x8(%rcx), %ecx
shrl $0x3, %ecx
movl %ecx, %ecx
bsrq %rcx, %rcx
xorq $0x3f, %rcx
movslq %ecx, %rdx
movl $0x40, %ecx
subq %rdx, %rcx
subq $0x1, %rcx
shrl %cl, %eax
movl %eax, -0x28(%rbp)
callq 0x52d0
movq %rax, -0x58(%rbp)
callq 0x5400
movq -0x58(%rbp), %rdi
movq %rax, %rcx
movl -0x28(%rbp), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2d0b(%rip), %rdx      # 0xd01f
leaq 0x2247(%rip), %r8       # 0xc562
movl $0x263, %r9d            # imm = 0x263
movl %eax, (%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x50(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x50(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movl -0x28(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl -0x28(%rbp), %ecx
addl $0x8, %ecx
cmpl %ecx, %eax
jae 0xa485
movq -0x48(%rbp), %rax
movl -0x24(%rbp), %ecx
andl $0x7, %ecx
movl %ecx, -0x2c(%rbp)
movl -0x2c(%rbp), %ecx
cmpl $-0x1, 0x34(%rax,%rcx,4)
jne 0xa38e
movq -0x48(%rbp), %rdi
callq 0x5760
jmp 0xa485
movq -0x48(%rbp), %rax
movl -0x2c(%rbp), %ecx
cmpl $0x0, 0x34(%rax,%rcx,4)
jbe 0xa411
callq 0x52d0
movq %rax, -0x68(%rbp)
callq 0x5400
movq -0x68(%rbp), %rdi
movq %rax, %rcx
movq -0x48(%rbp), %rax
movl -0x2c(%rbp), %r10d
movl -0x2c(%rbp), %edx
movl 0x34(%rax,%rdx,4), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2caf(%rip), %rdx      # 0xd07b
leaq 0x218f(%rip), %r8       # 0xc562
movl $0x26b, %r9d            # imm = 0x26B
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x60(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x60(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
jmp 0xa485
callq 0x52d0
movq %rax, -0x78(%rbp)
callq 0x5400
movq -0x78(%rbp), %rdi
movq %rax, %rcx
movl -0x2c(%rbp), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2c8d(%rip), %rdx      # 0xd0c2
leaq 0x2126(%rip), %r8       # 0xc562
movl $0x26e, %r9d            # imm = 0x26E
movl %eax, (%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x70(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x70(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
jmp 0xa475
jmp 0xa477
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0xa358
movq -0x48(%rbp), %rax
movl -0x2c(%rbp), %edx
movq 0x6a85(%rip), %rcx      # 0x10f18
movl 0x8(%rcx), %ecx
shrl $0x3, %ecx
movl %ecx, %ecx
bsrq %rcx, %rcx
xorq $0x3f, %rcx
movslq %ecx, %rsi
movl $0x40, %ecx
subq %rsi, %rcx
subq $0x1, %rcx
shll %cl, %edx
movl %edx, %ecx
movl -0x18(%rbp), %edx
addl $0x1, %edx
movq 0x6a55(%rip), %rsi      # 0x10f18
movl 0x8(%rsi), %esi
shrl $0x3, %esi
subl $0x1, %esi
andl %esi, %edx
addl %edx, %ecx
movl %ecx, -0x18(%rbp)
movq 0x58(%rax), %rax
movl -0x18(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
callq 0x52d0
movq %rax, -0x88(%rbp)
callq 0x5400
movq -0x88(%rbp), %rdi
movq %rax, %rcx
movq -0x20(%rbp), %r11
movl -0x2c(%rbp), %r10d
movl -0x18(%rbp), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2bfa(%rip), %rdx      # 0xd10e
leaq 0x2047(%rip), %r8       # 0xc562
movl $0x277, %r9d            # imm = 0x277
movq %r11, (%rsp)
movl %r10d, 0x8(%rsp)
movl %eax, 0x10(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x80(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x80(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
cmpq $0x0, -0x20(%rbp)
setne %al
xorb $-0x1, %al
testb $0x1, %al
jne 0xa56f
jmp 0xa65c
callq 0x52d0
movq %rax, -0x98(%rbp)
callq 0x5400
movq -0x98(%rbp), %rdi
movq %rax, %rcx
movq -0x48(%rbp), %rax
movl -0x18(%rbp), %r11d
movq -0x20(%rbp), %r10
movl 0x2c(%rax), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2bc4(%rip), %rdx      # 0xd169
leaq 0x1fb6(%rip), %r8       # 0xc562
movl $0x27e, %r9d            # imm = 0x27E
movl %r11d, (%rsp)
movq %r10, 0x8(%rsp)
movl %eax, 0x10(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0x90(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0x90(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movl -0x18(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %eax
movq 0x6912(%rip), %rcx      # 0x10f18
movl 0x8(%rcx), %ecx
shrl $0x3, %ecx
subl $0x1, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
jne 0xa644
movl -0x2c(%rbp), %eax
movq 0x68f8(%rip), %rcx      # 0x10f18
movl 0x8(%rcx), %ecx
shrl $0x3, %ecx
movl %ecx, %ecx
bsrq %rcx, %rcx
xorq $0x3f, %rcx
movslq %ecx, %rdx
movl $0x40, %ecx
subq %rdx, %rcx
subq $0x1, %rcx
shll %cl, %eax
movl %eax, -0x18(%rbp)
movq -0x48(%rbp), %rax
movq 0x58(%rax), %rax
movl -0x18(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
jmp 0xa55c
jmp 0xa65e
movl -0x18(%rbp), %eax
movq 0x68b0(%rip), %rcx      # 0x10f18
movl 0x8(%rcx), %ecx
shrl $0x3, %ecx
movl %ecx, %ecx
bsrq %rcx, %rcx
xorq $0x3f, %rcx
movslq %ecx, %rdx
movl $0x40, %ecx
subq %rdx, %rcx
subq $0x1, %rcx
shrl %cl, %eax
movl %eax, -0x30(%rbp)
testb $0x1, -0x11(%rbp)
je 0xa73f
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x5940
cmpq $0x0, %rax
jbe 0xa73f
callq 0x52d0
movq %rax, -0xa8(%rbp)
callq 0x5400
movq -0xa8(%rbp), %rdi
movq %rax, %rcx
movl -0x18(%rbp), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2afd(%rip), %rdx      # 0xd1d4
leaq 0x1e84(%rip), %r8       # 0xc562
movl $0x291, %r9d            # imm = 0x291
movl %eax, (%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0xa0(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0xa0(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *(%rax)
movq %rax, %rdx
movq -0x48(%rbp), %rax
movq 0x58(%rax), %rax
movl -0x18(%rbp), %ecx
movq %rdx, (%rax,%rcx,8)
jmp 0xa8af
callq 0x52d0
movq %rax, -0xc8(%rbp)
callq 0x5400
movq -0xc8(%rbp), %rdi
movq %rax, %rcx
movq -0x48(%rbp), %rax
movq 0x58(%rax), %rbx
movq 0x58(%rax), %r11
movl -0x18(%rbp), %edx
shlq $0x3, %rdx
addq %rdx, %r11
movq 0x58(%rax), %rax
movl -0x18(%rbp), %edx
movq (%rax,%rdx,8), %r10
movl -0x18(%rbp), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2aaa(%rip), %rdx      # 0xd234
leaq 0x1dd1(%rip), %r8       # 0xc562
movl $0x297, %r9d            # imm = 0x297
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movl %eax, 0x18(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0xc0(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0xc0(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movq -0x48(%rbp), %rax
movq 0x58(%rax), %rcx
movl -0x18(%rbp), %edx
movq $0x0, (%rcx,%rdx,8)
movl 0x2c(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x2c(%rax)
callq 0x52d0
movq %rax, -0xb8(%rbp)
callq 0x5400
movq -0xb8(%rbp), %rdi
movq %rax, %rcx
movl -0x30(%rbp), %r10d
movl -0x18(%rbp), %eax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2a7a(%rip), %rdx      # 0xd2a1
leaq 0x1d34(%rip), %r8       # 0xc562
movl $0x29b, %r9d            # imm = 0x29B
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0xb0(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0xb0(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movq -0x48(%rbp), %rax
movl -0x30(%rbp), %ecx
movl 0x34(%rax,%rcx,4), %edx
addl $-0x1, %edx
movl %edx, 0x34(%rax,%rcx,4)
movl -0x30(%rbp), %ecx
cmpl $0x0, 0x34(%rax,%rcx,4)
jb 0xa88e
jmp 0xa8ad
leaq 0x2a4f(%rip), %rdi      # 0xd2e4
leaq 0x1cc6(%rip), %rsi      # 0xc562
movl $0x29d, %edx            # imm = 0x29D
leaq 0x2a60(%rip), %rcx      # 0xd308
callq 0x5300
jmp 0xa8af
callq 0x52d0
movq %rax, -0xd8(%rbp)
callq 0x5400
movq -0xd8(%rbp), %rdi
movq %rax, %rcx
movq -0x20(%rbp), %rax
movl $0x1000, %esi           # imm = 0x1000
leaq 0x2a68(%rip), %rdx      # 0xd342
leaq 0x1c81(%rip), %r8       # 0xc562
movl $0x2a0, %r9d            # imm = 0x2A0
movq %rax, (%rsp)
movb $0x0, %al
callq 0x57e0
callq 0x52d0
movq %rax, -0xd0(%rbp)
callq 0x52d0
movq %rax, %rdi
callq 0x51e0
movq -0xd0(%rbp), %rsi
movq %rax, %rdx
movl $0x2, %edi
callq 0x5160
movq -0x20(%rbp), %rax
addq $0xf8, %rsp
popq %rbx
popq %rbp
retq
nopl (%rax)