Esempio n. 1
0
 /**
  * Copy numbytes from src to dst. Assumption either the ranges are non overlapping, or src >= dst
  * + 4. Also, src and dst are 4 byte aligned and numBytes is a multiple of 4.
  *
  * @param dst the destination addr
  * @param src the source addr
  * @param numBytes the number of bytes top copy
  */
 @Inline
 public static void aligned32Copy(Address dst, Address src, Offset numBytes) {
   if (USE_NATIVE && numBytes.sGT(Offset.fromIntSignExtend(NATIVE_THRESHOLD))) {
     memcopy(dst, src, numBytes.toWord().toExtent());
   } else {
     if (VM.BuildFor64Addr) {
       Word wordMask = Word.one().lsh(LOG_BYTES_IN_ADDRESS).minus(Word.one());
       Word srcAlignment = src.toWord().and(wordMask);
       if (srcAlignment.EQ(dst.toWord().and(wordMask))) {
         Offset i = Offset.zero();
         if (srcAlignment.EQ(Word.fromIntZeroExtend(BYTES_IN_INT))) {
           dst.store(src.loadInt(i), i);
           i = i.plus(BYTES_IN_INT);
         }
         Word endAlignment =
             srcAlignment.plus(numBytes).and(Word.fromIntSignExtend(BYTES_IN_ADDRESS - 1));
         numBytes = numBytes.minus(endAlignment.toOffset());
         for (; i.sLT(numBytes); i = i.plus(BYTES_IN_ADDRESS)) {
           dst.store(src.loadWord(i), i);
         }
         if (!endAlignment.isZero()) {
           dst.store(src.loadInt(i), i);
         }
         return;
       }
     }
     // normal case: 32 bit or (64 bit not aligned)
     for (Offset i = Offset.zero(); i.sLT(numBytes); i = i.plus(BYTES_IN_INT)) {
       dst.store(src.loadInt(i), i);
     }
   }
 }
 /**
  * Copy <code>numbytes</code> from <code>src</code> to <code>dst</code>. Assumption either the
  * ranges are non overlapping, or <code>src >= dst + BYTES_IN_ADDRESS</code>.
  *
  * @param dst The destination addr
  * @param src The source addr
  * @param numBytes The number of bytes to copy
  */
 private static void internalAlignedWordCopy(Address dst, Address src, int numBytes) {
   Address end = src.plus(numBytes);
   while (src.LT(end)) {
     dst.store(src.loadWord());
     src = src.plus(BYTES_IN_ADDRESS);
     dst = dst.plus(BYTES_IN_ADDRESS);
   }
 }
Esempio n. 3
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);
        }
      }
    }
  }
Esempio n. 4
0
  /**
   * Low level copy of len elements from src[srcPos] to dst[dstPos].
   *
   * <p>Assumption src != dst || (srcPos >= dstPos + 2).
   *
   * @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 arraycopy16Bit(Object src, int srcPos, Object dst, int dstPos, int len) {
    if (USE_NATIVE && len > (NATIVE_THRESHOLD >> LOG_BYTES_IN_SHORT)) {
      memcopy(
          VM_Magic.objectAsAddress(dst).plus(dstPos << LOG_BYTES_IN_SHORT),
          VM_Magic.objectAsAddress(src).plus(srcPos << LOG_BYTES_IN_SHORT),
          len << LOG_BYTES_IN_SHORT);
    } else {
      if (len >= (BYTES_IN_ADDRESS >>> LOG_BYTES_IN_SHORT)
          && (srcPos & ((BYTES_IN_ADDRESS - 1) >>> LOG_BYTES_IN_SHORT))
              == (dstPos & ((BYTES_IN_ADDRESS - 1) >>> LOG_BYTES_IN_SHORT))) {
        // relative alignment is the same
        int byteStart = srcPos << LOG_BYTES_IN_SHORT;
        int wordStart = alignUp(byteStart, BYTES_IN_ADDRESS);
        int wordEnd = alignDown(byteStart + (len << LOG_BYTES_IN_SHORT), BYTES_IN_ADDRESS);
        int byteEnd = byteStart + (len << LOG_BYTES_IN_SHORT);
        int startDiff = wordStart - byteStart;
        int endDiff = byteEnd - wordEnd;
        int wordLen = wordEnd - wordStart;
        Address srcPtr =
            VM_Magic.objectAsAddress(src).plus((srcPos << LOG_BYTES_IN_SHORT) + startDiff);
        Address dstPtr =
            VM_Magic.objectAsAddress(dst).plus((dstPos << LOG_BYTES_IN_SHORT) + startDiff);

        if (VM.BuildFor64Addr) {
          switch (startDiff) {
            case 6:
              dstPtr.store(
                  srcPtr.loadChar(Offset.fromIntSignExtend(-6)), Offset.fromIntSignExtend(-6));
            case 4:
              dstPtr.store(
                  srcPtr.loadChar(Offset.fromIntSignExtend(-4)), Offset.fromIntSignExtend(-4));
            case 2:
              dstPtr.store(
                  srcPtr.loadChar(Offset.fromIntSignExtend(-2)), Offset.fromIntSignExtend(-2));
          }
        } else {
          if (startDiff == 2) {
            dstPtr.store(
                srcPtr.loadChar(Offset.fromIntSignExtend(-2)), Offset.fromIntSignExtend(-2));
          }
        }

        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 6:
              dstPtr.store(
                  srcPtr.loadChar(Offset.fromIntSignExtend(4)), Offset.fromIntSignExtend(4));
            case 4:
              dstPtr.store(
                  srcPtr.loadChar(Offset.fromIntSignExtend(2)), Offset.fromIntSignExtend(2));
            case 2:
              dstPtr.store(srcPtr.loadChar());
          }
        } else {
          if (endDiff == 2) {
            dstPtr.store(srcPtr.loadChar());
          }
        }

      } else {
        Address srcPtr = VM_Magic.objectAsAddress(src).plus(srcPos << LOG_BYTES_IN_CHAR);
        Address dstPtr = VM_Magic.objectAsAddress(dst).plus(dstPos << LOG_BYTES_IN_CHAR);
        Address endPtr = srcPtr.plus(len << LOG_BYTES_IN_CHAR);
        while (srcPtr.LT(endPtr)) {
          dstPtr.store(srcPtr.loadChar());
          srcPtr = srcPtr.plus(2);
          dstPtr = dstPtr.plus(2);
        }
      }
    }
  }