Add some more API.
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/.
22 #include "Spaces-inl.h"
26 HeapStack::HeapStack()
32 HeapStack::~HeapStack()
35 HeapChunk::Destroy(chunk_);
39 HeapStack::initialize()
41 chunk_ = HeapChunk::New(NULL, kStackSize);
42 cursor_ = chunk_->first();
47 HeapChunk::New(HeapChunk *prev, size_t size)
49 OS::AlignableMapping map =
50 OS::MapAlignedMemory(size, HeapChunk::kAlignment, OS::Map_Commit);
55 HeapChunk *chunk = reinterpret_cast<HeapChunk *>(map.aligned());
56 chunk->base_ = map.base();
57 chunk->end_ = map.base() + map.size();
65 HeapChunk::Destroy(HeapChunk *chunk)
67 OS::UnmapAlignedMemory(chunk->base(), chunk->size());
71 HeapChunk::resetMarkBits()
73 memset(markBits(), 0, kMarkBytes);
77 : small_objects_(NULL),
78 medium_objects_(NULL),
85 FreeList::add(FreedObject *obj)
87 if (obj->size() < kMinObjectSize)
91 if (obj->size() < kMaxSmallObject)
92 list = &small_objects_;
93 else if (obj->size() < kMaxMediumObject)
94 list = &medium_objects_;
95 else if (obj->size() < kMaxLargeObject)
96 list = &large_objects_;
98 list = &huge_objects_;
101 (*list)->setNext(obj);
106 FreeList::pick(size_t size)
108 if (size < kMinObjectSize && small_objects_) {
109 FreedObject *obj = small_objects_;
110 small_objects_ = small_objects_->next();
113 if (size < kMaxSmallObject && medium_objects_) {
114 FreedObject *obj = medium_objects_;
115 medium_objects_ = medium_objects_->next();
118 if (size < kMaxMediumObject && large_objects_) {
119 FreedObject *obj = large_objects_;
120 large_objects_ = large_objects_->next();
124 FreedObject *obj = huge_objects_;
125 huge_objects_ = huge_objects_->next();
134 small_objects_ = NULL;
135 medium_objects_ = NULL;
136 large_objects_ = NULL;
137 huge_objects_ = NULL;
140 OldSpace::OldSpace(Zone *zone)
148 OldSpace::initialize()
150 first_ = HeapChunk::New(first_, HeapChunk::kDefaultSize);
152 cursor_ = first_->first();
157 OldSpace::~OldSpace()
160 HeapChunk *temp = first_->next();
161 HeapChunk::Destroy(first_);
167 OldSpace::allocateSlow(size_t nbytes)
169 if (FreedObject *obj = freelist_.pick(nbytes)) {
170 Address address = reinterpret_cast<Address>(obj);
171 size_t actual = obj->size();
172 assert(actual >= nbytes);
173 if (actual != nbytes)
174 markRegionFree(address + nbytes, actual - nbytes);
179 // Free unused stuff at the end of the current chunk.
180 if (cursor_ != last_->end())
181 markRegionFree(cursor_, last_->end() - cursor_);
185 // The next chunk is guaranteed to be empty.
186 chunk = last_->next();
188 chunk = HeapChunk::New(last_, HeapChunk::kDefaultSize);
194 cursor_ = chunk->first();
196 assert(cursor_ + nbytes <= chunk->end());
198 Address address = cursor_;
204 OldSpace::markRegionFree(Address start, size_t length)
206 FreedObject *obj = reinterpret_cast<FreedObject *>(start);
207 new (obj) FreedObject(zone_->getMap(MapKind_FreeRegion), length);
209 if (length < sizeof(FreedObject)) {
210 // Can't encode a list in this object, but it's marked free, so we're done.
218 OldSpace::freeUnusedPages()
220 HeapChunk **prev = &first_;
221 HeapChunk *empty = NULL;
223 HeapChunk *chunk = *prev;
224 if (chunk->isEmpty()) {
225 *prev = chunk->next();
227 // Remove this chunk.
228 HeapChunk::Destroy(chunk);
233 prev = chunk->nextp();
237 *empty->nextp() = NULL;
238 *last_->nextp() = empty;
243 OldSpace::resetFreeList()
248 LargeObjectSpace::LargeObjectSpace()
254 LargeObjectSpace::~LargeObjectSpace()
257 HeapChunk *temp = first_->next();
258 HeapChunk::Destroy(first_);
264 LargeObjectSpace::initialize()
270 LargeObjectSpace::allocate(size_t nbytes)
272 assert(IsAligned(nbytes, kObjectAlignment));
274 // Always allocate a new chunk for large objects.
275 HeapChunk *chunk = HeapChunk::New(last_, nbytes);
283 return chunk->first();
287 LargeObjectSpace::sweep()
292 HeapChunk **pprev = &first_;
294 HeapChunk *chunk = *pprev;
295 Object *obj = reinterpret_cast<Object *>(chunk->first());
296 MarkBit bit = HeapChunk::GetMarkBit(obj);
297 if (HeapChunk::IsWhite(bit)) {
298 *pprev = chunk->next();
299 HeapChunk::Destroy(chunk);
301 assert(HeapChunk::IsBlack(bit));
302 HeapChunk::Clear(bit);
303 pprev = chunk->nextp();