Patch title: Release 85 bulk changes
Abstract:
File: /pliant/language/memory/alloc.c
Key:
    Removed line
    Added line
   
// This program is free software; you can redistribute it an
// modify it under the terms of the GNU General Public Licen
// as published by the Free Software Foundation; either vers
// of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be u
// but WITHOUT ANY WARRANTY; without even the implied warran
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// along with this program; if not, write to the Free Softwa
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA


// This program is free software; you can redistribute it an
// modify it under the terms of the GNU General Public Licen
// as published by the Free Software Foundation; either vers
// of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be u
// but WITHOUT ANY WARRANTY; without even the implied warran
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public
// along with this program; if not, write to the Free Softwa
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA


FUNCTION Void default_pre_extend(Int size) {}
FUNCTION Void default_post_extend() {}

FUNCTION Address memory_allocate(Int asked,Address with) {
  return G.memory_allocate_hook(asked,with); }

FUNCTION Address MemoryPool_allocate(struct MemoryPool *pool
  Int size,index; struct MemoryChunk *binchunk;
  struct MemoryChunk *victim; Int victim_size;
  struct MemoryChunk *remainder; Int remainder_size;
  Address address; Bool newsection; Int reserve;
  MEMORY_LOCK_VAR MEMORY_UNLOCK_VAR
  check(asked>=0);
  if(asked==0) return null;
  size=required_size(asked);
  MEMORY_LOCK
  if(size<sort_threshold-align_size) {
    index=index_for_small_size(size);
    binchunk=bin_chunk(pool,index);
    victim=binchunk->previous;
    if(victim==binchunk) {
      index++;
      binchunk=bin_chunk(pool,index);
      victim=binchunk->previous; }
    if(victim!=binchunk) {
      victim_size=Chunk_size(victim);
      Chunk_remove(victim);
      Chunk_set_inuse(victim);
      Chunk_check_allocated(victim,size);
      G.memory_current_used+=Chunk_size(victim);
      MEMORY_UNLOCK
      #ifdef _CHECK_
        memory_random(Chunk_user_area(victim),memory_size(Ch
      #endif
      return Chunk_user_area(victim); }
    index++;
  other
    index=index_for_size(size);
    binchunk=bin_chunk(pool,index);
    for(victim=binchunk->previous; victim!=binchunk; victim=
      victim_size=Chunk_size(victim);
      remainder_size=victim_size-size;
      if(remainder_size>=sizeof(struct MemoryChunk)) {
        index--;
        break;
      orif(remainder_size>=0)
        Chunk_remove_and_commit(victim);
        Chunk_set_inuse(victim);
        Chunk_check_allocated(victim,size);
        G.memory_current_used+=Chunk_size(victim);
        MEMORY_UNLOCK
        #ifdef _CHECK_
          memory_random(Chunk_user_area(victim),memory_size(
        #endif
        return Chunk_user_area(victim); } }
    index++; }
  binchunk=bin_chunk(pool,0);
  victim=binchunk->previous;
  if(victim!=binchunk) {
    victim_size=Chunk_size(victim);
    remainder_size=victim_size-size;
    if(remainder_size>=sizeof(struct MemoryChunk)) {
      victim->size=size|previous_chunk_is_inuse;
      remainder=Chunk_translate(victim,size);
      remainder->size=remainder_size|previous_chunk_is_inuse
      Chunk_translate(remainder,remainder_size)->prev_size=r
      remainder_set(pool,remainder);
      Chunk_check_allocated(victim,size);
      G.memory_current_used+=Chunk_size(victim);
      MEMORY_UNLOCK
      #ifdef _CHECK_
        memory_random(Chunk_user_area(victim),memory_size(Ch
      #endif
      return Chunk_user_area(victim);
    orif(remainder_size>=0)
      Chunk_set_inuse(victim);
      remainder_clear(pool);
      Chunk_check_allocated(victim,size);
      G.memory_current_used+=Chunk_size(victim);
      MEMORY_UNLOCK
      #ifdef _CHECK_
        memory_random(Chunk_user_area(victim),memory_size(Ch
      #endif
      return Chunk_user_area(victim);
    other
      remainder_clear(pool);
      Chunk_insert(pool,victim,victim_size); } }
  while(index<nb_bins)
    if(*(uInt32 *)(pool->noempty_bins+index/8)>>(index%8)==0
      index=round_up(index+1,32);
    orif(*(uInt8 *)(pool->noempty_bins+index/8)>>(index%8)==
      index=round_up(index+1,8);
    orif(!bit_test(pool->noempty_bins,index))
      index++;
    other
      binchunk=bin_chunk(pool,index);
      for(victim=binchunk->previous; victim!=binchunk; victi
        victim_size=Chunk_size(victim);
        remainder_size=victim_size-size;
        if(remainder_size>=sizeof(struct MemoryChunk)) {
          Chunk_remove_and_commit(victim);
          victim->size=size|previous_chunk_is_inuse;
          remainder=Chunk_translate(victim,size);
          remainder->size=remainder_size|previous_chunk_is_i
          Chunk_translate(remainder,remainder_size)->prev_si
          if(with!=(Address)-1) {
            remainder_set(pool,remainder);
          other
            Chunk_insert(pool,remainder,remainder_size); }
          Chunk_check_allocated(victim,size);
          G.memory_current_used+=Chunk_size(victim);
          MEMORY_UNLOCK
          #ifdef _CHECK_
            memory_random(Chunk_user_area(victim),memory_siz
          #endif
          return Chunk_user_area(victim);
        orif(remainder_size>=0)
          Chunk_remove_and_commit(victim);
          Chunk_set_inuse(victim);
          Chunk_check_allocated(victim,size);
          G.memory_current_used+=Chunk_size(victim);
          MEMORY_UNLOCK
          #ifdef _CHECK_
            memory_random(Chunk_user_area(victim),memory_siz
          #endif
          return Chunk_user_area(victim); } }
      if(binchunk->previous==binchunk)
        bit_clear(pool->noempty_bins,index);
      index++; }
FUNCTION Address memory_allocate(Int asked,Address with) {
  return G.memory_allocate_hook(asked,with); }

FUNCTION Address MemoryPool_allocate(struct MemoryPool *pool
  Int size,index; struct MemoryChunk *binchunk;
  struct MemoryChunk *victim; Int victim_size;
  struct MemoryChunk *remainder; Int remainder_size;
  Address address; Bool newsection; Int reserve;
  MEMORY_LOCK_VAR MEMORY_UNLOCK_VAR
  check(asked>=0);
  if(asked==0) return null;
  size=required_size(asked);
  MEMORY_LOCK
  if(size<sort_threshold-align_size) {
    index=index_for_small_size(size);
    binchunk=bin_chunk(pool,index);
    victim=binchunk->previous;
    if(victim==binchunk) {
      index++;
      binchunk=bin_chunk(pool,index);
      victim=binchunk->previous; }
    if(victim!=binchunk) {
      victim_size=Chunk_size(victim);
      Chunk_remove(victim);
      Chunk_set_inuse(victim);
      Chunk_check_allocated(victim,size);
      G.memory_current_used+=Chunk_size(victim);
      MEMORY_UNLOCK
      #ifdef _CHECK_
        memory_random(Chunk_user_area(victim),memory_size(Ch
      #endif
      return Chunk_user_area(victim); }
    index++;
  other
    index=index_for_size(size);
    binchunk=bin_chunk(pool,index);
    for(victim=binchunk->previous; victim!=binchunk; victim=
      victim_size=Chunk_size(victim);
      remainder_size=victim_size-size;
      if(remainder_size>=sizeof(struct MemoryChunk)) {
        index--;
        break;
      orif(remainder_size>=0)
        Chunk_remove_and_commit(victim);
        Chunk_set_inuse(victim);
        Chunk_check_allocated(victim,size);
        G.memory_current_used+=Chunk_size(victim);
        MEMORY_UNLOCK
        #ifdef _CHECK_
          memory_random(Chunk_user_area(victim),memory_size(
        #endif
        return Chunk_user_area(victim); } }
    index++; }
  binchunk=bin_chunk(pool,0);
  victim=binchunk->previous;
  if(victim!=binchunk) {
    victim_size=Chunk_size(victim);
    remainder_size=victim_size-size;
    if(remainder_size>=sizeof(struct MemoryChunk)) {
      victim->size=size|previous_chunk_is_inuse;
      remainder=Chunk_translate(victim,size);
      remainder->size=remainder_size|previous_chunk_is_inuse
      Chunk_translate(remainder,remainder_size)->prev_size=r
      remainder_set(pool,remainder);
      Chunk_check_allocated(victim,size);
      G.memory_current_used+=Chunk_size(victim);
      MEMORY_UNLOCK
      #ifdef _CHECK_
        memory_random(Chunk_user_area(victim),memory_size(Ch
      #endif
      return Chunk_user_area(victim);
    orif(remainder_size>=0)
      Chunk_set_inuse(victim);
      remainder_clear(pool);
      Chunk_check_allocated(victim,size);
      G.memory_current_used+=Chunk_size(victim);
      MEMORY_UNLOCK
      #ifdef _CHECK_
        memory_random(Chunk_user_area(victim),memory_size(Ch
      #endif
      return Chunk_user_area(victim);
    other
      remainder_clear(pool);
      Chunk_insert(pool,victim,victim_size); } }
  while(index<nb_bins)
    if(*(uInt32 *)(pool->noempty_bins+index/8)>>(index%8)==0
      index=round_up(index+1,32);
    orif(*(uInt8 *)(pool->noempty_bins+index/8)>>(index%8)==
      index=round_up(index+1,8);
    orif(!bit_test(pool->noempty_bins,index))
      index++;
    other
      binchunk=bin_chunk(pool,index);
      for(victim=binchunk->previous; victim!=binchunk; victi
        victim_size=Chunk_size(victim);
        remainder_size=victim_size-size;
        if(remainder_size>=sizeof(struct MemoryChunk)) {
          Chunk_remove_and_commit(victim);
          victim->size=size|previous_chunk_is_inuse;
          remainder=Chunk_translate(victim,size);
          remainder->size=remainder_size|previous_chunk_is_i
          Chunk_translate(remainder,remainder_size)->prev_si
          if(with!=(Address)-1) {
            remainder_set(pool,remainder);
          other
            Chunk_insert(pool,remainder,remainder_size); }
          Chunk_check_allocated(victim,size);
          G.memory_current_used+=Chunk_size(victim);
          MEMORY_UNLOCK
          #ifdef _CHECK_
            memory_random(Chunk_user_area(victim),memory_siz
          #endif
          return Chunk_user_area(victim);
        orif(remainder_size>=0)
          Chunk_remove_and_commit(victim);
          Chunk_set_inuse(victim);
          Chunk_check_allocated(victim,size);
          G.memory_current_used+=Chunk_size(victim);
          MEMORY_UNLOCK
          #ifdef _CHECK_
            memory_random(Chunk_user_area(victim),memory_siz
          #endif
          return Chunk_user_area(victim); } }
      if(binchunk->previous==binchunk)
        bit_clear(pool->noempty_bins,index);
      index++; }
  G.memory_pre_extend_hook(size);
  size=round_up(size+sizeof(Int),commit_step);
  newsection=false;
  if(pool->nb_area==0 || pool->areas[pool->nb_area-1].size-p
    reserve=maximum(size,G.memory_maximal_address==null ? fi
    pool->areas[pool->nb_area].address=memory_page_reserve(n
    pool->areas[pool->nb_area].size=reserve;
    pool->areas[pool->nb_area++].consumed=0;
    newsection=true; }
  address=address_translate(pool->areas[pool->nb_area-1].add
  pool->areas[pool->nb_area-1].consumed+=size;
  memory_page_commit(address,size);
  if(integer_from_address(address)<integer_from_address(G.me
  if(integer_from_address(address_translate(address,size-1))
  if(newsection) {
    victim=Chunk_first(address);
    victim_size=size-align_size;
    victim->size=victim_size|previous_chunk_is_inuse;
    remainder=Chunk_translate(victim,victim_size);
    remainder->prev_size=victim_size;
    remainder->size=0;
    Chunk_insert(pool,victim,victim_size);
    Chunk_check_free(victim);
    MEMORY_UNLOCK
  other
    victim=struct_from_field(MemoryChunk,size,address_transl
    victim_size=size;
    victim->size=victim_size|(victim->size&previous_chunk_is
    remainder=Chunk_translate(victim,victim_size);
    remainder->size=previous_chunk_is_inuse;
    Chunk_check_inuse(victim);
    G.memory_current_used+=victim_size;
    MEMORY_UNLOCK
    MemoryPool_free(pool,Chunk_user_area(victim)); }
  size=round_up(size+sizeof(Int),commit_step);
  newsection=false;
  if(pool->nb_area==0 || pool->areas[pool->nb_area-1].size-p
    reserve=maximum(size,G.memory_maximal_address==null ? fi
    pool->areas[pool->nb_area].address=memory_page_reserve(n
    pool->areas[pool->nb_area].size=reserve;
    pool->areas[pool->nb_area++].consumed=0;
    newsection=true; }
  address=address_translate(pool->areas[pool->nb_area-1].add
  pool->areas[pool->nb_area-1].consumed+=size;
  memory_page_commit(address,size);
  if(integer_from_address(address)<integer_from_address(G.me
  if(integer_from_address(address_translate(address,size-1))
  if(newsection) {
    victim=Chunk_first(address);
    victim_size=size-align_size;
    victim->size=victim_size|previous_chunk_is_inuse;
    remainder=Chunk_translate(victim,victim_size);
    remainder->prev_size=victim_size;
    remainder->size=0;
    Chunk_insert(pool,victim,victim_size);
    Chunk_check_free(victim);
    MEMORY_UNLOCK
  other
    victim=struct_from_field(MemoryChunk,size,address_transl
    victim_size=size;
    victim->size=victim_size|(victim->size&previous_chunk_is
    remainder=Chunk_translate(victim,victim_size);
    remainder->size=previous_chunk_is_inuse;
    Chunk_check_inuse(victim);
    G.memory_current_used+=victim_size;
    MEMORY_UNLOCK
    MemoryPool_free(pool,Chunk_user_area(victim)); }
  return MemoryPool_allocate(pool,asked,with); }
  address=MemoryPool_allocate(pool,asked,with);
  G.memory_post_extend_hook();
  return address; }