// File: tomfunkhouser[P]gaps/pkgs/jpeg/jmemmgr.c
// Function: alloc_small
METHODDEF(void *)
alloc_small (j_common_ptr cinfo, int pool_id, size_t sizeofobject)
/* Allocate a "small" object */
{
  my_mem_ptr mem = (my_mem_ptr) cinfo->mem;
  small_pool_ptr hdr_ptr, prev_hdr_ptr;
  char * data_ptr;
  size_t odd_bytes, min_request, slop;

  /* Check for unsatisfiable request (do now to ensure no overflow below) */
  if (sizeofobject > (size_t) (MAX_ALLOC_CHUNK-SIZEOF(small_pool_hdr)))
    out_of_memory(cinfo, 1);	/* request exceeds malloc's ability */

  /* Round up the requested size to a multiple of SIZEOF(ALIGN_TYPE) */
  odd_bytes = sizeofobject % SIZEOF(ALIGN_TYPE);
  if (odd_bytes > 0)
    sizeofobject += SIZEOF(ALIGN_TYPE) - odd_bytes;

  /* See if space is available in any existing pool */
  if (pool_id < 0 || pool_id >= JPOOL_NUMPOOLS)
    ERREXIT1(cinfo, JERR_BAD_POOL_ID, pool_id);	/* safety check */
  prev_hdr_ptr = NULL;
  hdr_ptr = mem->small_list[pool_id];
  while (hdr_ptr != NULL) {
    if (hdr_ptr->hdr.bytes_left >= sizeofobject)
      break;			/* found pool with enough space */
    prev_hdr_ptr = hdr_ptr;
    hdr_ptr = hdr_ptr->hdr.next;
  }

  /* Time to make a new pool? */
  if (hdr_ptr == NULL) {
    /* min_request is what we need now, slop is what will be leftover */
    min_request = sizeofobject + SIZEOF(small_pool_hdr);
    if (prev_hdr_ptr == NULL)	/* first pool in class? */
      slop = first_pool_slop[pool_id];
    else
      slop = extra_pool_slop[pool_id];
    /* Don't ask for more than MAX_ALLOC_CHUNK */
    if (slop > (size_t) (MAX_ALLOC_CHUNK-min_request))
      slop = (size_t) (MAX_ALLOC_CHUNK-min_request);
    /* Try to get space, if fail reduce slop and try again */
    for (;;) {
      hdr_ptr = (small_pool_ptr) jpeg_get_small(cinfo, min_request + slop);
      if (hdr_ptr != NULL)
	break;
      slop /= 2;
      if (slop < MIN_SLOP)	/* give up when it gets real small */
	out_of_memory(cinfo, 2); /* jpeg_get_small failed */
    }
    mem->total_space_allocated += min_request + slop;
    /* Success, initialize the new pool header and add to end of list */
    hdr_ptr->hdr.next = NULL;
    hdr_ptr->hdr.bytes_used = 0;
    hdr_ptr->hdr.bytes_left = sizeofobject + slop;
    if (prev_hdr_ptr == NULL)	/* first pool in class? */
      mem->small_list[pool_id] = hdr_ptr;
    else
      prev_hdr_ptr->hdr.next = hdr_ptr;
  }

  /* OK, allocate the object from the current pool */
  data_ptr = (char *) (hdr_ptr + 1); /* point to first data byte in pool */
  data_ptr += hdr_ptr->hdr.bytes_used; /* point to place for object */
  hdr_ptr->hdr.bytes_used += sizeofobject;
  hdr_ptr->hdr.bytes_left -= sizeofobject;

  return (void *) data_ptr;
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movl %esi, 0x4c(%rsp)
movq %rdx, 0x40(%rsp)
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x38(%rsp)
cmpq $0x3b9ac9e8, 0x40(%rsp) # imm = 0x3B9AC9E8
jbe 0xf9b4a
movq 0x50(%rsp), %rdi
movl $0x1, %esi
callq 0xfafe0
movq 0x40(%rsp), %rax
andq $0x7, %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, 0x18(%rsp)
jbe 0xf9b74
movl $0x8, %eax
subq 0x18(%rsp), %rax
addq 0x40(%rsp), %rax
movq %rax, 0x40(%rsp)
cmpl $0x0, 0x4c(%rsp)
jl 0xf9b82
cmpl $0x2, 0x4c(%rsp)
jl 0xf9bb2
movq 0x50(%rsp), %rax
movq (%rax), %rax
movl $0xe, 0x28(%rax)
movl 0x4c(%rsp), %ecx
movq 0x50(%rsp), %rax
movq (%rax), %rax
movl %ecx, 0x2c(%rax)
movq 0x50(%rsp), %rax
movq (%rax), %rax
movq (%rax), %rax
movq 0x50(%rsp), %rdi
callq *%rax
movq $0x0, 0x28(%rsp)
movq 0x38(%rsp), %rax
movslq 0x4c(%rsp), %rcx
movq 0x68(%rax,%rcx,8), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
je 0xf9c02
movq 0x30(%rsp), %rax
movq 0x10(%rax), %rax
cmpq 0x40(%rsp), %rax
jb 0xf9be9
jmp 0xf9c02
movq 0x30(%rsp), %rax
movq %rax, 0x28(%rsp)
movq 0x30(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x30(%rsp)
jmp 0xf9bcf
cmpq $0x0, 0x30(%rsp)
jne 0xf9d34
movq 0x40(%rsp), %rax
addq $0x18, %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, 0x28(%rsp)
jne 0xf9c3b
movslq 0x4c(%rsp), %rcx
leaq 0x3ec50(%rip), %rax     # 0x138880
movq (%rax,%rcx,8), %rax
movq %rax, 0x8(%rsp)
jmp 0xf9c50
movslq 0x4c(%rsp), %rcx
leaq 0x3ec49(%rip), %rax     # 0x138890
movq (%rax,%rcx,8), %rax
movq %rax, 0x8(%rsp)
movq 0x8(%rsp), %rax
movl $0x3b9aca00, %ecx       # imm = 0x3B9ACA00
subq 0x10(%rsp), %rcx
cmpq %rcx, %rax
jbe 0xf9c73
movl $0x3b9aca00, %eax       # imm = 0x3B9ACA00
subq 0x10(%rsp), %rax
movq %rax, 0x8(%rsp)
jmp 0xf9c75
movq 0x50(%rsp), %rdi
movq 0x10(%rsp), %rsi
addq 0x8(%rsp), %rsi
callq 0xfb410
movq %rax, 0x30(%rsp)
cmpq $0x0, 0x30(%rsp)
je 0xf9c98
jmp 0xf9cbe
movq 0x8(%rsp), %rax
shrq %rax
movq %rax, 0x8(%rsp)
cmpq $0x32, 0x8(%rsp)
jae 0xf9cbc
movq 0x50(%rsp), %rdi
movl $0x2, %esi
callq 0xfafe0
jmp 0xf9c75
movq 0x10(%rsp), %rcx
addq 0x8(%rsp), %rcx
movq 0x38(%rsp), %rax
addq 0x98(%rax), %rcx
movq %rcx, 0x98(%rax)
movq 0x30(%rsp), %rax
movq $0x0, (%rax)
movq 0x30(%rsp), %rax
movq $0x0, 0x8(%rax)
movq 0x40(%rsp), %rcx
addq 0x8(%rsp), %rcx
movq 0x30(%rsp), %rax
movq %rcx, 0x10(%rax)
cmpq $0x0, 0x28(%rsp)
jne 0xf9d25
movq 0x30(%rsp), %rdx
movq 0x38(%rsp), %rax
movslq 0x4c(%rsp), %rcx
movq %rdx, 0x68(%rax,%rcx,8)
jmp 0xf9d32
movq 0x30(%rsp), %rcx
movq 0x28(%rsp), %rax
movq %rcx, (%rax)
jmp 0xf9d34
movq 0x30(%rsp), %rax
addq $0x18, %rax
movq %rax, 0x20(%rsp)
movq 0x30(%rsp), %rax
movq 0x8(%rax), %rax
addq 0x20(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x40(%rsp), %rcx
movq 0x30(%rsp), %rax
addq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x40(%rsp), %rdx
movq 0x30(%rsp), %rax
movq 0x10(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x10(%rax)
movq 0x20(%rsp), %rax
addq $0x58, %rsp
retq
nopw %cs:(%rax,%rax)