From: Jan Kotas Date: Tue, 21 Nov 2017 19:20:00 +0000 (-0800) Subject: Move SafeBuffer and a few other files to shared CoreLib partition (#15141) X-Git-Tag: accepted/tizen/base/20180629.140029~503 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=60222780cde77346bff1eb8979846769c223f833;p=platform%2Fupstream%2Fcoreclr.git Move SafeBuffer and a few other files to shared CoreLib partition (#15141) --- diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj index e39b73e..9dd49af 100644 --- a/src/mscorlib/System.Private.CoreLib.csproj +++ b/src/mscorlib/System.Private.CoreLib.csproj @@ -153,12 +153,10 @@ - - @@ -176,9 +174,6 @@ - - - @@ -499,7 +494,6 @@ - @@ -546,8 +540,7 @@ - - + @@ -607,7 +600,6 @@ - diff --git a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems index ab7dc93..f1eeb04 100644 --- a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems +++ b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems @@ -400,6 +400,7 @@ + @@ -414,10 +415,12 @@ + + @@ -512,6 +515,7 @@ + @@ -704,13 +708,14 @@ - + + diff --git a/src/mscorlib/shared/System/Runtime/ExceptionServices/ExceptionNotification.cs b/src/mscorlib/shared/System/Runtime/ExceptionServices/ExceptionNotification.cs new file mode 100644 index 0000000..605588d --- /dev/null +++ b/src/mscorlib/shared/System/Runtime/ExceptionServices/ExceptionNotification.cs @@ -0,0 +1,18 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Runtime.ExceptionServices +{ + // Definition of the argument-type passed to the FirstChanceException event handler + public class FirstChanceExceptionEventArgs : EventArgs + { + public FirstChanceExceptionEventArgs(Exception exception) + { + Exception = exception; + } + + // Returns the exception object pertaining to the first chance exception + public Exception Exception { get; } + } +} diff --git a/src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs b/src/mscorlib/shared/System/Runtime/InteropServices/MarshalDirectiveException.cs similarity index 100% rename from src/mscorlib/src/System/Runtime/InteropServices/MarshalDirectiveException.cs rename to src/mscorlib/shared/System/Runtime/InteropServices/MarshalDirectiveException.cs diff --git a/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs b/src/mscorlib/shared/System/Runtime/InteropServices/SafeBuffer.cs similarity index 78% rename from src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs rename to src/mscorlib/shared/System/Runtime/InteropServices/SafeBuffer.cs index 0447ea5..4632b2a 100644 --- a/src/mscorlib/src/System/Runtime/InteropServices/SafeBuffer.cs +++ b/src/mscorlib/shared/System/Runtime/InteropServices/SafeBuffer.cs @@ -4,16 +4,16 @@ /*============================================================ ** -** Purpose: Unsafe code that uses pointers should use -** SafePointer to fix subtle lifetime problems with the +** Purpose: Unsafe code that uses pointers should use +** SafePointer to fix subtle lifetime problems with the ** underlying resource. ** ===========================================================*/ // Design points: -// *) Avoid handle-recycling problems (including ones triggered via +// *) Avoid handle-recycling problems (including ones triggered via // resurrection attacks) for all accesses via pointers. This requires tying -// together the lifetime of the unmanaged resource with the code that reads +// together the lifetime of the unmanaged resource with the code that reads // from that resource, in a package that uses synchronization to enforce // the correct semantics during finalization. We're using SafeHandle's // ref count as a gate on whether the pointer can be dereferenced because that @@ -24,23 +24,23 @@ // will already require 2 additional interlocked operations. If we add in // a "current position" concept, that requires additional space in memory and // synchronization. Since the position in memory is often (but not always) -// something that can be stored on the stack, we can save some memory by -// excluding it from this object. However, avoiding the need for -// synchronization is a more significant win. This design allows multiple -// threads to read and write memory simultaneously without locks (as long as -// you don't write to a region of memory that overlaps with what another +// something that can be stored on the stack, we can save some memory by +// excluding it from this object. However, avoiding the need for +// synchronization is a more significant win. This design allows multiple +// threads to read and write memory simultaneously without locks (as long as +// you don't write to a region of memory that overlaps with what another // thread is accessing). -// +// // *) Space-wise, we use the following memory, including SafeHandle's fields: // Object Header MT* handle int bool bool <2 pad bytes> length // On 32 bit platforms: 24 bytes. On 64 bit platforms: 40 bytes. // (We can safe 4 bytes on x86 only by shrinking SafeHandle) // // *) Wrapping a SafeHandle would have been a nice solution, but without an -// ordering between critical finalizable objects, it would have required -// changes to each SafeHandle subclass to opt in to being usable from a +// ordering between critical finalizable objects, it would have required +// changes to each SafeHandle subclass to opt in to being usable from a // SafeBuffer (or some clever exposure of SafeHandle's state fields and a -// way of forcing ReleaseHandle to run even after the SafeHandle has been +// way of forcing ReleaseHandle to run even after the SafeHandle has been // finalized with a ref count > 1). We can use less memory and create fewer // objects by simply inserting a SafeBuffer into the class hierarchy. // @@ -65,14 +65,10 @@ // static variable (perhaps using Interlocked.CompareExchange). Of course, // assignments in a static class constructor are under a lock implicitly. - using System; -using System.Runtime.InteropServices; +using System.Diagnostics; using System.Runtime.CompilerServices; -using System.Runtime.ConstrainedExecution; -using System.Runtime.Versioning; using Microsoft.Win32.SafeHandles; -using System.Diagnostics; namespace System.Runtime.InteropServices { @@ -90,7 +86,7 @@ namespace System.Runtime.InteropServices } /// - /// Specifies the size of the region of memory, in bytes. Must be + /// Specifies the size of the region of memory, in bytes. Must be /// called before using the SafeBuffer. /// /// Number of valid bytes in memory. @@ -107,7 +103,7 @@ namespace System.Runtime.InteropServices } /// - /// Specifies the size of the region in memory, as the number of + /// Specifies the size of the region in memory, as the number of /// elements in an array. Must be called before using the SafeBuffer. /// [CLSCompliant(false)] @@ -123,7 +119,7 @@ namespace System.Runtime.InteropServices } /// - /// Specifies the size of the region in memory, as the number of + /// Specifies the size of the region in memory, as the number of /// elements in an array. Must be called before using the SafeBuffer. /// [CLSCompliant(false)] @@ -133,13 +129,12 @@ namespace System.Runtime.InteropServices } // Callers should ensure that they check whether the pointer ref param - // is null when AcquirePointer returns. If it is not null, they must - // call ReleasePointer in a CER. This method calls DangerousAddRef - // & exposes the pointer. Unlike Read, it does not alter the "current + // is null when AcquirePointer returns. If it is not null, they must + // call ReleasePointer. This method calls DangerousAddRef + // & exposes the pointer. Unlike Read, it does not alter the "current // position" of the pointer. Here's how to use it: // // byte* pointer = null; - // RuntimeHelpers.PrepareConstrainedRegions(); // try { // safeBuffer.AcquirePointer(ref pointer); // // Use pointer here, with your own bounds checking @@ -149,15 +144,15 @@ namespace System.Runtime.InteropServices // safeBuffer.ReleasePointer(); // } // - // Note: If you cast this byte* to a T*, you have to worry about + // Note: If you cast this byte* to a T*, you have to worry about // whether your pointer is aligned. Additionally, you must take // responsibility for all bounds checking with this pointer. /// /// Obtain the pointer from a SafeBuffer for a block of code, - /// with the express responsibility for bounds checking and calling - /// ReleasePointer later within a CER to ensure the pointer can be - /// freed later. This method either completes successfully or - /// throws an exception and returns with pointer set to null. + /// with the express responsibility for bounds checking and calling + /// ReleasePointer later to ensure the pointer can be freed later. + /// This method either completes successfully or throws an exception + /// and returns with pointer set to null. /// /// A byte*, passed by reference, to receive /// the pointer from within the SafeBuffer. You must set @@ -169,7 +164,6 @@ namespace System.Runtime.InteropServices throw NotInitialized(); pointer = null; - RuntimeHelpers.PrepareConstrainedRegions(); bool junk = false; DangerousAddRef(ref junk); @@ -189,7 +183,7 @@ namespace System.Runtime.InteropServices /// equivalent to: return *(T*)(bytePtr + byteOffset); /// /// The value type to read - /// Where to start reading from memory. You + /// Where to start reading from memory. You /// may have to consider alignment. /// An instance of T read from memory. [CLSCompliant(false)] @@ -203,14 +197,14 @@ namespace System.Runtime.InteropServices SpaceCheck(ptr, sizeofT); // return *(T*) (_ptr + byteOffset); - T value; + T value = default(T); bool mustCallRelease = false; - RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustCallRelease); - GenericPtrToStructure(ptr, out value, sizeofT); + fixed (byte* pStructure = &Unsafe.As(ref value)) + Buffer.Memmove(pStructure, ptr, sizeofT); } finally { @@ -242,13 +236,21 @@ namespace System.Runtime.InteropServices SpaceCheck(ptr, checked((ulong)(alignedSizeofT * count))); bool mustCallRelease = false; - RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustCallRelease); - for (int i = 0; i < count; i++) - unsafe { GenericPtrToStructure(ptr + alignedSizeofT * i, out array[i + index], sizeofT); } + if (count > 0) + { + unsafe + { + fixed (byte* pStructure = &Unsafe.As(ref array[index])) + { + for (int i = 0; i < count; i++) + Buffer.Memmove(pStructure + sizeofT * i, ptr + alignedSizeofT * i, sizeofT); + } + } + } } finally { @@ -262,7 +264,7 @@ namespace System.Runtime.InteropServices /// equivalent to: *(T*)(bytePtr + byteOffset) = value; /// /// The type of the value type to write to memory. - /// The location in memory to write to. You + /// The location in memory to write to. You /// may have to consider alignment. /// The value type to write to memory. [CLSCompliant(false)] @@ -277,11 +279,12 @@ namespace System.Runtime.InteropServices // *((T*) (_ptr + byteOffset)) = value; bool mustCallRelease = false; - RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustCallRelease); - GenericStructureToPtr(ref value, ptr, sizeofT); + + fixed (byte* pStructure = &Unsafe.As(ref value)) + Buffer.Memmove(ptr, pStructure, sizeofT); } finally { @@ -312,12 +315,21 @@ namespace System.Runtime.InteropServices SpaceCheck(ptr, checked((ulong)(alignedSizeofT * count))); bool mustCallRelease = false; - RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustCallRelease); - for (int i = 0; i < count; i++) - unsafe { GenericStructureToPtr(ref array[i + index], ptr + alignedSizeofT * i, sizeofT); } + + if (count > 0) + { + unsafe + { + fixed (byte* pStructure = &Unsafe.As(ref array[index])) + { + for (int i = 0; i < count; i++) + Buffer.Memmove(ptr + alignedSizeofT * i, pStructure + sizeofT * i, sizeofT); + } + } + } } finally { @@ -326,7 +338,6 @@ namespace System.Runtime.InteropServices } } - /// /// Returns the number of bytes in the memory region. /// @@ -342,7 +353,7 @@ namespace System.Runtime.InteropServices } } - /* No indexer. The perf would be misleadingly bad. People should use + /* No indexer. The perf would be misleadingly bad. People should use * AcquirePointer and ReleasePointer instead. */ private void SpaceCheck(byte* ptr, ulong sizeInBytes) @@ -363,62 +374,31 @@ namespace System.Runtime.InteropServices return new InvalidOperationException(SR.InvalidOperation_MustCallInitialize); } - // FCALL limitations mean we can't have generic FCALL methods. However, we can pass - // TypedReferences to FCALL methods. - internal static void GenericPtrToStructure(byte* ptr, out T structure, uint sizeofT) where T : struct - { - structure = default(T); // Dummy assignment to silence the compiler - PtrToStructureNative(ptr, __makeref(structure), sizeofT); - } - - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void PtrToStructureNative(byte* ptr, /*out T*/ TypedReference structure, uint sizeofT); - - internal static void GenericStructureToPtr(ref T structure, byte* ptr, uint sizeofT) where T : struct - { - StructureToPtrNative(__makeref(structure), ptr, sizeofT); - } - - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern void StructureToPtrNative(/*ref T*/ TypedReference structure, byte* ptr, uint sizeofT); - - /// - /// Returns the aligned size of an instance of a value type. - /// - /// Provide a value type to figure out its size - /// The aligned size of T in bytes. - internal static uint SizeOf() where T : struct - { - return SizeOfType(typeof(T)); - } - /// - /// Returns the aligned size of an instance of a value type. + /// Returns the size that SafeBuffer (and hence, UnmanagedMemoryAccessor) reserves in the unmanaged buffer for each element of an array of T. This is not the same + /// value that sizeof(T) returns! Since the primary use case is to parse memory mapped files, we cannot change this algorithm as this defines a de-facto serialization format. + /// Throws if T contains GC references. /// - /// Provide a value type to figure out its size - /// The aligned size of T in bytes. internal static uint AlignedSizeOf() where T : struct { - uint size = SizeOfType(typeof(T)); + uint size = SizeOf(); if (size == 1 || size == 2) { return size; } - if (IntPtr.Size == 8 && size == 4) - { - return size; - } - return AlignedSizeOfType(typeof(T)); + + return (uint)(((size + 3) & (~3))); } - // Type must be a value type with no object reference fields. We only - // assert this, due to the lack of a suitable generic constraint. - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern uint SizeOfType(Type type); + /// + /// Returns same value as sizeof(T) but throws if T contains GC references. + /// + internal static uint SizeOf() where T : struct + { + if (RuntimeHelpers.IsReferenceOrContainsReferences()) + throw new ArgumentException(SR.Argument_NeedStructWithNoRefs); - // Type must be a value type with no object reference fields. We only - // assert this, due to the lack of a suitable generic constraint. - [MethodImpl(MethodImplOptions.InternalCall)] - private static extern uint AlignedSizeOfType(Type type); + return (uint)Unsafe.SizeOf(); + } } } diff --git a/src/mscorlib/src/System/Text/Normalization.Unix.cs b/src/mscorlib/shared/System/Text/Normalization.Unix.cs similarity index 100% rename from src/mscorlib/src/System/Text/Normalization.Unix.cs rename to src/mscorlib/shared/System/Text/Normalization.Unix.cs diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs b/src/mscorlib/shared/System/Threading/Tasks/TaskCompletionSource.cs similarity index 100% rename from src/mscorlib/src/System/Threading/Tasks/TaskCompletionSource.cs rename to src/mscorlib/shared/System/Threading/Tasks/TaskCompletionSource.cs diff --git a/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs b/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs similarity index 100% rename from src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionServicesCommon.cs rename to src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionDispatchInfo.cs diff --git a/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs b/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs deleted file mode 100644 index d986ea9..0000000 --- a/src/mscorlib/src/System/Runtime/ExceptionServices/ExceptionNotification.cs +++ /dev/null @@ -1,37 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. -/*============================================================================= -** -** -** -** Purpose: Contains definitions for supporting Exception Notifications. -** -** Created: 10/07/2008 -** -** -=============================================================================*/ -using System; -using System.Runtime.ConstrainedExecution; - -namespace System.Runtime.ExceptionServices -{ - // Definition of the argument-type passed to the FirstChanceException event handler - public class FirstChanceExceptionEventArgs : EventArgs - { - // Constructor - public FirstChanceExceptionEventArgs(Exception exception) - { - m_Exception = exception; - } - - // Returns the exception object pertaining to the first chance exception - public Exception Exception - { - get { return m_Exception; } - } - - // Represents the FirstChance exception instance - private Exception m_Exception; - } -} diff --git a/src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs b/src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs deleted file mode 100644 index 85756cf..0000000 --- a/src/mscorlib/src/System/Runtime/InteropServices/ITypeLibConverter.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================================= -** -** -** -** Purpose: Methods used to convert a TypeLib to metadata and vice versa. -** -** -=============================================================================*/ - -// *************************************************************************** -// *** Note: The following definitions must remain synchronized with the IDL -// *** in src/inc/TlbImpExp.idl. -// *************************************************************************** - - -using System; -using System.Reflection; -using System.Reflection.Emit; - -namespace System.Runtime.InteropServices -{ -} diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h index 207e89a..14ce9dd 100644 --- a/src/vm/ecalllist.h +++ b/src/vm/ecalllist.h @@ -198,13 +198,6 @@ FCFuncStart(gCriticalHandleFuncs) FCFuncElement("FireCustomerDebugProbe", CriticalHandle::FireCustomerDebugProbe) FCFuncEnd() -FCFuncStart(gSafeBufferFuncs) - FCFuncElement("PtrToStructureNative", SafeBuffer::PtrToStructure) - FCFuncElement("StructureToPtrNative", SafeBuffer::StructureToPtr) - FCFuncElement("SizeOfType", SafeBuffer::SizeOfType) - FCFuncElement("AlignedSizeOfType", SafeBuffer::AlignedSizeOfType) -FCFuncEnd() - FCFuncStart(gTypedReferenceFuncs) FCFuncElement("InternalToObject", ReflectionInvocation::TypedReferenceToObject) FCFuncElement("InternalSetTypedReference", ReflectionInvocation::SetTypedReference) @@ -1386,7 +1379,6 @@ FCClassElement("RuntimeModule", "System.Reflection", gCOMModuleFuncs) FCClassElement("RuntimeThread", "Internal.Runtime.Augments", gRuntimeThreadFuncs) FCClassElement("RuntimeType", "System", gSystem_RuntimeType) FCClassElement("RuntimeTypeHandle", "System", gCOMTypeHandleFuncs) -FCClassElement("SafeBuffer", "System.Runtime.InteropServices", gSafeBufferFuncs) FCClassElement("SafeHandle", "System.Runtime.InteropServices", gSafeHandleFuncs) FCClassElement("SafeTypeNameParserHandle", "System", gSafeTypeNameParserHandle) diff --git a/src/vm/nativeoverlapped.h b/src/vm/nativeoverlapped.h index 0c0693d..7f12f47 100644 --- a/src/vm/nativeoverlapped.h +++ b/src/vm/nativeoverlapped.h @@ -21,8 +21,7 @@ class OverlappedDataObject : public Object { public: - ASYNCRESULTREF m_asyncResult; - + OBJECTREF m_asyncResult; OBJECTREF m_iocb; OBJECTREF m_iocbHelper; OBJECTREF m_overlapped; diff --git a/src/vm/object.h b/src/vm/object.h index 0fdcff3..a79e846 100644 --- a/src/vm/object.h +++ b/src/vm/object.h @@ -2955,20 +2955,6 @@ class CriticalHandle : public Object }; -class ReflectClassBaseObject; - -class SafeBuffer : SafeHandle -{ - private: - size_t m_numBytes; - - public: - static FCDECL1(UINT, SizeOfType, ReflectClassBaseObject* typeUNSAFE); - static FCDECL1(UINT, AlignedSizeOfType, ReflectClassBaseObject* typeUNSAFE); - static FCDECL3_IVI(void, PtrToStructure, BYTE* ptr, FC_TypedByRef structure, UINT32 sizeofT); - static FCDECL3_VII(void, StructureToPtr, FC_TypedByRef structure, BYTE* ptr, UINT32 sizeofT); -}; - #ifdef USE_CHECKED_OBJECTREFS typedef REF CRITICALHANDLE; typedef REF CRITICALHANDLEREF; @@ -3000,44 +2986,6 @@ typedef REF WAITHANDLEREF; typedef WaitHandleBase* WAITHANDLEREF; #endif // USE_CHECKED_OBJECTREFS -// This class corresponds to FileStreamAsyncResult on the managed side. -class AsyncResultBase :public Object -{ - friend class MscorlibBinder; - -public: - WAITHANDLEREF GetWaitHandle() { LIMITED_METHOD_CONTRACT; return _waitHandle;} - void SetErrorCode(int errcode) { LIMITED_METHOD_CONTRACT; _errorCode = errcode;} - void SetNumBytes(int numBytes) { LIMITED_METHOD_CONTRACT; _numBytes = numBytes;} - void SetIsComplete() { LIMITED_METHOD_CONTRACT; _isComplete = TRUE; } - void SetCompletedAsynchronously() { LIMITED_METHOD_CONTRACT; _completedSynchronously = FALSE; } - - // README: - // If you modify the order of these fields, make sure to update the definition in - // BCL for this object. -private: - OBJECTREF _userCallback; - OBJECTREF _userStateObject; - - WAITHANDLEREF _waitHandle; - SAFEHANDLEREF _fileHandle; // For cancellation. - LPOVERLAPPED _overlapped; - int _EndXxxCalled; // Whether we've called EndXxx already. - int _numBytes; // number of bytes read OR written - int _errorCode; - int _numBufferedBytes; - - CLR_BOOL _isWrite; // Whether this is a read or a write - CLR_BOOL _isComplete; - CLR_BOOL _completedSynchronously; // Which thread called callback -}; - -#ifdef USE_CHECKED_OBJECTREFS -typedef REF ASYNCRESULTREF; -#else // USE_CHECKED_OBJECTREFS -typedef AsyncResultBase* ASYNCRESULTREF; -#endif // USE_CHECKED_OBJECTREFS - // This class corresponds to System.MulticastDelegate on the managed side. class DelegateObject : public Object { diff --git a/src/vm/safehandle.cpp b/src/vm/safehandle.cpp index 5e0626b..23e415d 100644 --- a/src/vm/safehandle.cpp +++ b/src/vm/safehandle.cpp @@ -438,60 +438,3 @@ FCIMPL1(void, CriticalHandle::FireCustomerDebugProbe, CriticalHandle* refThisUNS HELPER_METHOD_FRAME_END(); } FCIMPLEND - - -FCIMPL1(UINT, SafeBuffer::SizeOfType, ReflectClassBaseObject* typeUNSAFE) -{ - FCALL_CONTRACT; - - REFLECTCLASSBASEREF type(typeUNSAFE); - - MethodTable* pMT = type->GetType().AsMethodTable(); - - if (!pMT->IsValueType() || pMT->ContainsPointers()) - FCThrowArgument(W("type"), W("Argument_NeedStructWithNoRefs")); - - FC_GC_POLL_RET(); - - return pMT->GetNumInstanceFieldBytes(); -} -FCIMPLEND - -FCIMPL1(UINT, SafeBuffer::AlignedSizeOfType, ReflectClassBaseObject* typeUNSAFE) -{ - FCALL_CONTRACT; - - REFLECTCLASSBASEREF type(typeUNSAFE); - - MethodTable* pMT = type->GetType().AsMethodTable(); - - if (!pMT->IsValueType() || pMT->ContainsPointers()) - FCThrowArgument(W("type"), W("Argument_NeedStructWithNoRefs")); - - FC_GC_POLL_RET(); - - return pMT->GetAlignedNumInstanceFieldBytes(); -} -FCIMPLEND - -FCIMPL3_IVI(void, SafeBuffer::PtrToStructure, BYTE* ptr, FC_TypedByRef structure, UINT32 sizeofT) -{ - FCALL_CONTRACT; - - LPVOID structData = structure.data; - _ASSERTE(ptr != NULL && structData != NULL); - memcpyNoGCRefs(structData, ptr, sizeofT); - FC_GC_POLL(); -} -FCIMPLEND - -FCIMPL3_VII(void, SafeBuffer::StructureToPtr, FC_TypedByRef structure, BYTE* ptr, UINT32 sizeofT) -{ - FCALL_CONTRACT; - - LPVOID structData = structure.data; - _ASSERTE(ptr != NULL && structData != NULL); - memcpyNoGCRefs(ptr, structData, sizeofT); - FC_GC_POLL(); -} -FCIMPLEND