-
Notifications
You must be signed in to change notification settings - Fork 1
/
memory.h
161 lines (128 loc) · 3.4 KB
/
memory.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#ifndef MEMORY_H
#define MEMORY_H
#include "general.h"
#include "array.h"
// ------------------------------------------- //
enum PageFlags
{
PAGE_FLAG_WRITE = 0x01,
PAGE_FLAG_EXECUTE = 0x02,
PAGE_FLAG_STACK = 0x04,
};
static void InitPageCache();
static void InitGlobalArena();
static byte* AllocateVirtualPage(uint64 size, PageFlags flags);
static void DeAllocateVirtualPage(byte* page, uint64 size);
static byte* GetPage(uint64 size);
static void RetirePage(byte* page, uint64 size);
// ------------------------------------------- //
static byte* AllocateMemory(uint64 size);
static byte* ReAllocateMemory(void* p, uint64 old_size, uint64 new_size);
static void DeAllocateMemory(void* p, uint64 size);
// ------------------------------------------- //
template<typename T>
static inline T* Allocate(uint64 count = 1)
{
return (T*)AllocateMemory(count * sizeof(T));
}
template<typename T>
static inline T* ReAllocate(T* p, uint64 old_count, uint64 new_count)
{
return (T*)ReAllocateMemory((byte*)p, old_count * sizeof(T), new_count * sizeof(T));
}
template<typename T>
static inline void DeAllocate(T* p, uint64 count = 1)
{
DeAllocateMemory((byte*)p, count * sizeof(T));
}
// ------------------------------------------- //
template<typename T>
static inline void DeAllocateArray(Array<T> array)
{
DeAllocateMemory(array.data, sizeof(T) * array.count);
}
template<typename T>
static inline Array<T> AllocateArray(uint64 count)
{
return Array<T>((T*)AllocateMemory(count * sizeof(T)), count);
}
// ------------------------------------------- //
struct Stack_Block
{
Stack_Block* previous;
uint64 size;
char data[];
};
struct Stack
{
Stack_Block* block;
byte* head;
byte* end;
};
static Stack CreateStack(uint64 size);
static void FreeStack(Stack* stack);
static void* StackAllocate(Stack* stack, uint64 size);
template<typename T>
static inline T* StackAllocate(Stack* stack)
{
return (T*)StackAllocate(stack, sizeof(T));
}
template<typename T>
static inline T* StackAllocate(Stack* stack, uint64 count)
{
return (T*)StackAllocate(stack, count * sizeof(T));
}
template<typename T>
static Array<T> StackAllocateArray(Stack* stack, uint64 count)
{
Array<T> array;
array.data = count ? StackAllocate<T>(stack, count) : null;
array.count = count;
return array;
}
// ------------------------------------------- //
template<typename T>
static void CopyMemory(T* dest, const T* src, uint64 count = 1)
{
__builtin_memcpy(dest, src, sizeof(T) * count);
}
template<typename T>
static void FillMemory(T* dest, uint64 count, T value)
{
for (uint64 i = 0; i < count; i++) dest[i] = value;
}
template<typename T>
static void FillMemory(T* begin, T* end, T value)
{
for (; begin < end; begin++) *begin = value;
}
template<typename T>
static inline bool CompareMemory(const T* a, const T* b, uint64 count = 1)
{
return __builtin_memcmp(a, b, sizeof(T) * count) == 0;
}
template<typename T>
static inline bool Compare(const T* a, const T* b, uint64 count = 1)
{
for (uint64 i = 0; i < count; i++)
{
if (!Compare(a[i], b[i])) return false;
}
return true;
}
template<typename T>
static inline void ZeroMemory(T* begin, T* end)
{
__builtin_memset((char*)begin, 0, (char*)end - (char*)begin);
}
template<typename T>
static inline void ZeroMemory(T* p, uint64 count = 1)
{
ZeroMemory(p, p + count);
}
template<typename T>
static inline void ZeroArray(Array<T> array)
{
ZeroMemory(array.data, array.count);
}
#endif // MEMORY_H