public static IntPtr AllocateArray(RuntimeTypeHandle handle, uint elementSize, uint elements) { // An array has the following memory layout: // - IntPtr TypeDef // - IntPtr SyncBlock // - int length // - ElementType[length] elements // - Padding uint allocationSize = ((uint)(IntPtr.Size) * 3) + (elements * elementSize); allocationSize = (allocationSize + 3) & ~3u; // Align to 4-bytes boundary var memory = GC.AllocateObject(allocationSize); Intrinsic.Store(memory, 0, handle.Value); if (IntPtr.Size == 4) { Intrinsic.Store32(memory, IntPtr.Size, 0); Intrinsic.Store32(memory, IntPtr.Size * 2, elements); } else { Intrinsic.Store64(memory, IntPtr.Size, 0); Intrinsic.Store64(memory, IntPtr.Size * 2, elements); } return(memory); }
public static void MemorySet(IntPtr dest, uint value, uint count) { // FUTURE: Improve for (int i = 0; i < count; i = i + 4) { Intrinsic.Store32(dest, i, value); } }
public static IntPtr Box32(RuntimeTypeHandle handle, uint value) { var memory = AllocateObject(handle, IntPtr.Size); Intrinsic.Store(memory, 0, handle.Value); Intrinsic.Store32(memory, IntPtr.Size * 2, value); return(memory); }
public static IntPtr AllocateObject(RuntimeTypeHandle handle, uint classSize) { // An object has the following memory layout: // - IntPtr TypeDef // - IntPtr SyncBlock // - 0 .. n object data fields var memory = GC.AllocateObject((2 * (uint)(IntPtr.Size)) + classSize); Intrinsic.Store(memory, 0, handle.Value); if (IntPtr.Size == 4) { Intrinsic.Store32(memory, IntPtr.Size, 0); } else { Intrinsic.Store64(memory, IntPtr.Size, 0); } return(memory); }
public void Store32(uint value) { Intrinsic.Store32(this, value); }
public void Store32(int offset, int value) { Intrinsic.Store32(this, offset, value); }