allocator_common.h 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. //===-- allocator_common.h --------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #ifndef SCUDO_ALLOCATOR_COMMON_H_
  9. #define SCUDO_ALLOCATOR_COMMON_H_
  10. #include "common.h"
  11. #include "list.h"
  12. namespace scudo {
  13. template <class SizeClassAllocator> struct TransferBatch {
  14. typedef typename SizeClassAllocator::SizeClassMap SizeClassMap;
  15. typedef typename SizeClassAllocator::CompactPtrT CompactPtrT;
  16. static const u16 MaxNumCached = SizeClassMap::MaxNumCachedHint;
  17. void setFromArray(CompactPtrT *Array, u16 N) {
  18. DCHECK_LE(N, MaxNumCached);
  19. Count = N;
  20. memcpy(Batch, Array, sizeof(Batch[0]) * Count);
  21. }
  22. void appendFromArray(CompactPtrT *Array, u16 N) {
  23. DCHECK_LE(N, MaxNumCached - Count);
  24. memcpy(Batch + Count, Array, sizeof(Batch[0]) * N);
  25. // u16 will be promoted to int by arithmetic type conversion.
  26. Count = static_cast<u16>(Count + N);
  27. }
  28. void appendFromTransferBatch(TransferBatch *B, u16 N) {
  29. DCHECK_LE(N, MaxNumCached - Count);
  30. DCHECK_GE(B->Count, N);
  31. // Append from the back of `B`.
  32. memcpy(Batch + Count, B->Batch + (B->Count - N), sizeof(Batch[0]) * N);
  33. // u16 will be promoted to int by arithmetic type conversion.
  34. Count = static_cast<u16>(Count + N);
  35. B->Count = static_cast<u16>(B->Count - N);
  36. }
  37. void clear() { Count = 0; }
  38. void add(CompactPtrT P) {
  39. DCHECK_LT(Count, MaxNumCached);
  40. Batch[Count++] = P;
  41. }
  42. void moveToArray(CompactPtrT *Array) {
  43. memcpy(Array, Batch, sizeof(Batch[0]) * Count);
  44. clear();
  45. }
  46. u16 getCount() const { return Count; }
  47. bool isEmpty() const { return Count == 0U; }
  48. CompactPtrT get(u16 I) const {
  49. DCHECK_LE(I, Count);
  50. return Batch[I];
  51. }
  52. TransferBatch *Next;
  53. private:
  54. CompactPtrT Batch[MaxNumCached];
  55. u16 Count;
  56. };
  57. // A BatchGroup is used to collect blocks. Each group has a group id to
  58. // identify the group kind of contained blocks.
  59. template <class SizeClassAllocator> struct BatchGroup {
  60. // `Next` is used by IntrusiveList.
  61. BatchGroup *Next;
  62. // The compact base address of each group
  63. uptr CompactPtrGroupBase;
  64. // Cache value of SizeClassAllocatorLocalCache::getMaxCached()
  65. u16 MaxCachedPerBatch;
  66. // Number of blocks pushed into this group. This is an increment-only
  67. // counter.
  68. uptr PushedBlocks;
  69. // This is used to track how many bytes are not in-use since last time we
  70. // tried to release pages.
  71. uptr BytesInBGAtLastCheckpoint;
  72. // Blocks are managed by TransferBatch in a list.
  73. SinglyLinkedList<TransferBatch<SizeClassAllocator>> Batches;
  74. };
  75. } // namespace scudo
  76. #endif // SCUDO_ALLOCATOR_COMMON_H_