public static UnalignedCopy64 ( byte source, int sourceIndex, byte dest, int destIndex ) : void | ||
source | byte | The source array. |
sourceIndex | int | Index to start copying. |
dest | byte | The destination array. |
destIndex | int | Index to start writing. |
return | void |
internal int EmitLiteral(byte[] output, int outputIndex, byte[] literal, int literalIndex, int length, bool allowFastPath) { int n = length - 1; outputIndex = EmitLiteralTag(output, outputIndex, n); if (allowFastPath && length <= 16) { Utilities.UnalignedCopy64(literal, literalIndex, output, outputIndex); Utilities.UnalignedCopy64(literal, literalIndex + 8, output, outputIndex + 8); return(outputIndex + length); } Buffer.BlockCopy(literal, literalIndex, output, outputIndex, length); return(outputIndex + length); }
private static void IncrementalCopyFastPath(byte[] output, int srcIndex, int opIndex, int length) { int copiedLength = 0; while ((opIndex + copiedLength) - srcIndex < 8) { Utilities.UnalignedCopy64(output, srcIndex, output, opIndex + copiedLength); copiedLength += (opIndex + copiedLength) - srcIndex; } for (int i = 0; i < length - copiedLength; i += 8) { Utilities.UnalignedCopy64(output, srcIndex + i, output, opIndex + copiedLength + i); } }
private static void CopyLiteral(byte[] input, int ipIndex, byte[] output, int opIndex, int length) { Debug.Assert(length > 0); Debug.Assert(ipIndex >= 0); Debug.Assert(opIndex >= 0); int spaceLeft = output.Length - opIndex; int readableBytes = input.Length - ipIndex; if (readableBytes < length || spaceLeft < length) { throw new InvalidOperationException("Corrupt literal length"); } if (length <= 16 && spaceLeft >= 16 && readableBytes >= 16) { Utilities.UnalignedCopy64(input, ipIndex, output, opIndex); Utilities.UnalignedCopy64(input, ipIndex + 8, output, opIndex + 8); } else { int fastLength = (int)(length & 0xFFFFFFF8); if (fastLength <= 64) { // copy long-by-long for (int i = 0; i < fastLength; i += 8) { Utilities.UnalignedCopy64(input, ipIndex + i, output, opIndex + i); } // copy byte-by-byte int slowLength = length & 0x7; // NOTE: This is not a manual array copy. We are copying an overlapping region // and we want input data to repeat as it is recopied. see incrementalCopy below. for (int i = 0; i < slowLength; i += 1) { output[opIndex + fastLength + i] = input[ipIndex + fastLength + i]; } } else { Buffer.BlockCopy(input, ipIndex, output, opIndex, length); } } }
private static void CopyCopy(byte[] output, int length, int opIndex, int outputLimit, int copyOffset) { int spaceLeft = outputLimit - opIndex; int srcIndex = opIndex - copyOffset; if (length <= 16 && copyOffset >= 8 && spaceLeft >= 16) { // Fast path, used for the majority (70-80%) of dynamic invocations. Utilities.UnalignedCopy64(output, srcIndex, output, opIndex); Utilities.UnalignedCopy64(output, srcIndex + 8, output, opIndex + 8); } else if (spaceLeft >= length + MAX_INCREMENT_COPY_OVERFLOW) { IncrementalCopyFastPath(output, srcIndex, opIndex, length); } else { IncrementalCopy(output, srcIndex, output, opIndex, length); } }