2008-11-17 18:29:00 -05:00
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
|
|
|
|
2008-03-05 09:52:00 -05:00
|
|
|
/*******************************************************************/
|
|
|
|
/* WARNING */
|
|
|
|
/* This file should be identical in the Bartok and Singularity */
|
|
|
|
/* depots. Master copy resides in Bartok Depot. Changes should be */
|
|
|
|
/* made to Bartok Depot and propagated to Singularity Depot. */
|
|
|
|
/*******************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
namespace System.GCs
|
|
|
|
{
|
|
|
|
using System.Runtime.CompilerServices;
|
|
|
|
|
|
|
|
// Util contains common functions for alignment and padding
|
|
|
|
// arithmetic and for calculating object sizes.
|
|
|
|
internal class Util
|
|
|
|
{
|
|
|
|
// WARNING: don't initialize any static fields in this class
|
|
|
|
// without manually running the class constructor at startup!
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
internal static uint dwordAlign(uint numBytes) {
|
|
|
|
return ((numBytes+3) & ~3U);
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
internal static UIntPtr dwordAlign(UIntPtr numBytes) {
|
|
|
|
return ((numBytes+3) & new UIntPtr(~3U));
|
|
|
|
}
|
|
|
|
|
|
|
|
[NoHeapAllocation]
|
|
|
|
static UIntPtr qwordAlign(UIntPtr addr) {
|
|
|
|
return ((addr+7) & new UIntPtr(~7U));
|
|
|
|
}
|
|
|
|
|
|
|
|
[Inline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
internal static bool IsAligned(uint bytes, uint size)
|
|
|
|
{
|
|
|
|
return (bytes & (size - 1)) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Inline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
internal static bool IsAligned(UIntPtr bytes, UIntPtr size)
|
|
|
|
{
|
|
|
|
return (bytes & (size - 1)) == UIntPtr.Zero;
|
|
|
|
}
|
|
|
|
|
|
|
|
[Inline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
internal static uint Align(uint bytes, uint size)
|
|
|
|
{
|
|
|
|
return (bytes & ~(size - 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
[Inline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
internal static UIntPtr Align(UIntPtr bytes, UIntPtr size)
|
|
|
|
{
|
|
|
|
return (bytes & ~(size - 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
[Inline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
internal static UIntPtr UIntPtrAlign(UIntPtr bytes)
|
|
|
|
{
|
|
|
|
return Align(bytes, (UIntPtr) UIntPtr.Size);
|
|
|
|
}
|
|
|
|
|
|
|
|
[Inline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
internal static uint Pad(uint data, uint size)
|
|
|
|
{
|
|
|
|
return ((data + (size - 1)) & ~(size - 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
[Inline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
internal static UIntPtr Pad(UIntPtr data, UIntPtr size)
|
|
|
|
{
|
|
|
|
return ((data + (size - 1)) & ~(size - 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
[Inline]
|
|
|
|
[NoHeapAllocation]
|
|
|
|
internal static UIntPtr UIntPtrPad(UIntPtr bytes)
|
|
|
|
{
|
|
|
|
return Pad(bytes, (UIntPtr) UIntPtr.Size);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal static unsafe void MemClear(UIntPtr startAddr,
|
|
|
|
UIntPtr size)
|
|
|
|
{
|
|
|
|
#if SINGULARITY
|
|
|
|
// On Singularity we use the common optimized functions.
|
|
|
|
Buffer.ZeroMemory((byte*)startAddr, (int)size);
|
|
|
|
#else
|
|
|
|
VTable.Assert(UIntPtr.Size !=4 || ((startAddr & ((UIntPtr)0x3)) == ((UIntPtr)0)), "Not-aligned address in Util.MemClear");
|
|
|
|
VTable.Assert(UIntPtr.Size !=8 || ((startAddr & ((UIntPtr)0x7)) == ((UIntPtr)0)), "Not-aligned address in Util.MemClear");
|
2008-11-17 18:29:00 -05:00
|
|
|
VTable.Assert((size & ((UIntPtr)0x3)) == ((UIntPtr)0), "size expected to be multiple of 4 (size of int) in Util.MemClear");
|
2008-03-05 09:52:00 -05:00
|
|
|
Buffer.ZeroMemory((byte*)startAddr, size);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
internal static unsafe void MemCopy(UIntPtr toAddress,
|
|
|
|
UIntPtr fromAddress,
|
|
|
|
UIntPtr count)
|
|
|
|
{
|
|
|
|
#if SINGULARITY
|
|
|
|
// On Singularity we use the common optimized functions.
|
|
|
|
Buffer.MoveMemory((byte*)toAddress, (byte*)fromAddress, (int)count);
|
|
|
|
#else
|
|
|
|
int wordCount = (int) (count >> 2);
|
|
|
|
int *from = (int *) fromAddress;
|
|
|
|
int *to = (int *) toAddress;
|
|
|
|
for (int i = 0; i < wordCount; i++) {
|
|
|
|
to[i] = from[i];
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
internal static void PrintPageContents(UIntPtr page)
|
|
|
|
{
|
|
|
|
UIntPtr startAddr = PageTable.PageAddr(page);
|
|
|
|
UIntPtr endAddr = PageTable.PageAddr(page + 1);
|
|
|
|
PrintMemoryContents(startAddr, endAddr);
|
|
|
|
}
|
|
|
|
|
|
|
|
internal static unsafe void PrintMemoryContents(UIntPtr startAddr,
|
|
|
|
UIntPtr endAddr)
|
|
|
|
{
|
|
|
|
if (UIntPtr.Size == 4) {
|
|
|
|
VTable.DebugPrint("Memory contents for {0,8:x8}..{1,8:x8}\n",
|
|
|
|
__arglist(startAddr, endAddr));
|
|
|
|
for (UIntPtr addr = startAddr; addr < endAddr; addr += 32) {
|
|
|
|
UIntPtr *ptr = (UIntPtr *) addr;
|
|
|
|
// Only print 6 digits of the address in order to
|
|
|
|
// fit on 80 column output devices
|
|
|
|
uint printAddress = unchecked((uint) addr) & 0xffffff;
|
|
|
|
VTable.DebugPrint("{0,6:x6}: "+
|
|
|
|
"{1,8:x8} {2,8:x8} {3,8:x8} {4,8:x8} "+
|
|
|
|
"{5,8:x8} {6,8:x8} {7,8:x8} {8,8:x8}\n",
|
|
|
|
__arglist(printAddress, *ptr, *(ptr+1),
|
|
|
|
*(ptr+2), *(ptr+3), *(ptr+4),
|
|
|
|
*(ptr+5), *(ptr+6), *(ptr+7)));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
VTable.DebugPrint("Memory contents for "+
|
|
|
|
"{0,16:x16}..{1,16:x16}\n",
|
|
|
|
__arglist(startAddr, endAddr));
|
|
|
|
for (UIntPtr addr = startAddr; addr < endAddr; addr += 32) {
|
|
|
|
UIntPtr *ptr = (UIntPtr *) addr;
|
|
|
|
uint printAddress = unchecked((uint) addr);
|
|
|
|
VTable.DebugPrint("{0,8:x8}: {1,16:x16} {2,16:x16} "+
|
|
|
|
"{3,16:x16} {4,16:x16}\n",
|
|
|
|
__arglist(printAddress, *ptr,
|
|
|
|
*(ptr+1), *(ptr+2), *(ptr+3)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-05 09:52:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|