!Heapswop for IMN
!RWT April 1986

%systemroutine heapswop(%integer depth)

! 0 < DEPTH < HEAP_LEVEL
! Exchange the mark levels of all heap cells with
! level heap_level and heap_level-depth, thus allowing
! the next RELEASE to by-pass the most recently marked region(s).

%recordformat f0(%integer limit,(%byte level %orinteger size),
                 %record(*)%name link,holes)
%recordformat f1(%byte level %orinteger size,%record(*)%name next,prev)
@724(a5) %record(f0)%name heap
%byte a,b
%record(f1)%name end,this
%constinteger sizemask=16_fffffc

  %signal 5,,depth,"Heapswop: illegal depth" %unless 0<=depth<heap_level
  a = heap_level; b = a-depth
  %returnif a=b
  end == record(heap_limit)
  this == record(addr(heap)+sizeof(heap))
  %cycle
    %returnif this==end
    %signal 5,,addr(this),"Heapswop: heap corrupt" %if addr(this)>heap_limit
    %if this_level=a %start
      this_level = b
    %elseif this_level=b
      this_level = a
    %finish
    this == record(addr(this)+this_size&sizemask)
  %repeat
%end
