GC_INNER void GC_unmap(ptr_t start, size_t bytes)
{
    ptr_t start_addr = GC_unmap_start(start, bytes);
    ptr_t end_addr = GC_unmap_end(start, bytes);
    word len = end_addr - start_addr;

    if (0 == start_addr) return;
#   ifdef USE_WINALLOC
      while (len != 0) {
          MEMORY_BASIC_INFORMATION mem_info;
          word free_len;

          if (VirtualQuery(start_addr, &mem_info, sizeof(mem_info))
              != sizeof(mem_info))
              ABORT("Weird VirtualQuery result");
          free_len = (len < mem_info.RegionSize) ? len : mem_info.RegionSize;
          if (!VirtualFree(start_addr, free_len, MEM_DECOMMIT))
              ABORT("VirtualFree failed");
          GC_unmapped_bytes += free_len;
          start_addr += free_len;
          len -= free_len;
      }
#   else
      /* We immediately remap it to prevent an intervening mmap from    */
      /* accidentally grabbing the same address space.                  */
      {
        void * result;

        result = mmap(start_addr, len, PROT_NONE,
                      MAP_PRIVATE | MAP_FIXED | OPT_MAP_ANON,
                      zero_fd, 0/* offset */);
        if (result != (void *)start_addr)
          ABORT("mmap(PROT_NONE) failed");
      }
      GC_unmapped_bytes += len;
#   endif
}
GC_INNER void GC_unmap(ptr_t start, size_t bytes)
{
    ptr_t start_addr = GC_unmap_start(start, bytes);
    ptr_t end_addr = GC_unmap_end(start, bytes);
    word len = end_addr - start_addr;

    if (0 == start_addr) return;
#   ifdef USE_WINALLOC
      while (len != 0) {
          MEMORY_BASIC_INFORMATION mem_info;
          word free_len;

          if (VirtualQuery(start_addr, &mem_info, sizeof(mem_info))
              != sizeof(mem_info))
              ABORT("Weird VirtualQuery result");
          free_len = (len < mem_info.RegionSize) ? len : mem_info.RegionSize;
          if (!VirtualFree(start_addr, free_len, MEM_DECOMMIT))
              ABORT("VirtualFree failed");
          GC_unmapped_bytes += free_len;
          start_addr += free_len;
          len -= free_len;
      }
#   else
       
       
      {
        void * result;

        result = mmap(start_addr, len, PROT_NONE,
                      MAP_PRIVATE | MAP_FIXED | OPT_MAP_ANON,
                      zero_fd, 0 );
        if (result != (void *)start_addr)
          ABORT("mmap(PROT_NONE) failed");
      }
      GC_unmapped_bytes += len;
#   endif
}