33 #define CHAR_PTR(c) ((char*)c)
34 #define ALLOCATOR_REF_COUNT (*((unsigned*)(CHAR_PTR(start) + 2 * sizeof(size_t))))
101 #undef ALLOCATOR_REF_COUNT
102 #define ALLOCATOR_REF_COUNT (*((unsigned*)(CHAR_PTR(myState.activeRAM) + 2 * sizeof(size_t))))
103 #define LAST_USED (*((size_t*)myState.activeRAM))
104 #define OFFSET_TO_OBJECT (*((size_t*)(CHAR_PTR(myState.activeRAM) + sizeof(size_t))))
105 #define OFFSET_TO_OBJECT_RELATIVE(fromWhere) (*((size_t*)(CHAR_PTR(fromWhere) + sizeof(size_t))))
106 #define HEADER_SIZE (sizeof(unsigned) + 2 * sizeof(size_t))
107 #define GET_CHUNK_SIZE(ofMe) (*((unsigned*)ofMe))
108 #define CHUNK_HEADER_SIZE sizeof(unsigned)
111 #ifdef DEBUG_OBJECT_MODEL
114 std::vector<InactiveAllocationBlock>& allInactives,
115 AllocatorState& myState,
120 std::vector<InactiveAllocationBlock>& allInactives,
133 int leadingZeros = __builtin_clz(chunkSize);
136 myState.
chunks[31 - leadingZeros].push_back(here);
140 #ifdef DEBUG_OBJECT_MODEL
141 std::cout <<
"**defaultFreeRAM**" << std::endl;
142 std::cout <<
"###################################" << std::endl;
144 <<
" with typeId=" << typeId << std::endl;
145 std::cout <<
"allocator block start =" << myState.
activeRAM << std::endl;
146 std::cout <<
"allocator numBytes=" << myState.
numBytes << std::endl;
147 std::cout <<
"freed numBytes=" << chunkSize << std::endl;
148 std::cout <<
"chunk index=" << 31 - leadingZeros << std::endl;
149 std::cout <<
"###################################" << std::endl;
155 auto i = std::lower_bound(allInactives.begin(), allInactives.end(), here);
158 if (i != allInactives.end() && !(*i > here)) {
161 i->decReferenceCount();
162 #ifdef DEBUG_OBJECT_MODEL
163 std::cout <<
"###################################" << std::endl;
164 std::cout <<
"allocator block reference count--=" << i->getReferenceCount()
165 <<
" with typeId=" << typeId << std::endl;
166 std::cout <<
"allocator block starting address=" << i->getStart() << std::endl;
167 std::cout <<
"allocator block size=" << i->numBytes() << std::endl;
168 std::cout <<
"###################################" << std::endl;
171 if (i->areNoReferences()) {
173 PDB_COUT <<
"Killed an old block naturally." << std::endl;
174 allInactives.erase(i);
181 #ifdef DEBUG_OBJECT_MODEL
182 std::cout <<
"###################################################################" << std::endl;
183 std::cout <<
"We can't free the object, it may be allocated by some other thread!" << std::endl;
184 std::cout <<
"typeId=" << typeId << std::endl;
185 std::cout <<
"###################################################################" << std::endl;
192 #ifdef DEBUG_OBJECT_MODEL
193 inline void*
defaultGetRAM(
size_t howMuch, AllocatorState& myState, int16_t typeId) {
194 std::cout <<
"to get RAM with size = " << howMuch <<
" and typeId = " << typeId << std::endl;
199 if ((bytesNeeded % 4) != 0) {
200 bytesNeeded += (4 - (bytesNeeded % 4));
203 unsigned int numLeadingZeros = __builtin_clz(bytesNeeded);
205 #ifdef DEBUG_OBJECT_MODEL
206 std::cout <<
"howMuch=" << howMuch <<
", bytesNeeded=" << bytesNeeded
207 <<
", numLeadingZeros=" << numLeadingZeros << std::endl;
217 for (
unsigned int i = 31 - numLeadingZeros; i < 32; i++) {
218 int len = myState.
chunks[i].size();
219 for (
int j = len - 1; j >= 0; j--) {
221 void* returnVal = myState.
chunks[i][j];
225 #ifdef DEBUG_OBJECT_MODEL
226 std::cout <<
"**defaultGetRAM**" << std::endl;
227 std::cout <<
"###################################" << std::endl;
229 <<
" with typeId=" << typeId << std::endl;
230 std::cout <<
"allocator block start =" << myState.
activeRAM << std::endl;
231 std::cout <<
"allocator numBytes=" << myState.
numBytes << std::endl;
232 std::cout <<
"starting chunk index=" << 31 - numLeadingZeros << std::endl;
233 std::cout <<
"ending chunk index=" << i << std::endl;
234 std::cout <<
"bytes needed=" << bytesNeeded << std::endl;
235 std::cout <<
"###################################" << std::endl;
249 PDB_COUT <<
"Allocator: bytesNeeded=" << bytesNeeded << std::endl;
267 #ifdef DEBUG_OBJECT_MODEL
268 std::cout <<
"###################################" << std::endl;
270 <<
" with typeId=" << typeId << std::endl;
271 std::cout <<
"allocator block start =" << myState.
activeRAM << std::endl;
272 std::cout <<
"allocator numBytes=" << myState.
numBytes << std::endl;
273 std::cout <<
"created a new chunk with size =" << bytesNeeded << std::endl;
274 std::cout <<
"###################################" << std::endl;
281 #ifdef DEBUG_OBJECT_MODEL
282 inline void*
fastGetRAM(
size_t howMuch, AllocatorState& myState, int16_t typeId) {
283 std::cout <<
"to get RAM with size = " << howMuch <<
" and typeId = " << typeId << std::endl;
288 if ((bytesNeeded % 4) != 0) {
289 bytesNeeded += (4 - (bytesNeeded % 4));
299 PDB_COUT <<
"Allocator: bytesNeeded=" << bytesNeeded << std::endl;
317 #ifdef DEBUG_OBJECT_MODEL
318 std::cout <<
"**fastGetRAM**" << std::endl;
319 std::cout <<
"###################################" << std::endl;
321 <<
" with typeId=" << typeId << std::endl;
322 std::cout <<
"allocator block start =" << myState.
activeRAM << std::endl;
323 std::cout <<
"allocator numBytes=" << myState.
numBytes << std::endl;
324 std::cout <<
"created a new chunk with size =" << bytesNeeded << std::endl;
325 std::cout <<
"###################################" << std::endl;
332 #ifdef DEBUG_OBJECT_MODEL
335 std::vector<InactiveAllocationBlock>& allInactives,
336 AllocatorState& myState,
341 std::vector<InactiveAllocationBlock>& allInactives,
345 #ifdef DEBUG_OBJECT_MODEL
354 #ifdef DEBUG_OBJECT_MODEL
360 #ifdef DEBUG_OBJECT_MODEL
369 #ifdef DEBUG_OBJECT_MODEL
372 std::vector<InactiveAllocationBlock>& allInactives,
378 std::vector<InactiveAllocationBlock>& allInactives,
382 #ifdef DEBUG_OBJECT_MODEL
392 #ifdef DEBUG_OBJECT_MODEL
398 #ifdef DEBUG_OBJECT_MODEL
407 #ifdef DEBUG_OBJECT_MODEL
410 std::vector<InactiveAllocationBlock>& allInactives,
413 std::cout <<
"**NoReferenceCountPolicy**" << std::endl;
417 std::vector<InactiveAllocationBlock>& allInactives,
424 #ifdef DEBUG_OBJECT_MODEL
432 #ifdef DEBUG_OBJECT_MODEL
443 template <
typename FirstPolicy,
typename... OtherPolicies>
449 template <
typename FirstPolicy,
typename... OtherPolicies>
454 std::cout <<
"This is bad. Current allocation block has "
460 for (
auto& a : allInactives) {
461 if (a.areNoReferences()) {
462 std::cout <<
"This is bad. There is an allocation block left with no references.\n";
465 std::cout <<
"This is bad. There is an allocation block left with "
466 << a.getReferenceCount() <<
" references.\n";
473 template <
typename FirstPolicy,
typename... OtherPolicies>
475 for (
unsigned int i = 0; i < 32; i++) {
476 std::vector<void*> temp;
477 myState.
chunks.push_back(temp);
486 #ifdef INITIALIZE_ALLOCATOR_BLOCK
487 void* putMeHere = calloc(1024, 1);
489 void* putMeHere = malloc(1024);
493 if (putMeHere ==
nullptr) {
494 std::cout <<
"Fatal Error in temporarilyUseBlockForAllocations(): out of memory with size="
495 << 1024 << std::endl;
498 setupBlock(putMeHere, 1024,
true);
504 template <
typename FirstPolicy,
typename... OtherPolicies>
506 for (
unsigned int i = 0; i < 32; i++) {
507 std::vector<void*> temp;
508 myState.
chunks.push_back(temp);
517 #ifdef INITIALIZE_ALLOCATOR_BLOCK
518 void* putMeHere = calloc(1, numBytesIn);
520 void* putMeHere = malloc(numBytesIn);
523 if (putMeHere ==
nullptr) {
524 std::cout <<
"Fatal Error in temporarilyUseBlockForAllocations(): out of memory with size="
525 << numBytesIn << std::endl;
528 setupBlock(putMeHere, numBytesIn,
true);
535 template <
typename FirstPolicy,
typename... OtherPolicies>
538 myPolicies.setPolicy(policy);
542 template <
typename FirstPolicy,
typename... OtherPolicies>
546 return (where >= target && where < target + myState.
numBytes);
552 template <
typename FirstPolicy,
typename... OtherPolicies>
553 #ifdef DEBUG_OBJECT_MODEL
560 #ifdef DEBUG_OBJECT_MODEL
561 return myPolicies.getRAM(howMuch, myState, typeId);
563 return myPolicies.getRAM(howMuch, myState);
576 template <
typename FirstPolicy,
typename... OtherPolicies>
580 if (contains(here)) {
585 auto i = std::lower_bound(allInactives.begin(), allInactives.end(), here);
588 if (i != allInactives.end() && !(*i > here)) {
595 template <
typename FirstPolicy,
typename... OtherPolicies>
599 if (contains(here)) {
601 for (
auto& c : myState.
chunks) {
608 PDB_COUT <<
"Killed the current block.\n";
613 auto i = std::lower_bound(allInactives.begin(), allInactives.end(), here);
616 if (i != allInactives.end() && !(*i > here)) {
618 allInactives.erase(i);
619 PDB_COUT <<
"Killed an old block block.\n";
623 PDB_COUT <<
"This is kind of bad. You asked me to empty out a block, and I cannot find it.\n";
627 template <
typename FirstPolicy,
typename... OtherPolicies>
628 #ifdef DEBUG_OBJECT_MODEL
635 bool isContained = contains(here);
637 #ifdef DEBUG_OBJECT_MODEL
638 myPolicies.freeRAM(isContained, here, allInactives, myState, typeId);
640 myPolicies.freeRAM(isContained, here, allInactives, myState);
652 template <
typename FirstPolicy,
typename... OtherPolicies>
654 void* where,
size_t numBytesIn,
bool throwExceptionOnFail) {
655 setupBlock(where, numBytesIn, throwExceptionOnFail);
659 template <
typename FirstPolicy,
typename... OtherPolicies>
664 unsigned amtUnused = 0;
665 for (
auto& a : myState.
chunks) {
674 template <
typename FirstPolicy,
typename... OtherPolicies>
680 template <
typename FirstPolicy,
typename... OtherPolicies>
685 if (contains(here)) {
690 auto i = std::lower_bound(allInactives.begin(), allInactives.end(), here);
693 if (i != allInactives.end() && !(*i > here)) {
696 return i->getReferenceCount();
702 template <
typename FirstPolicy,
typename... OtherPolicies>
703 template <
class ObjType>
707 void* here = forMe.getTarget();
711 template <
typename FirstPolicy,
typename... OtherPolicies>
713 void* where,
size_t numBytesIn,
bool throwExceptionOnFail) {
718 std::cerr <<
"You need to have an allocation block that is at least " <<
HEADER_SIZE
724 if (where ==
nullptr) {
725 std::cerr <<
"Fatal Error in setupBlock(): The block doesn't have a valid address"
739 std::sort(allInactives.begin(), allInactives.end());
746 for (
auto& c : myState.
chunks) {
758 template <
typename FirstPolicy,
typename... OtherPolicies>
759 template <
class ObjType>
764 void* here = forMe.getTarget();
766 if (contains(here)) {
775 auto i = std::lower_bound(allInactives.begin(), allInactives.end(), here);
778 if (i != allInactives.end() && !(*i > here)) {
791 template <
typename FirstPolicy,
typename... OtherPolicies>
794 void* putMeHere,
size_t numBytesAvailable) {
806 setupUserSuppliedBlock(putMeHere, numBytesAvailable,
true);
812 template <
typename FirstPolicy,
typename... OtherPolicies>
815 size_t numBytesAvailable) {
828 #ifdef INITIALIZE_ALLOCATOR_BLOCK
829 void* putMeHere = calloc(numBytesAvailable, 1);
831 void* putMeHere = malloc(numBytesAvailable);
834 if (putMeHere ==
nullptr) {
835 std::cout <<
"Fatal Error in temporarilyUseBlockForAllocations(): out of memory with size="
836 << numBytesAvailable << std::endl;
839 setupBlock(putMeHere, numBytesAvailable,
true);
845 template <
typename FirstPolicy,
typename... OtherPolicies>
853 std::sort(allInactives.begin(), allInactives.end());
863 for (
int i = 0; i < allInactives.size(); i++) {
864 if (allInactives[i].start == myState.
activeRAM) {
865 allInactives.erase(allInactives.begin() + i);
875 template <
typename FirstPolicy,
typename... OtherPolicies>
877 std::string out =
"Allocator: address= ";
878 std::stringstream stream;
880 out = out + stream.str();
881 out = out +
", size=";
882 out = out + std::to_string(myState.
numBytes);
887 template <
typename FirstPolicy,
typename... OtherPolicies>
891 std::string out =
"Allocator: NumInactives=";
892 int numInactives = allInactives.size();
893 out = out + std::to_string(numInactives);
894 out = out + std::string(
"\n");
896 for (i = 0; i < numInactives; i++) {
898 out = out + std::to_string(i);
899 out = out + std::string(
":");
901 out = out + std::string(
", size=");
902 out = out + std::to_string(curBlock.
numBytes());
903 out = out + std::string(
", start=");
904 std::stringstream stream;
906 out = out + stream.str();
907 out = out + std::string(
"\n");
916 template <
typename FirstPolicy,
typename... OtherPolicies>
918 for (
auto it = allInactives.begin(); it != allInactives.end();) {
920 it = allInactives.erase(it);
925 template <
typename FirstPolicy,
typename... OtherPolicies>
927 for (
auto it = allInactives.begin(); it != allInactives.end();) {
928 if (it->numBytes() == size) {
930 it = allInactives.erase(it);
952 if (stackBase ==
nullptr || !(((
char*)&i) >= (
char*)stackBase && ((
char*)&i) < (
char*)stackEnd))
958 size_t temp = (size_t)&i;
959 return *((
Allocator*)((temp >> 22) << 22));
void defaultFreeRAM(bool isContained, void *here, std::vector< InactiveAllocationBlock > &allInactives, AllocatorState &myState)
std::string printCurrentBlock()
void * getRAM(size_t howMuch, AllocatorState &myState)
void * getRAM(size_t howMuch, AllocatorState &myState)
bool curBlockUserSupplied
AllocatorState temporarilyUseBlockForAllocations(void *putMeHere, size_t numBytesAvailable)
void setPolicy(AllocatorPolicy policy)
bool operator<(const InactiveAllocationBlock &in, const void *compToMe)
void freeRAM(bool isContained, void *here, std::vector< InactiveAllocationBlock > &allInactives, AllocatorState &myState)
InactiveAllocationBlock()
Allocator & getAllocator()
void setupBlock(void *where, size_t numBytesIn, bool throwExceptionOnFail)
#define GET_CHUNK_SIZE(ofMe)
void restoreAllocationBlock(AllocatorState &restoreMe)
void * getRAM(size_t howMuch, AllocatorState &myState)
NotEnoughSpace myException
unsigned getReferenceCount()
std::vector< std::vector< void * > > chunks
bool contains(void *whereIn)
bool isManaged(void *here)
void * getAllocationBlock(Handle< ObjType > &forMe)
LambdaTree< bool > operator==(LambdaTree< LeftType > lhs, LambdaTree< RightType > rhs)
size_t getBytesAvailableInCurrentAllocatorBlock()
#define CHUNK_HEADER_SIZE
void * getRAM(size_t howMuch)
unsigned getNumObjectsInCurrentAllocatorBlock()
void cleanInactiveBlocks()
unsigned getNumObjectsInAllocatorBlock(void *forMe)
void setupUserSuppliedBlock(void *where, size_t numBytesIn, bool throwExceptionOnFail)
void freeRAM(bool isContained, void *here, std::vector< InactiveAllocationBlock > &allInactives, AllocatorState &myState)
void freeRAM(bool isContained, void *here, std::vector< InactiveAllocationBlock > &allInactives, AllocatorState &myState)
void * defaultGetRAM(size_t howMuch, AllocatorState &myState)
void * fastGetRAM(size_t howMuch, AllocatorState &myState)
unsigned getNumObjectsInCurrentAllocatorBlock()
void emptyOutBlock(void *here)
#define ALLOCATOR_REF_COUNT
unsigned getNumObjectsInAllocatorBlock(void *forMe)
Allocator * mainAllocatorPtr
#define OFFSET_TO_OBJECT_RELATIVE(fromWhere)
unsigned getNumObjectsInHomeAllocatorBlock(Handle< ObjType > &forMe)
bool operator>(const InactiveAllocationBlock &in, const void *compToMe)
std::string printInactiveBlocks()