Fix OS X build.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
23 #include "Spaces-inl.h"
28 HeapStack::HeapStack()
34 HeapStack::~HeapStack()
37 HeapChunk::Destroy(chunk_);
41 HeapStack::initialize()
43 chunk_ = HeapChunk::New(NULL, kStackSize);
44 cursor_ = chunk_->first();
49 HeapChunk::New(HeapChunk *prev, size_t size)
51 OS::AlignableMapping map =
52 OS::MapAlignedMemory(size, HeapChunk::kAlignment, OS::Map_Commit);
57 HeapChunk *chunk = reinterpret_cast<HeapChunk *>(map.aligned());
58 chunk->base_ = map.base();
59 chunk->end_ = map.base() + map.size();
67 HeapChunk::Destroy(HeapChunk *chunk)
69 OS::UnmapAlignedMemory(chunk->base(), chunk->size());
73 HeapChunk::resetMarkBits()
75 memset(markBits(), 0, kMarkBytes);
79 : small_objects_(NULL),
80 medium_objects_(NULL),
87 FreeList::add(FreedObject *obj)
89 if (obj->size() < kMinObjectSize)
93 if (obj->size() < kMaxSmallObject)
94 list = &small_objects_;
95 else if (obj->size() < kMaxMediumObject)
96 list = &medium_objects_;
97 else if (obj->size() < kMaxLargeObject)
98 list = &large_objects_;
100 list = &huge_objects_;
103 (*list)->setNext(obj);
108 FreeList::pick(size_t size)
110 if (size < kMinObjectSize && small_objects_) {
111 FreedObject *obj = small_objects_;
112 small_objects_ = small_objects_->next();
115 if (size < kMaxSmallObject && medium_objects_) {
116 FreedObject *obj = medium_objects_;
117 medium_objects_ = medium_objects_->next();
120 if (size < kMaxMediumObject && large_objects_) {
121 FreedObject *obj = large_objects_;
122 large_objects_ = large_objects_->next();
126 FreedObject *obj = huge_objects_;
127 huge_objects_ = huge_objects_->next();
136 small_objects_ = NULL;
137 medium_objects_ = NULL;
138 large_objects_ = NULL;
139 huge_objects_ = NULL;
142 OldSpace::OldSpace(Zone *zone)
150 OldSpace::initialize()
152 first_ = HeapChunk::New(first_, HeapChunk::kDefaultSize);
154 cursor_ = first_->first();
159 OldSpace::~OldSpace()
162 HeapChunk *temp = first_->next();
163 HeapChunk::Destroy(first_);
169 OldSpace::allocateSlow(size_t nbytes)
171 if (FreedObject *obj = freelist_.pick(nbytes)) {
172 Address address = reinterpret_cast<Address>(obj);
173 size_t actual = obj->size();
174 assert(actual >= nbytes);
175 if (actual != nbytes)
176 markRegionFree(address + nbytes, actual - nbytes);
181 // Free unused stuff at the end of the current chunk.
182 if (cursor_ != last_->end())
183 markRegionFree(cursor_, last_->end() - cursor_);
187 // The next chunk is guaranteed to be empty.
188 chunk = last_->next();
190 chunk = HeapChunk::New(last_, HeapChunk::kDefaultSize);
196 cursor_ = chunk->first();
198 assert(cursor_ + nbytes <= chunk->end());
200 Address address = cursor_;
206 OldSpace::markRegionFree(Address start, size_t length)
208 FreedObject *obj = reinterpret_cast<FreedObject *>(start);
209 new (obj) FreedObject(zone_->getMap(MapKind_FreeRegion), length);
211 if (length < sizeof(FreedObject)) {
212 // Can't encode a list in this object, but it's marked free, so we're done.
220 OldSpace::freeUnusedPages()
222 HeapChunk **prev = &first_;
223 HeapChunk *empty = NULL;
225 HeapChunk *chunk = *prev;
226 if (chunk->isEmpty()) {
227 *prev = chunk->next();
229 // Remove this chunk.
230 HeapChunk::Destroy(chunk);
235 prev = chunk->nextp();
239 *empty->nextp() = NULL;
240 *last_->nextp() = empty;
245 OldSpace::resetFreeList()
250 LargeObjectSpace::LargeObjectSpace()
256 LargeObjectSpace::~LargeObjectSpace()
259 HeapChunk *temp = first_->next();
260 HeapChunk::Destroy(first_);
266 LargeObjectSpace::initialize()
272 LargeObjectSpace::allocate(size_t nbytes)
274 assert(IsAligned(nbytes, kObjectAlignment));
276 // Always allocate a new chunk for large objects.
277 HeapChunk *chunk = HeapChunk::New(last_, nbytes);
285 return chunk->first();
289 LargeObjectSpace::sweep()
294 HeapChunk **pprev = &first_;
296 HeapChunk *chunk = *pprev;
297 Object *obj = reinterpret_cast<Object *>(chunk->first());
298 MarkBit bit = HeapChunk::GetMarkBit(obj);
299 if (HeapChunk::IsWhite(bit)) {
300 *pprev = chunk->next();
301 HeapChunk::Destroy(chunk);
303 assert(HeapChunk::IsBlack(bit));
304 HeapChunk::Clear(bit);
305 pprev = chunk->nextp();