HeapBucket.inl 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. template <typename TBlockType>
  7. template <ObjectInfoBits attributes, bool nothrow>
  8. inline char *
  9. HeapBucketT<TBlockType>::RealAlloc(Recycler * recycler, size_t sizeCat, size_t size)
  10. {
  11. Assert(sizeCat == this->sizeCat);
  12. char * memBlock = allocatorHead.template InlinedAlloc<(ObjectInfoBits)(attributes & InternalObjectInfoBitMask)>(recycler, sizeCat);
  13. if (memBlock == nullptr)
  14. {
  15. memBlock = SnailAlloc(recycler, &allocatorHead, sizeCat, size, attributes, nothrow);
  16. Assert(memBlock != nullptr || nothrow);
  17. }
  18. // If this API is called and throwing is not allowed,
  19. // check if we actually allocated a block before verifying
  20. // its zero fill state. If it is nullptr, return that here.
  21. if (nothrow)
  22. {
  23. if (memBlock == nullptr)
  24. {
  25. return nullptr;
  26. }
  27. }
  28. #ifdef RECYCLER_ZERO_MEM_CHECK
  29. // Do the verify zero fill only if it's not a nothrow alloc
  30. if ((attributes & ObjectInfoBits::LeafBit) == 0
  31. #ifdef RECYCLER_WRITE_BARRIER_ALLOC_THREAD_PAGE
  32. && ((attributes & ObjectInfoBits::WithBarrierBit) == 0)
  33. #endif
  34. )
  35. {
  36. if (this->IsPageHeapEnabled(attributes))
  37. {
  38. // in page heap there's no free list, and using size instead of sizeCat
  39. recycler->VerifyZeroFill(memBlock, size);
  40. }
  41. else
  42. {
  43. // Skip the first and the last pointer objects- the first may have next pointer for the free list
  44. // the last might have the old size of the object if this was allocated from an explicit free list
  45. recycler->VerifyZeroFill(memBlock + sizeof(FreeObject), sizeCat - (2 * sizeof(FreeObject)));
  46. }
  47. }
  48. #endif
  49. return memBlock;
  50. }
  51. template <typename TBlockType>
  52. void
  53. HeapBucketT<TBlockType>::ExplicitFree(void* object, size_t sizeCat)
  54. {
  55. FreeObject* explicitFreeObject = (FreeObject*) object;
  56. if (lastExplicitFreeListAllocator->IsExplicitFreeObjectListAllocMode())
  57. {
  58. explicitFreeObject->SetNext(lastExplicitFreeListAllocator->GetFreeObjectList());
  59. lastExplicitFreeListAllocator->SetFreeObjectList(explicitFreeObject);
  60. }
  61. else
  62. {
  63. explicitFreeObject->SetNext(this->explicitFreeList);
  64. this->explicitFreeList = explicitFreeObject;
  65. }
  66. // Don't fill memory fill pattern here since we're still pretending like the object
  67. // is allocated to other parts of the GC.
  68. }
  69. #if DBG || defined(RECYCLER_SLOW_CHECK_ENABLED)
  70. inline
  71. Recycler *
  72. HeapBucket::GetRecycler() const
  73. {
  74. return this->heapInfo->recycler;
  75. }
  76. #endif