* src/vm/jit/codegen-common.cpp, src/vm/jit/x86_64/codegen.c: Generate
[cacao.git] / src / mm / tlh.c
1 /* src/mm/tlh.c
2
3    Copyright (C) 2008
4    CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22 */
23
24 #include "config.h"
25
26 #include "mm/memory.hpp"
27 #include "mm/tlh.h"
28
29 #include "vm/global.h"
30
31 #include <assert.h>
32 #include <sys/mman.h>
33
34 static const int TLH_MAX_SIZE = (20 * 1024 * 1024);
35
36 static inline bool tlh_avail(tlh_t *tlh, unsigned n) {
37         /*
38     ---  --- --- ---
39                     ^ end
40             ^ top
41                     ^ top + 2
42         */
43         return (tlh->top + n) <= tlh->end;
44 }
45
46 void tlh_init(tlh_t *tlh) {
47
48         void *heap = mmap(
49                 NULL, 
50                 TLH_MAX_SIZE, 
51                 PROT_READ|PROT_WRITE, 
52                 MAP_ANONYMOUS|MAP_PRIVATE, 
53                 -1, 
54                 0
55         );
56         
57         if (heap == MAP_FAILED) {
58                 /* The top pointer points to end, so all allocations will fail. */
59                 tlh->start = NULL;
60                 tlh->end = NULL;
61                 tlh->top = NULL;
62                 tlh->base = NULL;
63         } else {
64                 tlh->start = (uint8_t *)heap;
65                 tlh->top = tlh->start;
66                 tlh->base = tlh->start;
67                 tlh->end = tlh->start + TLH_MAX_SIZE;
68         }
69
70         tlh->overflows = 0;
71 }
72
73 void tlh_destroy(tlh_t *tlh) {
74         int res = munmap(tlh->start, TLH_MAX_SIZE);
75         if (res == -1) {
76                 /* TODO */
77                 assert(0);
78         }
79         tlh->start = NULL;
80         tlh->end = NULL;
81         tlh->top = NULL;
82         tlh->base = NULL;
83 }
84
85 void tlh_add_frame(tlh_t *tlh) {
86         if (tlh_avail(tlh, SIZEOF_VOID_P)) {
87                 *(uint8_t **)tlh->top = tlh->base;
88                 tlh->base = tlh->top;
89                 tlh->top += SIZEOF_VOID_P;
90         } else {
91                 tlh->overflows += 1;
92         }
93 }
94
95 void tlh_remove_frame(tlh_t *tlh) {
96         if (tlh->overflows > 0) {
97                 tlh->overflows -= 1;
98         } else {
99                 tlh->top = tlh->base;
100                 tlh->base = *(uint8_t **)tlh->top;
101         }
102 }
103
104 void *tlh_alloc(tlh_t *tlh, size_t size) {
105         void *ret;
106         if (tlh_avail(tlh, size)) {
107                 ret = tlh->top;
108                 tlh->top += size;
109                 MZERO(ret, char, size);
110         } else {
111                 ret = NULL;
112         }
113         return ret;
114 }
115
116 /*
117  * These are local overrides for various environment variables in Emacs.
118  * Please do not remove this and leave it at the end of the file, where
119  * Emacs will automagically detect them.
120  * ---------------------------------------------------------------------
121  * Local variables:
122  * mode: c
123  * indent-tabs-mode: t
124  * c-basic-offset: 4
125  * tab-width: 4
126  * End:
127  * vim:noexpandtab:sw=4:ts=4:
128  */