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; }
/** * 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); } } } }