Program: 149937
Project: 149937
Buggy source:
/** 
 * Perform the compacting phase of the collection.
 */
public void compact(){
  if (initialRegion.isZero())   return;
  Address start=initialRegion;
  Address allocStart=initialRegion;
  Address allocEnd=initialRegion.plus(REGION_LIMIT_OFFSET).loadAddress();
  Address allocCursor=allocStart.plus(DATA_START_OFFSET);
  int oldPages=0;
  int newPages=0;
  while (!start.isZero()) {
    Address end=start.plus(REGION_LIMIT_OFFSET).loadAddress();
    Address dataEnd=start.plus(DATA_END_OFFSET).loadAddress();
    Address nextRegion=start.plus(NEXT_REGION_OFFSET).loadAddress();
    oldPages+=Conversions.bytesToPages(end.diff(start).plus(BYTES_IN_ADDRESS));
    Address currentLimit=(dataEnd.isZero() ? cursor : dataEnd);
    ObjectReference current=VM.objectModel.getObjectFromStartAddress(start.plus(DATA_START_OFFSET));
    while (VM.objectModel.refToAddress(current).LT(currentLimit) && !current.isNull()) {
      ObjectReference next=VM.objectModel.getNextObject(current);
      ObjectReference copyTo=MarkCompactSpace.getForwardingPointer(current);
      if (!copyTo.isNull() && Space.isInSpace(MC.MARK_COMPACT,copyTo)) {
        if (VM.VERIFY_ASSERTIONS)         VM.assertions._assert(!MarkCompactSpace.isMarked(current));
        if (copyTo.toAddress().GT(allocEnd) || copyTo.toAddress().LT(allocStart)) {
          VM.memory.zero(allocCursor,allocEnd.diff(allocCursor).toWord().toExtent().plus(BYTES_IN_ADDRESS));
          allocStart.store(allocCursor,DATA_END_OFFSET);
          allocStart=allocStart.plus(NEXT_REGION_OFFSET).loadAddress();
          allocEnd=allocStart.plus(REGION_LIMIT_OFFSET).loadAddress();
          allocCursor=allocStart.plus(DATA_START_OFFSET);
          newPages+=Conversions.bytesToPages(allocEnd.diff(allocStart).plus(BYTES_IN_ADDRESS));
          if (VM.VERIFY_ASSERTIONS) {
            VM.assertions._assert(allocCursor.LT(allocEnd) && allocCursor.GE(allocStart));
          }
        }
        int copySize=VM.objectModel.getSizeWhenCopied(current);
        Address newAllocCursor=VM.objectModel.copyTo(current,copyTo,allocCursor);
        Address objectStart=newAllocCursor.minus(copySize);
        fillAlignmentGap(allocCursor,objectStart);
        allocCursor=newAllocCursor;
        MarkCompactSpace.setForwardingPointer(copyTo,ObjectReference.nullReference());
      }
      current=next;
    }
    if (dataEnd.isZero()) {
      break;
    }
    start=nextRegion;
  }
  Extent zeroBytes=allocEnd.diff(allocCursor).toWord().toExtent().plus(BYTES_IN_ADDRESS);
  VM.memory.zero(allocCursor,zeroBytes);
  allocStart.store(Address.zero(),DATA_END_OFFSET);
  region=allocStart;
  cursor=allocCursor;
  updateLimit(allocEnd,region,0);
  if (oldPages > newPages) {
    ((MarkCompactSpace)space).unusePages((oldPages - newPages));
  }
  allocStart=allocStart.loadAddress(NEXT_REGION_OFFSET);
  while (!allocStart.isZero()) {
    allocStart.store(Address.zero(),DATA_END_OFFSET);
    if (VM.VERIFY_ASSERTIONS) {
      Address low=allocStart.plus(DATA_START_OFFSET);
      Extent size=allocStart.loadAddress(REGION_LIMIT_OFFSET).diff(allocStart).toWord().toExtent().minus(2 * BYTES_IN_ADDRESS);
      VM.memory.zero(low,size);
    }
    allocStart=allocStart.loadAddress(NEXT_REGION_OFFSET);
  }
}

