LargeHeapBucket.inl 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. inline char *
  7. LargeHeapBucket::TryAlloc(Recycler * recycler, size_t sizeCat, ObjectInfoBits attributes)
  8. {
  9. Assert((attributes & InternalObjectInfoBitMask) == attributes);
  10. char * memBlock;
  11. // Algorithm:
  12. // Try bump allocate from a heap block
  13. // Otherwise, If free list isn't empty, allocate from it
  14. // * Otherwise, try allocate from a larger heap block (TODO)
  15. // Otherwise allocate new heap block
  16. if (this->largeBlockList != nullptr)
  17. {
  18. memBlock = this->largeBlockList->Alloc(sizeCat, attributes);
  19. if (memBlock != nullptr)
  20. {
  21. // Don't need to verify zero fill here since we will do it in LargeHeapBucket::Alloc
  22. return memBlock;
  23. }
  24. }
  25. if (!this->supportFreeList)
  26. {
  27. return nullptr;
  28. }
  29. memBlock = this->TryAllocFromExplicitFreeList(recycler, sizeCat, attributes);
  30. if (memBlock != nullptr)
  31. {
  32. // Don't need to verify zero fill here since we will do it in LargeHeapBucket::Alloc
  33. return memBlock;
  34. }
  35. return this->TryAllocFromFreeList(recycler, sizeCat, attributes);
  36. }
  37. template <ObjectInfoBits attributes, bool nothrow>
  38. inline char *
  39. LargeHeapBucket::Alloc(Recycler * recycler, size_t sizeCat)
  40. {
  41. Assert(!HeapInfo::IsMediumObject(sizeCat) || HeapInfo::GetMediumObjectAlignedSizeNoCheck(sizeCat) == this->sizeCat);
  42. Assert((attributes & InternalObjectInfoBitMask) == attributes);
  43. char * memBlock = TryAlloc(recycler, sizeCat, attributes);
  44. if (memBlock == nullptr)
  45. {
  46. memBlock = SnailAlloc(recycler, sizeCat, attributes, nothrow);
  47. Assert(memBlock != nullptr);
  48. }
  49. else
  50. {
  51. #ifdef RECYCLER_PAGE_HEAP
  52. Assert(!IsPageHeapEnabled(attributes));
  53. #endif
  54. }
  55. #ifdef RECYCLER_ZERO_MEM_CHECK
  56. // TODO: large heap block doesn't separate leaf object on to different page allocator.
  57. // so all the memory should still be zeroed.
  58. recycler->VerifyZeroFill(memBlock, sizeCat);
  59. #endif
  60. return memBlock;
  61. }
  62. template <class Fn>
  63. void
  64. LargeHeapBucket::ForEachLargeHeapBlock(Fn fn)
  65. {
  66. HeapBlockList::ForEach(fullLargeBlockList, fn);
  67. HeapBlockList::ForEach(largeBlockList, fn);
  68. #ifdef RECYCLER_PAGE_HEAP
  69. HeapBlockList::ForEach(largePageHeapBlockList, fn);
  70. #endif
  71. HeapBlockList::ForEach(pendingDisposeLargeBlockList, fn);
  72. #if ENABLE_CONCURRENT_GC
  73. HeapBlockList::ForEach(pendingSweepLargeBlockList, fn);
  74. #if ENABLE_PARTIAL_GC
  75. HeapBlockList::ForEach(partialSweptLargeBlockList, fn);
  76. #endif
  77. #endif
  78. }
  79. template <class Fn>
  80. void
  81. LargeHeapBucket::ForEachEditingLargeHeapBlock(Fn fn)
  82. {
  83. HeapBlockList::ForEachEditing(fullLargeBlockList, fn);
  84. HeapBlockList::ForEachEditing(largeBlockList, fn);
  85. #ifdef RECYCLER_PAGE_HEAP
  86. HeapBlockList::ForEachEditing(largePageHeapBlockList, fn);
  87. #endif
  88. HeapBlockList::ForEachEditing(pendingDisposeLargeBlockList, fn);
  89. #if ENABLE_CONCURRENT_GC
  90. HeapBlockList::ForEachEditing(pendingSweepLargeBlockList, fn);
  91. #if ENABLE_PARTIAL_GC
  92. HeapBlockList::ForEachEditing(partialSweptLargeBlockList, fn);
  93. #endif
  94. #endif
  95. }