1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5// We would like to allow "util" collection classes to be usable both
6// from the VM and from the JIT. The latter case presents a
7// difficulty, because in the (x86, soon to be cross-platform) JIT
8// compiler, we require allocation to be done using a "no-release"
9// (aka, arena-style) allocator that is provided as methods of the
10// JIT's Compiler type.
11
12// To allow utilcode collection classes to deal with this, they may be
13// written to do allocation and freeing via an instance of the
14// "IAllocator" class defined in this file.
15//
16#ifndef _IALLOCATOR_DEFINED_
17#define _IALLOCATOR_DEFINED_
18
19#include "contract.h"
20#include "safemath.h"
21
22class IAllocator
23{
24 public:
25 virtual void* Alloc(size_t sz) = 0;
26
27 // Allocate space for an array of "elems" elements, each of size "elemSize".
28 virtual void* ArrayAlloc(size_t elems, size_t elemSize) = 0;
29
30 virtual void Free(void* p) = 0;
31};
32
33// This class wraps an allocator that does not allow zero-length allocations,
34// producing one that does (every zero-length allocation produces a pointer to the same
35// statically-allocated memory, and freeing that pointer is a no-op).
36class AllowZeroAllocator: public IAllocator
37{
38 int m_zeroLenAllocTarg;
39 IAllocator* m_alloc;
40
41public:
42 AllowZeroAllocator(IAllocator* alloc) : m_alloc(alloc) {}
43
44 void* Alloc(size_t sz)
45 {
46 if (sz == 0)
47 {
48 return (void*)(&m_zeroLenAllocTarg);
49 }
50 else
51 {
52 return m_alloc->Alloc(sz);
53 }
54 }
55
56 void* ArrayAlloc(size_t elemSize, size_t numElems)
57 {
58 if (elemSize == 0 || numElems == 0)
59 {
60 return (void*)(&m_zeroLenAllocTarg);
61 }
62 else
63 {
64 return m_alloc->ArrayAlloc(elemSize, numElems);
65 }
66 }
67
68 virtual void Free(void * p)
69 {
70 if (p != (void*)(&m_zeroLenAllocTarg))
71 {
72 m_alloc->Free(p);
73 }
74 }
75};
76
77#endif // _IALLOCATOR_DEFINED_
78