diff --git a/Docs/Kernel/Memory.md b/Docs/Kernel/Memory.md index 3514da39e..9edb9f9e5 100644 --- a/Docs/Kernel/Memory.md +++ b/Docs/Kernel/Memory.md @@ -45,12 +45,18 @@ inline increases block size, but makes it faster to find metadata and keeps it u Could have a single pointer to another record elsewhere, but increases complexity and does not provide major benefit. -Data (handle pointer points here) --64 Ref count --64 Ptr to first ref --Optional - Stacked and single only - -64 Size (always need, cant interpolate even from slotted as may be smaller than slot) - -Always allocate bigger to word align (or page align for large?). Wont bother .NET, it never needs size from heap. - -If need actual size - could add 3 and mask lower 2 bits to round up. +-32/64 Ptr to first ref +using 32 below saves space on small/med objects. slightly increases access time, but access to these fields is not time critical +-32 (64 to align on large) Ref count +-32 (64 for large) Size (always need, cant interpolate even from slotted as may be smaller than slot) + -Always allocate bigger to word align (or page align for large?). Wont bother .NET, it never needs size from heap. + -If need align - could add 3 and mask lower 2 bits to round up. +-Optional + -32/64 Size allocated - may be bigger and not needed for slotted etc. + +-Tiny +If needed can make tiny types too with only ref and ptr, no need for size. But check heap and +see if such small ones are common. Probably not, likely only for boxing etc. -Small (Tables) Fixed sizes, max size one page. diff --git a/source/Cosmos.Core.Memory.Test/Cosmos.Core.Memory.Test.csproj b/source/Cosmos.Core.Memory.Test/Cosmos.Core.Memory.Test.csproj index 8c54de0e0..2ebd88688 100644 --- a/source/Cosmos.Core.Memory.Test/Cosmos.Core.Memory.Test.csproj +++ b/source/Cosmos.Core.Memory.Test/Cosmos.Core.Memory.Test.csproj @@ -52,6 +52,9 @@ + + + diff --git a/source/Cosmos.Core.Memory.Test/Heap.cs b/source/Cosmos.Core.Memory.Test/Heap.cs index 98e8cd834..2fe07aa2c 100644 --- a/source/Cosmos.Core.Memory.Test/Heap.cs +++ b/source/Cosmos.Core.Memory.Test/Heap.cs @@ -9,23 +9,29 @@ namespace Cosmos.Core.Memory.Test { unsafe static public class Heap { static public void Init() { - } static public void* New(Native aSize) { return null; } - static private void* NewBlock(int aSize) { - // size is inclusive? final sizse important when we get to vm + static private void* NewBlock(Native aSize) { + return NewBlockLarge(aSize); + } - // Block Status - 1 byte of 4 - // -Has Data - // -Empty (Can be removed or merged) - // Next Block - Pointer to data. 0 if this is current last. - // Data Size - Native - Size of data, not including header. - // Data - return null; + static private void* NewBlockLarge(Native aSize) { + const Native xPrefixWordsLarge = 4; + const Native xPrefixSizeLarge = xPrefixWordsLarge * sizeof(Native); + + Native xPages = (Native)((aSize + xPrefixSizeLarge) / RAT.PageSize); + var xPtr = (Native*)RAT.Alloc(RAT.PageType.HeapLarge, xPages); + + xPtr[0] = xPages * RAT.PageSize - xPrefixSizeLarge; // Allocated data size + xPtr[1] = aSize; // Actual data size + xPtr[2] = 0; // Ref count + xPtr[3] = 0; // Ptr to first + + return xPtr + xPrefixWordsLarge; } } } diff --git a/source/Cosmos.Core.Memory.Test/HeapItemLarge.cs b/source/Cosmos.Core.Memory.Test/HeapItemLarge.cs new file mode 100644 index 000000000..df231318f --- /dev/null +++ b/source/Cosmos.Core.Memory.Test/HeapItemLarge.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Cosmos.Core.Memory.Test { + static public class HeapItemLarge { + } +} diff --git a/source/Cosmos.Core.Memory.Test/HeapItemMedium.cs b/source/Cosmos.Core.Memory.Test/HeapItemMedium.cs new file mode 100644 index 000000000..b55067c74 --- /dev/null +++ b/source/Cosmos.Core.Memory.Test/HeapItemMedium.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Cosmos.Core.Memory.Test { + static public class HeapItemMedium { + } +} diff --git a/source/Cosmos.Core.Memory.Test/HeapItemSmall.cs b/source/Cosmos.Core.Memory.Test/HeapItemSmall.cs new file mode 100644 index 000000000..9b4d52466 --- /dev/null +++ b/source/Cosmos.Core.Memory.Test/HeapItemSmall.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Cosmos.Core.Memory.Test { + static public class HeapItemSmall { + } +} diff --git a/source/Cosmos.Core.Memory.Test/RAT.cs b/source/Cosmos.Core.Memory.Test/RAT.cs index 56bc8bb0a..2c2f37b59 100644 --- a/source/Cosmos.Core.Memory.Test/RAT.cs +++ b/source/Cosmos.Core.Memory.Test/RAT.cs @@ -9,8 +9,16 @@ namespace Cosmos.Core.Memory.Test { unsafe static public class RAT { static public class PageType { public const byte Empty = 0; - public const byte RAT = 1; + // Data Types from 1, special meanings from 255 down. + public const byte RAT = 1; + public const byte HeapSmall = 2; + public const byte HeapMedium = 3; + public const byte HeapLarge = 4; + // Code + // Stack + // Disk Cache + // Extension of previous page. public const byte Extension = 255; } @@ -80,7 +88,7 @@ namespace Cosmos.Core.Memory.Test { return xResult; } - static private byte* Alloc(byte aType, Native aCount = 1) { + static public byte* Alloc(byte aType, Native aPageCount = 1) { Native? xPos = null; // Could combine with an external method or delegate, but will slow things down @@ -88,11 +96,11 @@ namespace Cosmos.Core.Memory.Test { // // Alloc single blocks at bottom, larger blocks at top to help reduce fragmentation. Native xCount = 0; - if (aCount == 1) { + if (aPageCount == 1) { for (Native i = 0; i < mPageCount; i++) { if (mRAT[i] == PageType.Empty) { xCount++; - if (xCount == aCount) { + if (xCount == aPageCount) { xPos = i - xCount - 1; break; } @@ -104,7 +112,7 @@ namespace Cosmos.Core.Memory.Test { for (Native i = mPageCount - 1; i >= 0; i--) { if (mRAT[i] == PageType.Empty) { xCount++; - if (xCount == aCount) { + if (xCount == aPageCount) { xPos = i; break; } diff --git a/source/Cosmos.Core.Memory.Test/UnitTest1.cs b/source/Cosmos.Core.Memory.Test/UnitTest1.cs index 5b74a25b2..54ad064d2 100644 --- a/source/Cosmos.Core.Memory.Test/UnitTest1.cs +++ b/source/Cosmos.Core.Memory.Test/UnitTest1.cs @@ -17,6 +17,7 @@ namespace Cosmos.Core.Memory.Test { Assert.IsTrue(xRatPages > 0); Native xFreePages = RAT.GetPageCount(RAT.PageType.Empty); + Assert.IsTrue(xFreePages > 0); } } }