]> git.localhorst.tv Git - l2e.git/blob - src/loader/PagedAllocator.cpp
new object file format in compiler
[l2e.git] / src / loader / PagedAllocator.cpp
1 #include "PagedAllocator.h"
2
3 #include <stdexcept>
4
5 using std::deque;
6 using std::runtime_error;
7
8
9 namespace loader {
10
11 PagedAllocator::PagedAllocator(unsigned int pageSize)
12 : head(0)
13 , pageSize(pageSize) {
14         NewPage();
15 }
16
17 PagedAllocator::~PagedAllocator() {
18         for (deque<char *>::const_iterator i(pages.begin()), end(pages.end()); i != end; ++i) {
19                 delete[] *i;
20         }
21 }
22
23
24 char *PagedAllocator::Alloc(unsigned int size) {
25         if (size > pageSize) {
26                 char *page(new char[size]);
27                 pages.push_front(page);
28                 return page;
29         }
30         unsigned int free(Free());
31         if (free < size) {
32                 NewPage();
33         }
34         char *chunk(head);
35         head += size;
36         return chunk;
37 }
38
39 unsigned int PagedAllocator::PageOf(void *ptrIn) const {
40         char *ptr = reinterpret_cast<char *>(ptrIn);
41         unsigned int counter = 0;
42         for (deque<char *>::const_iterator i(pages.begin()), end(pages.end()); i != end; ++i, ++counter) {
43                 if (ptr < *i) continue;
44                 if (*i < ptr) return counter;
45         }
46         throw runtime_error("PagedAllocator::PageOf");
47 }
48
49 unsigned int PagedAllocator::PageOffsetOf(void *ptrIn) const {
50         char *ptr = reinterpret_cast<char *>(ptrIn);
51         for (deque<char *>::const_iterator i(pages.begin()), end(pages.end()); i != end; ++i) {
52                 if (ptr < *i) continue;
53                 if (*i < ptr) return ptr - *i;
54         }
55         throw runtime_error("PagedAllocator::PageOffsetOf");
56 }
57
58 unsigned int PagedAllocator::Free() const {
59         return pageSize - (head - CurrentPage());
60 }
61
62 void PagedAllocator::NewPage() {
63         char *page(new char[pageSize]);
64         pages.push_back(page);
65         head = page;
66 }
67
68 char *PagedAllocator::CurrentPage() {
69         return pages.back();
70 }
71
72 const char *PagedAllocator::CurrentPage() const {
73         return pages.back();
74 }
75
76 }