示例#1
0
        // A very simple and efficient array copy that assumes all of the
        // parameter validation has already been done.  All counts here are
        // in bytes.
        internal static unsafe void InternalBlockCopy(Array src, int srcOffset,
                                                      Array dst, int dstOffset,
                                                      int count)
        {
            VTable.Assert(src != null);
            VTable.Assert(dst != null);

            // Unfortunately, we must do a check to make sure we're writing
            // within the bounds of the array.  This will ensure that we don't
            // overwrite memory elsewhere in the system nor do we write out junk.
            // This can happen if multiple threads screw with our IO classes
            // simultaneously without being threadsafe.  Throw here.
            int srcLen = src.Length * src.vtable.arrayElementSize;

            if (srcOffset < 0 || dstOffset < 0 || count < 0 ||
                srcOffset > srcLen - count)
            {
                throw new IndexOutOfRangeException
                          ("IndexOutOfRange_IORaceCondition");
            }
            if (src == dst)
            {
                if (dstOffset > srcLen - count)
                {
                    throw new IndexOutOfRangeException
                              ("IndexOutOfRange_IORaceCondition");
                }
            }
            else
            {
                int dstLen = dst.Length * dst.vtable.arrayElementSize;
                if (dstOffset > dstLen - count)
                {
                    throw new IndexOutOfRangeException
                              ("IndexOutOfRange_IORaceCondition");
                }
            }

            // Copy the data.
            // Call our faster version of memmove, not the CRT one.
            fixed(int *srcFieldPtr = &src.field1)
            {
                fixed(int *dstFieldPtr = &dst.field1)
                {
                    byte *srcPtr = (byte *)
                                   src.GetFirstElementAddress(srcFieldPtr);
                    byte *dstPtr = (byte *)
                                   dst.GetFirstElementAddress(dstFieldPtr);

                    MoveMemory(dstPtr + dstOffset, srcPtr + srcOffset, count);
                }
            }
        }
示例#2
0
        private unsafe static void CloneVectorContents(Array srcArray,
                                                       Array dstArray)
        {
            int srcLength = srcArray.Length;

            fixed(int *srcFieldPtr = &srcArray.field1)
            {
                fixed(int *dstFieldPtr = &dstArray.field1)
                {
                    byte *srcDataPtr = (byte *)
                                       srcArray.GetFirstElementAddress(srcFieldPtr);
                    byte *dstDataPtr = (byte *)
                                       dstArray.GetFirstElementAddress(dstFieldPtr);
                    int size = srcArray.vtable.arrayElementSize * srcLength;

                    Buffer.MoveMemory(dstDataPtr, srcDataPtr, size);
                }
            }
        }
示例#3
0
        private unsafe static void CloneArrayContents(Array srcArray,
                                                      Array dstArray)
        {
            int srcLength = srcArray.Length;

            fixed(int *srcFieldPtr = &srcArray.field1)
            {
                fixed(int *dstFieldPtr = &dstArray.field1)
                {
                    byte *srcDataPtr = (byte *)
                                       srcArray.GetFirstElementAddress(srcFieldPtr);
                    byte *dstDataPtr = (byte *)
                                       dstArray.GetFirstElementAddress(dstFieldPtr);
                    byte *srcDimPtr = (byte *)
                                      srcArray.GetFirstDimInfoRectangleArray();
                    int dimInfoSize = (int)(srcDataPtr - srcDimPtr);
                    int size        = srcArray.vtable.arrayElementSize * srcLength;

                    Buffer.MoveMemory(dstDataPtr - dimInfoSize,
                                      srcDataPtr - dimInfoSize,
                                      size + dimInfoSize);
                }
            }
        }
示例#4
0
        public static unsafe void InitArray(System.Array srcArray,
                                            System.Array dstArray)
        {
#if !REFERENCE_COUNTING_GC && !DEFERRED_REFERENCE_COUNTING_GC
            Barrier.ArrayCopy(srcArray, 0, dstArray, 0, srcArray.Length);
#else
            fixed(int *srcFieldPtr = &srcArray.field1)
            {
                void *src = srcArray.GetFirstElementAddress(srcFieldPtr);

                fixed(int *dstFieldPtr = &dstArray.field1)
                {
                    void *dst  = dstArray.GetFirstElementAddress(dstFieldPtr);
                    int   size = (srcArray.vtable.arrayElementSize *
                                  srcArray.Length);

#if REFERENCE_COUNTING_GC
                    if (dstArray.vtable.arrayOf ==
                        StructuralType.Reference ||
                        dstArray.vtable.arrayOf ==
                        StructuralType.Struct)
                    {
                        int dstLength =
                            size / dstArray.vtable.arrayElementSize;
                        GCs.ReferenceCountingCollector.
                        IncrementReferentRefCounts(Magic.addressOf(srcArray),
                                                   srcArray.vtable,
                                                   0,
                                                   srcArray.Length);
                        GCs.ReferenceCountingCollector.
                        DecrementReferentRefCounts(Magic.addressOf(dstArray),
                                                   dstArray.vtable,
                                                   0,
                                                   dstLength);
                    }
#elif DEFERRED_REFERENCE_COUNTING_GC
                    if (dstArray.vtable.arrayOf ==
                        StructuralType.Reference ||
                        dstArray.vtable.arrayOf ==
                        StructuralType.Struct)
                    {
                        int dstLength =
                            size / dstArray.vtable.arrayElementSize;
                        GCs.DeferredReferenceCountingCollector.
                        IncrementReferentRefCounts(Magic.addressOf(srcArray),
                                                   srcArray.vtable,
                                                   0,
                                                   srcArray.Length);
                        GCs.DeferredReferenceCountingCollector.
                        DecrementReferentRefCounts(Magic.addressOf(dstArray),
                                                   dstArray.vtable,
                                                   0,
                                                   dstLength);
                    }
#endif // REFERENCE_COUNTING_GC
                    System.IO.__UnmanagedMemoryStream.memcpyimpl
                        ((byte *)src, (byte *)dst, size);
                }
            }
#endif // REFERENCE_COUNTING_GC
        }