private boolean acquireRecyclableLines(int bytes, int align, int offset) {
    while (line < LINES_IN_BLOCK || acquireRecyclableBlock()) {
      line = space.getNextAvailableLine(markTable, line);
      if (line < LINES_IN_BLOCK) {
        int endLine = space.getNextUnavailableLine(markTable, line);
        cursor = recyclableBlock.plus(Extent.fromIntSignExtend(line << LOG_BYTES_IN_LINE));
        limit = recyclableBlock.plus(Extent.fromIntSignExtend(endLine << LOG_BYTES_IN_LINE));
        if (SANITY_CHECK_LINE_MARKS) {
          Address tmp = cursor;
          while (tmp.LT(limit)) {
            if (tmp.loadByte() != (byte) 0) {
              Log.write("cursor: ");
              Log.writeln(cursor);
              Log.write(" limit: ");
              Log.writeln(limit);
              Log.write("current: ");
              Log.write(tmp);
              Log.write("  value: ");
              Log.write(tmp.loadByte());
              Log.write("   line: ");
              Log.write(line);
              Log.write("endline: ");
              Log.write(endLine);
              Log.write("  chunk: ");
              Log.write(Chunk.align(cursor));
              Log.write("     hw: ");
              Log.write(Chunk.getHighWater(Chunk.align(cursor)));
              Log.writeln(" values: ");
              Address tmp2 = cursor;
              while (tmp2.LT(limit)) {
                Log.write(tmp2.loadByte());
                Log.write(" ");
              }
              Log.writeln();
            }
            VM.assertions._assert(tmp.loadByte() == (byte) 0);
            tmp = tmp.plus(1);
          }
        }
        if (VM.VERIFY_ASSERTIONS && bytes <= BYTES_IN_LINE) {
          Address start = alignAllocationNoFill(cursor, align, offset);
          Address end = start.plus(bytes);
          VM.assertions._assert(end.LE(limit));
        }
        VM.memory.zero(cursor, limit.diff(cursor).toWord().toExtent());
        if (VM.VERIFY_ASSERTIONS && Options.verbose.getValue() >= 9) {
          Log.write("Z[");
          Log.write(cursor);
          Log.write("->");
          Log.write(limit);
          Log.writeln("]");
        }

        line = endLine;
        if (VM.VERIFY_ASSERTIONS && copy) VM.assertions._assert(!Block.isDefragSource(cursor));
        return true;
      }
    }
    return false;
  }