Fixed version (ground truth):
/** 
 * Perform the compacting phase of the collection.
 */
public void compact(){
  if (initialRegion.isZero())   return;
  Address start=initialRegion;
  Address allocStart=initialRegion;
  Address allocEnd=initialRegion.plus(REGION_LIMIT_OFFSET).loadAddress();
  Address allocCursor=allocStart.plus(DATA_START_OFFSET);
  int oldPages=0;
  int newPages=0;
  while (!start.isZero()) {
    Address end=start.plus(REGION_LIMIT_OFFSET).loadAddress();
    Address dataEnd=start.plus(DATA_END_OFFSET).loadAddress();
    Address nextRegion=start.plus(NEXT_REGION_OFFSET).loadAddress();
    oldPages+=Conversions.bytesToPages(end.diff(start).plus(BYTES_IN_ADDRESS));
    Address currentLimit=(dataEnd.isZero() ? cursor : dataEnd);
    ObjectReference current=VM.objectModel.getObjectFromStartAddress(start.plus(DATA_START_OFFSET));
    while (VM.objectModel.refToAddress(current).LT(currentLimit) && !current.isNull()) {
      ObjectReference next=VM.objectModel.getNextObject(current);
      ObjectReference copyTo=MarkCompactSpace.getForwardingPointer(current);
      if (!copyTo.isNull() && Space.isInSpace(MC.MARK_COMPACT,copyTo)) {
        if (VM.VERIFY_ASSERTIONS)         VM.assertions._assert(!MarkCompactSpace.isMarked(current));
        if (copyTo.toAddress().GT(allocEnd) || copyTo.toAddress().LT(allocStart)) {
          VM.memory.zero(allocCursor,allocEnd.diff(allocCursor).toWord().toExtent().plus(BYTES_IN_ADDRESS));
          allocStart.store(allocCursor,DATA_END_OFFSET);
          allocStart=allocStart.plus(NEXT_REGION_OFFSET).loadAddress();
          allocEnd=allocStart.plus(REGION_LIMIT_OFFSET).loadAddress();
          allocCursor=allocStart.plus(DATA_START_OFFSET);
          newPages+=Conversions.bytesToPages(allocEnd.diff(allocStart).plus(BYTES_IN_ADDRESS));
          if (VM.VERIFY_ASSERTIONS) {
            VM.assertions._assert(allocCursor.LT(allocEnd) && allocCursor.GE(allocStart));
          }
        }
        allocCursor=VM.objectModel.copyTo(current,copyTo,allocCursor);
        MarkCompactSpace.setForwardingPointer(copyTo,ObjectReference.nullReference());
      }
      current=next;
    }
    if (dataEnd.isZero()) {
      break;
    }
    start=nextRegion;
  }
  Extent zeroBytes=allocEnd.diff(allocCursor).toWord().toExtent().plus(BYTES_IN_ADDRESS);
  VM.memory.zero(allocCursor,zeroBytes);
  allocStart.store(Address.zero(),DATA_END_OFFSET);
  region=allocStart;
  cursor=allocCursor;
  updateLimit(allocEnd,region,0);
  if (oldPages > newPages) {
    ((MarkCompactSpace)space).unusePages((oldPages - newPages));
  }
  allocStart=allocStart.loadAddress(NEXT_REGION_OFFSET);
  while (!allocStart.isZero()) {
    allocStart.store(Address.zero(),DATA_END_OFFSET);
    if (VM.VERIFY_ASSERTIONS) {
      Address low=allocStart.plus(DATA_START_OFFSET);
      Extent size=allocStart.loadAddress(REGION_LIMIT_OFFSET).diff(allocStart).toWord().toExtent().minus(2 * BYTES_IN_ADDRESS);
      VM.memory.zero(low,size);
    }
    allocStart=allocStart.loadAddress(NEXT_REGION_OFFSET);
  }
}