blob: 01fb62f9897972a89c460d7913fe42bf462743ad [file]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
// Contains a class which will provide a uint32 array which can grow dynamically
// It behaves almost same as regex::List<> except it has less members, is customized for being used in SmallSpanSequence of FunctionBody
#pragma once
#ifdef DIAG_MEM
extern int listFreeAmount;
#endif
namespace JsUtil
{
template <class ValueType, class TAllocator>
class GrowingArray
{
public:
typedef Field(ValueType, TAllocator) TValue;
typedef typename AllocatorInfo<TAllocator, TValue>::AllocatorType AllocatorType;
static GrowingArray* Create(uint32 _length);
GrowingArray(AllocatorType* allocator, uint32 _length)
: buffer(nullptr),
alloc(allocator),
count(0),
length(_length)
{
EnsureArray();
}
~GrowingArray()
{
if (buffer != nullptr)
{
AllocatorFree(alloc, (TypeAllocatorFunc<AllocatorType, int>::GetFreeFunc()), buffer, UInt32Math::Mul(length, sizeof(TValue)));
}
}
TValue ItemInBuffer(uint32 index) const
{
if (index >= count)
{
return (TValue)0;
}
return buffer[index];
}
void ItemInBuffer(uint32 index, TValue item)
{
EnsureArray();
Assert(index < count);
buffer[index] = item;
}
void Add(TValue item)
{
EnsureArray();
buffer[count] = item;
count++;
}
uint32 Count() const { return count; }
void SetCount(uint32 _count) { count = _count; }
uint32 GetLength() const { return length; }
TValue* GetBuffer() const { return buffer; }
GrowingArray * Clone()
{
GrowingArray * pNewArray = AllocatorNew(AllocatorType, alloc, GrowingArray, alloc, length);
pNewArray->count = count;
if (buffer)
{
pNewArray->buffer = AllocateArray<AllocatorType, TValue, false>(
TRACK_ALLOC_INFO(alloc, TValue, AllocatorType, 0, length),
TypeAllocatorFunc<AllocatorType, TValue>::GetAllocFunc(),
length);
CopyArray<TValue, TValue, TAllocator>(pNewArray->buffer, length, buffer, length);
}
return pNewArray;
}
private:
Field(TValue*, TAllocator) buffer;
Field(uint32) count;
Field(uint32) length;
FieldNoBarrier(AllocatorType*) alloc;
void EnsureArray()
{
if (buffer == nullptr)
{
buffer = AllocateArray<AllocatorType, TValue, false>(
TRACK_ALLOC_INFO(alloc, TValue, AllocatorType, 0, length),
TypeAllocatorFunc<AllocatorType, TValue>::GetAllocFunc(),
length);
count = 0;
}
else if (count == length)
{
uint32 newLength = UInt32Math::AddMul<1, 2>(length);
TValue * newbuffer = AllocateArray<AllocatorType, TValue, false>(
TRACK_ALLOC_INFO(alloc, TValue, AllocatorType, 0, newLength),
TypeAllocatorFunc<AllocatorType, TValue>::GetAllocFunc(),
newLength);
CopyArray<TValue, TValue, TAllocator>(newbuffer, newLength, buffer, length);
#ifdef DIAG_MEM
listFreeAmount += length;
#endif
if (length != 0)
{
const size_t lengthByteSize = UInt32Math::Mul(length, sizeof(TValue));
AllocatorFree(alloc, (TypeAllocatorFunc<AllocatorType, int>::GetFreeFunc()), buffer, lengthByteSize);
}
length = newLength;
buffer = newbuffer;
}
}
};
typedef GrowingArray<uint32, HeapAllocator> GrowingUint32HeapArray;
}