GrowingArray.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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. // Contains a class which will provide a uint32 array which can grow dynamically
  6. // It behaves almost same as regex::List<> except it has less members, is customized for being used in SmallSpanSequence of FunctionBody
  7. #pragma once
  8. #ifdef DIAG_MEM
  9. extern int listFreeAmount;
  10. #endif
  11. namespace JsUtil
  12. {
  13. template <class TValue, class TAllocator>
  14. class GrowingArray
  15. {
  16. public:
  17. typedef typename AllocatorInfo<TAllocator, TValue>::AllocatorType AllocatorType;
  18. static GrowingArray* Create(uint32 _length);
  19. GrowingArray(AllocatorType* allocator, uint32 _length)
  20. : buffer(nullptr),
  21. alloc(allocator),
  22. count(0),
  23. length(_length)
  24. {
  25. EnsureArray();
  26. }
  27. ~GrowingArray()
  28. {
  29. if (buffer != nullptr)
  30. {
  31. AllocatorFree(alloc, (TypeAllocatorFunc<AllocatorType, int>::GetFreeFunc()), buffer, UInt32Math::Mul(length, sizeof(TValue)));
  32. }
  33. }
  34. TValue ItemInBuffer(uint32 index)
  35. {
  36. if (index >= count)
  37. {
  38. return 0;
  39. }
  40. return buffer[index];
  41. }
  42. void ItemInBuffer(uint32 index, TValue item)
  43. {
  44. EnsureArray();
  45. Assert(index < count);
  46. buffer[index] = item;
  47. }
  48. void Add(TValue item)
  49. {
  50. EnsureArray();
  51. buffer[count] = item;
  52. count++;
  53. }
  54. uint32 Count() const { return count; }
  55. void SetCount(uint32 _count) { count = _count; }
  56. uint32 GetLength() const { return length; }
  57. TValue* GetBuffer() const { return buffer; }
  58. GrowingArray * Clone()
  59. {
  60. GrowingArray * pNewArray = AllocatorNew(AllocatorType, alloc, GrowingArray, alloc, length);
  61. pNewArray->count = count;
  62. if (buffer)
  63. {
  64. pNewArray->buffer = AllocateArray<AllocatorType, TValue, false>(
  65. TRACK_ALLOC_INFO(alloc, TValue, AllocatorType, 0, length),
  66. TypeAllocatorFunc<AllocatorType, TValue>::GetAllocFunc(),
  67. length);
  68. const size_t byteSize = UInt32Math::Mul(length, sizeof(TValue));
  69. js_memcpy_s(pNewArray->buffer, byteSize, buffer, byteSize);
  70. }
  71. return pNewArray;
  72. }
  73. private:
  74. TValue* buffer;
  75. uint32 count;
  76. uint32 length;
  77. AllocatorType* alloc;
  78. void EnsureArray()
  79. {
  80. if (buffer == nullptr)
  81. {
  82. buffer = AllocateArray<AllocatorType, TValue, false>(
  83. TRACK_ALLOC_INFO(alloc, TValue, AllocatorType, 0, length),
  84. TypeAllocatorFunc<AllocatorType, TValue>::GetAllocFunc(),
  85. length);
  86. count = 0;
  87. }
  88. else if (count == length)
  89. {
  90. uint32 newLength = UInt32Math::AddMul<1, 2>(length);
  91. TValue * newbuffer = AllocateArray<AllocatorType, TValue, false>(
  92. TRACK_ALLOC_INFO(alloc, TValue, AllocatorType, 0, newLength),
  93. TypeAllocatorFunc<AllocatorType, TValue>::GetAllocFunc(),
  94. newLength);
  95. const size_t lengthByteSize = UInt32Math::Mul(length, sizeof(TValue));
  96. const size_t newLengthByteSize = UInt32Math::Mul(newLength, sizeof(TValue));
  97. js_memcpy_s(newbuffer, newLengthByteSize, buffer, lengthByteSize);
  98. #ifdef DIAG_MEM
  99. listFreeAmount += length;
  100. #endif
  101. if (length != 0)
  102. {
  103. AllocatorFree(alloc, (TypeAllocatorFunc<AllocatorType, int>::GetFreeFunc()), buffer, lengthByteSize);
  104. }
  105. length = newLength;
  106. buffer = newbuffer;
  107. }
  108. }
  109. };
  110. typedef GrowingArray<uint32, HeapAllocator> GrowingUint32HeapArray;
  111. }