Beispiel #2
0
  /**
   * Low level copy of len elements from src[srcPos] to dst[dstPos].
   *
   * <p>Assumptions: <code> src != dst || (scrPos >= dstPos + 4) </code> and src and dst are 8Bit
   * arrays.
   *
   * @param src the source array
   * @param srcPos index in the source array to begin copy
   * @param dst the destination array
   * @param dstPos index in the destination array to being copy
   * @param len number of array elements to copy
   */
  @Inline
  public static void arraycopy8Bit(Object src, int srcPos, Object dst, int dstPos, int len) {
    if (USE_NATIVE && len > NATIVE_THRESHOLD) {
      memcopy(
          VM_Magic.objectAsAddress(dst).plus(dstPos),
          VM_Magic.objectAsAddress(src).plus(srcPos),
          len);
    } else {
      if (len >= BYTES_IN_ADDRESS
          && (srcPos & (BYTES_IN_ADDRESS - 1)) == (dstPos & (BYTES_IN_ADDRESS - 1))) {
        // relative alignment is the same
        int byteStart = srcPos;
        int wordStart = alignUp(srcPos, BYTES_IN_ADDRESS);
        int wordEnd = alignDown(srcPos + len, BYTES_IN_ADDRESS);
        int byteEnd = srcPos + len;
        int startDiff = wordStart - byteStart;
        int endDiff = byteEnd - wordEnd;
        int wordLen = wordEnd - wordStart;
        Address srcPtr = VM_Magic.objectAsAddress(src).plus(srcPos + startDiff);
        Address dstPtr = VM_Magic.objectAsAddress(dst).plus(dstPos + startDiff);

        if (VM.BuildFor64Addr) {
          switch (startDiff) {
            case 7:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(-7)), Offset.fromIntSignExtend(-7));
            case 6:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(-6)), Offset.fromIntSignExtend(-6));
            case 5:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(-5)), Offset.fromIntSignExtend(-5));
            case 4:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(-4)), Offset.fromIntSignExtend(-4));
            case 3:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(-3)), Offset.fromIntSignExtend(-3));
            case 2:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(-2)), Offset.fromIntSignExtend(-2));
            case 1:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(-1)), Offset.fromIntSignExtend(-1));
          }
        } else {
          switch (startDiff) {
            case 3:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(-3)), Offset.fromIntSignExtend(-3));
            case 2:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(-2)), Offset.fromIntSignExtend(-2));
            case 1:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(-1)), Offset.fromIntSignExtend(-1));
          }
        }

        Address endPtr = srcPtr.plus(wordLen);
        while (srcPtr.LT(endPtr)) {
          dstPtr.store(srcPtr.loadWord());
          srcPtr = srcPtr.plus(BYTES_IN_ADDRESS);
          dstPtr = dstPtr.plus(BYTES_IN_ADDRESS);
        }

        if (VM.BuildFor64Addr) {
          switch (endDiff) {
            case 7:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(6)), Offset.fromIntSignExtend(6));
            case 6:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(5)), Offset.fromIntSignExtend(5));
            case 5:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(4)), Offset.fromIntSignExtend(4));
            case 4:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(3)), Offset.fromIntSignExtend(3));
            case 3:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(2)), Offset.fromIntSignExtend(2));
            case 2:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(1)), Offset.fromIntSignExtend(1));
            case 1:
              dstPtr.store(srcPtr.loadByte());
          }
        } else {
          switch (endDiff) {
            case 3:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(2)), Offset.fromIntSignExtend(2));
            case 2:
              dstPtr.store(
                  srcPtr.loadByte(Offset.fromIntSignExtend(1)), Offset.fromIntSignExtend(1));
            case 1:
              dstPtr.store(srcPtr.loadByte());
          }
        }

      } else {
        Address srcPtr = VM_Magic.objectAsAddress(src).plus(srcPos);
        Address dstPtr = VM_Magic.objectAsAddress(dst).plus(dstPos);
        Address endPtr = srcPtr.plus(len);
        while (srcPtr.LT(endPtr)) {
          dstPtr.store(srcPtr.loadByte());
          srcPtr = srcPtr.plus(1);
          dstPtr = dstPtr.plus(1);
        }
      }
    }
  }
 @Inline
 private static void copy1Bytes(Address dstPtr, Address srcPtr) {
   dstPtr.store(srcPtr.loadByte());
 }
  /**
   * Low level copy of <code>copyBytes</code> bytes from <code>src[srcPos]</code> to <code>
   * dst[dstPos]</code>.
   *
   * <p>Assumption <code>src != dst || (srcPos >= dstPos)</code> and element size is 4 bytes.
   *
   * @param dstPtr The destination start address
   * @param srcPtr The source start address
   * @param copyBytes The number of bytes to be copied
   */
  public static void aligned8Copy(Address dstPtr, Address srcPtr, int copyBytes) {
    if (USE_NATIVE && copyBytes > NATIVE_THRESHOLD) {
      memcopy(dstPtr, srcPtr, copyBytes);
    } else {
      if (copyBytes >= BYTES_IN_COPY
          && (srcPtr.toWord().and(Word.fromIntZeroExtend(BYTES_IN_COPY - 1))
              == (dstPtr.toWord().and(Word.fromIntZeroExtend(BYTES_IN_COPY - 1))))) {
        // relative alignment is the same
        Address endPtr = srcPtr.plus(copyBytes);
        Address wordEndPtr =
            endPtr.toWord().and(Word.fromIntZeroExtend(BYTES_IN_COPY - 1).not()).toAddress();

        if (BYTES_IN_COPY == 8) {
          if (srcPtr.toWord().and(Word.fromIntZeroExtend(1)).NE(Word.zero())) {
            copy1Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(1);
            dstPtr = dstPtr.plus(1);
          }
          if (srcPtr.toWord().and(Word.fromIntZeroExtend(2)).NE(Word.zero())) {
            copy2Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(2);
            dstPtr = dstPtr.plus(2);
          }
          if (srcPtr.toWord().and(Word.fromIntZeroExtend(4)).NE(Word.zero())) {
            copy4Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(4);
            dstPtr = dstPtr.plus(4);
          }
        } else {
          if (srcPtr.toWord().and(Word.fromIntZeroExtend(1)).NE(Word.zero())) {
            copy1Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(1);
            dstPtr = dstPtr.plus(1);
          }
          if (srcPtr.toWord().and(Word.fromIntZeroExtend(2)).NE(Word.zero())) {
            copy2Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(2);
            dstPtr = dstPtr.plus(2);
          }
        }
        while (srcPtr.LT(wordEndPtr)) {
          if (BYTES_IN_COPY == 8) {
            copy8Bytes(dstPtr, srcPtr);
          } else {
            copy4Bytes(dstPtr, srcPtr);
          }
          srcPtr = srcPtr.plus(BYTES_IN_COPY);
          dstPtr = dstPtr.plus(BYTES_IN_COPY);
        }
        // if(VM.VerifyAssertions) VM._assert(wordEndPtr.EQ(srcPtr));
        if (BYTES_IN_COPY == 8) {
          if (endPtr.toWord().and(Word.fromIntZeroExtend(4)).NE(Word.zero())) {
            copy4Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(4);
            dstPtr = dstPtr.plus(4);
          }
          if (endPtr.toWord().and(Word.fromIntZeroExtend(2)).NE(Word.zero())) {
            copy2Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(2);
            dstPtr = dstPtr.plus(2);
          }
          if (endPtr.toWord().and(Word.fromIntZeroExtend(1)).NE(Word.zero())) {
            copy1Bytes(dstPtr, srcPtr);
          }
        } else {
          if (endPtr.toWord().and(Word.fromIntZeroExtend(2)).NE(Word.zero())) {
            copy2Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(2);
            dstPtr = dstPtr.plus(2);
          }
          if (endPtr.toWord().and(Word.fromIntZeroExtend(1)).NE(Word.zero())) {
            copy1Bytes(dstPtr, srcPtr);
          }
        }
      } else {
        Address endPtr = srcPtr.plus(copyBytes);
        while (srcPtr.LT(endPtr)) {
          dstPtr.store(srcPtr.loadByte());
          srcPtr = srcPtr.plus(1);
          dstPtr = dstPtr.plus(1);
        }
      }
    }
  }