1.1 --- a/jitcraft/Heap-inl.h Wed Jul 04 19:54:53 2012 -0400
1.2 +++ b/jitcraft/Heap-inl.h Fri Jul 06 09:45:21 2012 -0400
1.3 @@ -1,4 +1,5 @@
1.4 -/*
1.5 +/* vim: set ts=4 sw=4 tw=99 et:
1.6 + *
1.7 * Copyright (C) 2012 David Anderson
1.8 *
1.9 * This file is part of JITCraft.
1.10 @@ -37,10 +38,8 @@
1.11 inline Address
1.12 Heap::newObject(size_t bytes, Tenure age)
1.13 {
1.14 -#if 0
1.15 - if (bytes >= kLargeObjectThreshold)
1.16 + if (bytes >= HeapChunk::kLargeObjectThreshold)
1.17 return newLargeObject(bytes);
1.18 -#endif
1.19
1.20 if (age == Tenure_Stack) {
1.21 if (Address addr = newStackObject(bytes))
1.22 @@ -62,13 +61,10 @@
1.23 if (Address addr = newOldObject(bytes))
1.24 return addr;
1.25
1.26 - // Uh-oh - perform a collection.
1.27 - assert(false);
1.28 + // Uh-oh - perform a last-ditch collection.
1.29 + reclaim();
1.30
1.31 -#if 0
1.32 return newOldObject(bytes);
1.33 -#endif
1.34 - return NULL;
1.35 }
1.36
1.37 inline Object *
1.38 @@ -89,6 +85,17 @@
1.39 return lifoSpace_.allocate(bytes);
1.40 }
1.41
1.42 +inline Address
1.43 +Heap::newOldObject(size_t bytes)
1.44 +{
1.45 + return oldSpace_.allocate(bytes);
1.46 +}
1.47 +
1.48 +inline Address
1.49 +Heap::newLargeObject(size_t bytes)
1.50 +{
1.51 + return largeSpace_.allocate(bytes);
1.52 +}
1.53
1.54 inline void
1.55 Object::write(Zone *zone, Object **ptr, Object *obj)
2.1 --- a/jitcraft/Heap.cpp Wed Jul 04 19:54:53 2012 -0400
2.2 +++ b/jitcraft/Heap.cpp Fri Jul 06 09:45:21 2012 -0400
2.3 @@ -1,51 +1,54 @@
2.4 -/*
2.5 - * Copyright (C) 2012 David Anderson
2.6 - *
2.7 - * This file is part of JITCraft.
2.8 - *
2.9 - * JITCraft is free software: you can redistribute it and/or modify it under
2.10 - * the terms of the GNU General Public License as published by the Free
2.11 - * Software Foundation, either version 3 of the License, or (at your option)
2.12 - * any later version.
2.13 - *
2.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
2.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
2.17 - *
2.18 - * You should have received a copy of the GNU General Public License along with
2.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
2.20 - */
2.21 -#include "Heap.h"
2.22 -#include "Heap-inl.h"
2.23 -#include "Spaces-inl.h"
2.24 -
2.25 -using namespace jc;
2.26 -
2.27 -Heap::Heap(Zone *zone)
2.28 - : zone_(zone)
2.29 -{
2.30 -}
2.31 -
2.32 -bool
2.33 -Heap::initialize()
2.34 -{
2.35 - if (!lifoSpace_.initialize())
2.36 - return false;
2.37 - if (!oldSpace_.initialize())
2.38 - return false;
2.39 - if (!mapSpace_.initialize())
2.40 - return false;
2.41 -
2.42 - if ((metaMap_ = allocateMap(MapKind_Meta, sizeof(Map))) == NULL)
2.43 - return false;
2.44 - metaMap_->init(metaMap_);
2.45 -
2.46 - return true;
2.47 -}
2.48 -
2.49 -Map *
2.50 -Heap::allocateMap(MapKind kind, size_t bytes)
2.51 -{
2.52 +/* vim: set ts=4 sw=4 tw=99 et:
2.53 + *
2.54 + * Copyright (C) 2012 David Anderson
2.55 + *
2.56 + * This file is part of JITCraft.
2.57 + *
2.58 + * JITCraft is free software: you can redistribute it and/or modify it under
2.59 + * the terms of the GNU General Public License as published by the Free
2.60 + * Software Foundation, either version 3 of the License, or (at your option)
2.61 + * any later version.
2.62 + *
2.63 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
2.64 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
2.65 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
2.66 + *
2.67 + * You should have received a copy of the GNU General Public License along with
2.68 + * JITCraft. If not, see http://www.gnu.org/licenses/.
2.69 + */
2.70 +#include "Heap.h"
2.71 +#include "Heap-inl.h"
2.72 +#include "Spaces-inl.h"
2.73 +
2.74 +using namespace jc;
2.75 +
2.76 +Heap::Heap(Zone *zone)
2.77 + : zone_(zone)
2.78 +{
2.79 +}
2.80 +
2.81 +bool
2.82 +Heap::initialize()
2.83 +{
2.84 + if (!lifoSpace_.initialize())
2.85 + return false;
2.86 + if (!oldSpace_.initialize())
2.87 + return false;
2.88 + if (!mapSpace_.initialize())
2.89 + return false;
2.90 + if (!largeSpace_.initialize())
2.91 + return false;
2.92 +
2.93 + if ((metaMap_ = allocateMap(MapKind_Meta, sizeof(Map))) == NULL)
2.94 + return false;
2.95 + metaMap_->init(metaMap_);
2.96 +
2.97 + return true;
2.98 +}
2.99 +
2.100 +Map *
2.101 +Heap::allocateMap(MapKind kind, size_t bytes)
2.102 +{
2.103 size_t actualBytes = Align(bytes, kObjectAlignment);
2.104
2.105 Address addr = mapSpace_.allocate(actualBytes);
2.106 @@ -59,11 +62,11 @@
2.107 Object *obj = InitAddressIntoObject(addr, NULL);
2.108 Map *map = reinterpret_cast<Map *>(obj);
2.109 map->setKind(kind);
2.110 - return map;
2.111 -}
2.112 -
2.113 -Address
2.114 -Heap::newOldObject(size_t bytes)
2.115 -{
2.116 - return oldSpace_.allocate(bytes);
2.117 -}
2.118 + return map;
2.119 +}
2.120 +
2.121 +void
2.122 +Heap::reclaim()
2.123 +{
2.124 +}
2.125 +
3.1 --- a/jitcraft/Heap.h Wed Jul 04 19:54:53 2012 -0400
3.2 +++ b/jitcraft/Heap.h Fri Jul 06 09:45:21 2012 -0400
3.3 @@ -1,4 +1,5 @@
3.4 -/*
3.5 +/* vim: set ts=4 sw=4 tw=99 et:
3.6 + *
3.7 * Copyright (C) 2012 David Anderson
3.8 *
3.9 * This file is part of JITCraft.
3.10 @@ -28,13 +29,67 @@
3.11
3.12 class Zone;
3.13
3.14 -// Heap-allocated objects go here. Heaps are thread-local.
3.15 +// Heap-allocated objects go here. Heaps are thread-local. The heap contains
3.16 +// four spaces:
3.17 +//
3.18 +// LIFO Space: Used for objects that may be stack-allocated.
3.19 +// New Space: Used for objects that are expected to be short-lived.
3.20 +// Old Space: Used for objects that are expected to be long-lived, or that
3.21 +// survive one collection.
3.22 +// Large Space: Used for objects that are so large they should never be
3.23 +// moved between spaces.
3.24 +//
3.25 +// The garbage collector is both incremental and generational. Marking is
3.26 +// performed incrementally, interleaved with program execution. Minor
3.27 +// collections are also performed to mitigate the potential necessity of
3.28 +// major collections.
3.29 +//
3.30 +// MINOR COLLECTIONS (also called "scavenges") are usually performed when the
3.31 +// new space reaches maximum capacity. During a minor collection, all live
3.32 +// objects in the new space are moved into the old space. Then, the new space
3.33 +// is reset such that it is empty.
3.34 +//
3.35 +// The new is split into contiguous halves. When both halves reach maximum
3.36 +// capacity, a scavenge is performed on the older half. Thus, allocation is
3.37 +// only ever performed in one half at a time, to give newer objects a chance
3.38 +// to die.
3.39 +//
3.40 +// Scavenges are beneficial for two major reasons:
3.41 +// (1) Allocation from the new space is just a pointer bump.
3.42 +// (2) Only the root set and remembered sets need to visited.
3.43 +//
3.44 +// The "remembered set" is a list of all pointers that reach into the new
3.45 +// space, but come from the Old or Large spaces. The remembered set is
3.46 +// maintained via write barriers, and if it becomes full, entire chunks
3.47 +// are marked as requiring traversal.
3.48 +//
3.49 +// The root and remembered sets must be visited twice: once to determine
3.50 +// which objects in the new space are live, and again to update any
3.51 +// references after the new space has been reclaimed.
3.52 +//
3.53 +// Live objects in the LIFO space are always deeply traversed for pointers
3.54 +// into the new space, since it would be too difficult to maintain a working
3.55 +// remembered set.
3.56 +//
3.57 +// MAJOR COLLECTIONS are performed periodically, when either a given memory
3.58 +// threshold has been reached, or when requested by the host application.
3.59 +// They are also performed if no memory can be allocated.
3.60 +//
3.61 +// Major collections are extremely slow; they require full heap traversal,
3.62 +// which can take more than a second on very large heaps. However, they
3.63 +// have the greatest chance at reclaiming all syntactically dead objects.
3.64 +//
3.65 +// SWEEPING is performed after major collections. The free space in between
3.66 +// live objects is added to a free list. Tenured allocations are then
3.67 +// performed in the free space, if possible.
3.68 +//
3.69 class Heap
3.70 {
3.71 Zone *zone_;
3.72 HeapStack lifoSpace_;
3.73 OldSpace mapSpace_;
3.74 OldSpace oldSpace_;
3.75 + LargeObjectSpace largeSpace_;
3.76
3.77 Map *metaMap_;
3.78
3.79 @@ -54,7 +109,8 @@
3.80 };
3.81
3.82 private:
3.83 - Address newOldObject(size_t bytes);
3.84 + inline Address newLargeObject(size_t bytes);
3.85 + inline Address newOldObject(size_t bytes);
3.86 inline Address newStackObject(size_t bytes);
3.87 inline Address newObject(size_t bytes, Tenure pretenure);
3.88
3.89 @@ -74,6 +130,9 @@
3.90 inline void unwindLifo(Address to) {
3.91 lifoSpace_.unwind(to);
3.92 }
3.93 +
3.94 + // Perform a full garbage collection.
3.95 + void reclaim();
3.96 };
3.97
3.98 }
4.1 --- a/jitcraft/Spaces-inl.h Wed Jul 04 19:54:53 2012 -0400
4.2 +++ b/jitcraft/Spaces-inl.h Fri Jul 06 09:45:21 2012 -0400
4.3 @@ -1,45 +1,46 @@
4.4 -/*
4.5 - * Copyright (C) 2012 David Anderson
4.6 - *
4.7 - * This file is part of JITCraft.
4.8 - *
4.9 - * JITCraft is free software: you can redistribute it and/or modify it under
4.10 - * the terms of the GNU General Public License as published by the Free
4.11 - * Software Foundation, either version 3 of the License, or (at your option)
4.12 - * any later version.
4.13 - *
4.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
4.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
4.17 - *
4.18 - * You should have received a copy of the GNU General Public License along with
4.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
4.20 - */
4.21 -#ifndef _include_jitcraft_spaces_inl_h_
4.22 -#define _include_jitcraft_spaces_inl_h_
4.23 -
4.24 -namespace jc {
4.25 -
4.26 -inline Address
4.27 -HeapStack::allocate(size_t nbytes)
4.28 -{
4.29 - nbytes = Align(nbytes, kObjectAlignment);
4.30 -
4.31 - if (pos_ + nbytes > end_)
4.32 - return NULL;
4.33 -
4.34 - Address ptr = pos_;
4.35 - pos_ += nbytes;
4.36 - return ptr;
4.37 -}
4.38 -
4.39 -inline void
4.40 -HeapStack::unwind(Address to)
4.41 -{
4.42 - assert(to <= pos_ && to >= buffer_);
4.43 - pos_ = to;
4.44 -}
4.45 -
4.46 +/* vim: set ts=4 sw=4 tw=99 et:
4.47 + *
4.48 + * Copyright (C) 2012 David Anderson
4.49 + *
4.50 + * This file is part of JITCraft.
4.51 + *
4.52 + * JITCraft is free software: you can redistribute it and/or modify it under
4.53 + * the terms of the GNU General Public License as published by the Free
4.54 + * Software Foundation, either version 3 of the License, or (at your option)
4.55 + * any later version.
4.56 + *
4.57 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
4.58 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4.59 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
4.60 + *
4.61 + * You should have received a copy of the GNU General Public License along with
4.62 + * JITCraft. If not, see http://www.gnu.org/licenses/.
4.63 + */
4.64 +#ifndef _include_jitcraft_spaces_inl_h_
4.65 +#define _include_jitcraft_spaces_inl_h_
4.66 +
4.67 +namespace jc {
4.68 +
4.69 +inline Address
4.70 +HeapStack::allocate(size_t nbytes)
4.71 +{
4.72 + nbytes = Align(nbytes, kObjectAlignment);
4.73 +
4.74 + if (pos_ + nbytes > end_)
4.75 + return NULL;
4.76 +
4.77 + Address ptr = pos_;
4.78 + pos_ += nbytes;
4.79 + return ptr;
4.80 +}
4.81 +
4.82 +inline void
4.83 +HeapStack::unwind(Address to)
4.84 +{
4.85 + assert(to <= pos_ && to >= buffer_);
4.86 + pos_ = to;
4.87 +}
4.88 +
4.89 inline Address
4.90 HeapChunk::allocate(size_t nbytes)
4.91 {
4.92 @@ -60,8 +61,8 @@
4.93 return addr;
4.94
4.95 return allocateSlow(nbytes);
4.96 -}
4.97 -
4.98 -}
4.99 -
4.100 -#endif // _include_jitcraft_spaces_inl_h_
4.101 +}
4.102 +
4.103 +}
4.104 +
4.105 +#endif // _include_jitcraft_spaces_inl_h_
5.1 --- a/jitcraft/Spaces.cpp Wed Jul 04 19:54:53 2012 -0400
5.2 +++ b/jitcraft/Spaces.cpp Fri Jul 06 09:45:21 2012 -0400
5.3 @@ -1,52 +1,54 @@
5.4 -/*
5.5 - * Copyright (C) 2012 David Anderson
5.6 - *
5.7 - * This file is part of JITCraft.
5.8 - *
5.9 - * JITCraft is free software: you can redistribute it and/or modify it under
5.10 - * the terms of the GNU General Public License as published by the Free
5.11 - * Software Foundation, either version 3 of the License, or (at your option)
5.12 - * any later version.
5.13 - *
5.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
5.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
5.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5.17 - *
5.18 - * You should have received a copy of the GNU General Public License along with
5.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
5.20 - */
5.21 -#include "Spaces.h"
5.22 -#include "Platform.h"
5.23 -#include "Spaces-inl.h"
5.24 -
5.25 -using namespace jc;
5.26 -
5.27 -HeapStack::HeapStack()
5.28 - : buffer_(NULL),
5.29 - pos_(NULL),
5.30 - end_(NULL)
5.31 -{
5.32 -}
5.33 -
5.34 -HeapStack::~HeapStack()
5.35 -{
5.36 - if (buffer_)
5.37 - OS::UnmapAlignedMemory(map_.base(), map_.size());
5.38 -}
5.39 -
5.40 -bool
5.41 -HeapStack::initialize()
5.42 -{
5.43 - map_ = OS::MapAlignedMemory(kStackSize, kStackSize, OS::Map_Commit);
5.44 - if (!map_.base())
5.45 - return false;
5.46 -
5.47 - buffer_ = map_.aligned();
5.48 - pos_ = buffer_;
5.49 - end_ = buffer_ + kStackSize;
5.50 - return true;
5.51 -}
5.52 -
5.53 +/* vim: set ts=4 sw=4 tw=99 et:
5.54 + *
5.55 + * Copyright (C) 2012 David Anderson
5.56 + *
5.57 + * This file is part of JITCraft.
5.58 + *
5.59 + * JITCraft is free software: you can redistribute it and/or modify it under
5.60 + * the terms of the GNU General Public License as published by the Free
5.61 + * Software Foundation, either version 3 of the License, or (at your option)
5.62 + * any later version.
5.63 + *
5.64 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
5.65 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
5.66 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
5.67 + *
5.68 + * You should have received a copy of the GNU General Public License along with
5.69 + * JITCraft. If not, see http://www.gnu.org/licenses/.
5.70 + */
5.71 +#include "Spaces.h"
5.72 +#include "Platform.h"
5.73 +#include "Spaces-inl.h"
5.74 +
5.75 +using namespace jc;
5.76 +
5.77 +HeapStack::HeapStack()
5.78 + : buffer_(NULL),
5.79 + pos_(NULL),
5.80 + end_(NULL)
5.81 +{
5.82 +}
5.83 +
5.84 +HeapStack::~HeapStack()
5.85 +{
5.86 + if (buffer_)
5.87 + OS::UnmapAlignedMemory(map_.base(), map_.size());
5.88 +}
5.89 +
5.90 +bool
5.91 +HeapStack::initialize()
5.92 +{
5.93 + map_ = OS::MapAlignedMemory(kStackSize, kStackSize, OS::Map_Commit);
5.94 + if (!map_.base())
5.95 + return false;
5.96 +
5.97 + buffer_ = map_.aligned();
5.98 + pos_ = buffer_;
5.99 + end_ = buffer_ + kStackSize;
5.100 + mask_ = kStackSize - 1;
5.101 + return true;
5.102 +}
5.103 +
5.104 HeapChunk *
5.105 HeapChunk::New(HeapChunk *prev, size_t size)
5.106 {
5.107 @@ -105,4 +107,18 @@
5.108 first_ = temp;
5.109 }
5.110 }
5.111 -
5.112 +
5.113 +
5.114 +Address
5.115 +LargeObjectSpace::allocate(size_t nbytes)
5.116 +{
5.117 + assert(IsAligned(nbytes, kObjectAlignment));
5.118 +
5.119 + if (last_) {
5.120 + if (Address addr = last_->allocate(nbytes))
5.121 + return addr;
5.122 + }
5.123 +
5.124 +
5.125 +}
5.126 +
6.1 --- a/jitcraft/Spaces.h Wed Jul 04 19:54:53 2012 -0400
6.2 +++ b/jitcraft/Spaces.h Fri Jul 06 09:45:21 2012 -0400
6.3 @@ -1,56 +1,65 @@
6.4 -/*
6.5 - * Copyright (C) 2012 David Anderson
6.6 - *
6.7 - * This file is part of JITCraft.
6.8 - *
6.9 - * JITCraft is free software: you can redistribute it and/or modify it under
6.10 - * the terms of the GNU General Public License as published by the Free
6.11 - * Software Foundation, either version 3 of the License, or (at your option)
6.12 - * any later version.
6.13 - *
6.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
6.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
6.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
6.17 - *
6.18 - * You should have received a copy of the GNU General Public License along with
6.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
6.20 - */
6.21 -#ifndef _include_jitcraft_spaces_h_
6.22 -#define _include_jitcraft_spaces_h_
6.23 -
6.24 -#include "Utility.h"
6.25 -#include "Platform.h"
6.26 -
6.27 -namespace jc {
6.28 -
6.29 -static const size_t kObjectAlignment = 8;
6.30 -
6.31 -// The heap stack is designed for structures which are known to not escape the
6.32 -// program stack, and can thus be quickly allocated in a LIFO manner.
6.33 -//
6.34 -class HeapStack
6.35 -{
6.36 - OS::AlignableMapping map_;
6.37 - Address buffer_;
6.38 - Address pos_;
6.39 - Address end_;
6.40 -
6.41 - private:
6.42 - static const size_t kStackSize = 1024 * 1024;
6.43 -
6.44 - public:
6.45 - HeapStack();
6.46 - ~HeapStack();
6.47 - bool initialize();
6.48 -
6.49 - public:
6.50 - Address position() const {
6.51 - return pos_;
6.52 - }
6.53 - inline Address allocate(size_t nbytes);
6.54 - inline void unwind(Address to);
6.55 -};
6.56 -
6.57 +/* vim: set ts=4 sw=4 tw=99 et:
6.58 + *
6.59 + * Copyright (C) 2012 David Anderson
6.60 + *
6.61 + * This file is part of JITCraft.
6.62 + *
6.63 + * JITCraft is free software: you can redistribute it and/or modify it under
6.64 + * the terms of the GNU General Public License as published by the Free
6.65 + * Software Foundation, either version 3 of the License, or (at your option)
6.66 + * any later version.
6.67 + *
6.68 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
6.69 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
6.70 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
6.71 + *
6.72 + * You should have received a copy of the GNU General Public License along with
6.73 + * JITCraft. If not, see http://www.gnu.org/licenses/.
6.74 + */
6.75 +#ifndef _include_jitcraft_spaces_h_
6.76 +#define _include_jitcraft_spaces_h_
6.77 +
6.78 +#include <limits.h>
6.79 +#include "Utility.h"
6.80 +#include "Platform.h"
6.81 +
6.82 +namespace jc {
6.83 +
6.84 +class Object;
6.85 +
6.86 +static const size_t kObjectAlignment = 8;
6.87 +
6.88 +// The heap stack is designed for structures which are known to not escape the
6.89 +// program stack, and can thus be quickly allocated in a LIFO manner.
6.90 +//
6.91 +class HeapStack
6.92 +{
6.93 + OS::AlignableMapping map_;
6.94 + Address buffer_;
6.95 + Address pos_;
6.96 + Address end_;
6.97 + uintptr_t mask_;
6.98 +
6.99 + private:
6.100 + static const size_t kStackSize = 1024 * 1024;
6.101 +
6.102 + public:
6.103 + HeapStack();
6.104 + ~HeapStack();
6.105 + bool initialize();
6.106 +
6.107 + public:
6.108 + Address position() const {
6.109 + return pos_;
6.110 + }
6.111 + inline Address allocate(size_t nbytes);
6.112 + inline void unwind(Address to);
6.113 +
6.114 + inline bool contains(Object *obj) {
6.115 + return (reinterpret_cast<uintptr_t>(obj) & mask_) == reinterpret_cast<uintptr_t>(buffer_);
6.116 + }
6.117 +};
6.118 +
6.119 class HeapChunk
6.120 {
6.121 HeapChunk *next_;
6.122 @@ -65,9 +74,25 @@
6.123 Address cursor_;
6.124
6.125 public:
6.126 - static const size_t kMaxObjectSize = 1 * kGB;
6.127 - static const size_t kDefaultSize = 256 * kKB;
6.128 - static const size_t kAlignment = 256 * kKB;
6.129 + static const size_t kDefaultSize = 1 * kMB;
6.130 + static const size_t kAlignment = 1 * kMB;
6.131 +
6.132 + // Maximum size of an object that will fit in a page. We limit this
6.133 + // specifically to help JITs: the computation of a[i] has a special
6.134 + // instruction form on most CPUs, but the index might not be sign-
6.135 + // extended on 64-bit architectures. We limit the size such that:
6.136 + //
6.137 + // index * sizeof(Object *)
6.138 + //
6.139 + // Is guaranteed to not overflow a signed 32-bit integer.
6.140 + static const size_t kMaxObjectSize = INT_MAX / sizeof(Object *);
6.141 +
6.142 + // Size of a HeapChunk header.
6.143 + static const size_t kHeaderSize =
6.144 + sizeof(HeapChunk *) +
6.145 + sizeof(Address) +
6.146 + sizeof(Address) +
6.147 + sizeof(Address);
6.148
6.149 // All objects must be allocated in the first kAlignment bytes of the
6.150 // chunk. Every object is at least 8 bytes (kPointerAlignment), so we
6.151 @@ -93,15 +118,16 @@
6.152 static const size_t kMarkBytes = kMarkBits / 8;
6.153 static const size_t kMarkWords = kMarkBytes / sizeof(uint32);
6.154
6.155 - static inline size_t offsetToMarkBits()
6.156 - {
6.157 - return Align(sizeof(HeapChunk), kObjectAlignment);
6.158 - }
6.159 + static const size_t kMarkBitsOffset = kHeaderSize;
6.160 + static const size_t kFirstObject = kMarkBitsOffset + kMarkBytes;
6.161
6.162 - static inline size_t offsetToFirst()
6.163 - {
6.164 - assert(IsAligned(kMarkBytes, kObjectAlignment));
6.165 - return offsetToMarkBits() + kMarkBytes;
6.166 + // Threshold for allocating an object in the large object space.
6.167 + static const size_t kLargeObjectThreshold = kAlignment - kFirstObject;
6.168 +
6.169 + static inline void StaticAsserts() {
6.170 + STATIC_ASSERT(kHeaderSize == sizeof(HeapChunk));
6.171 + STATIC_ASSERT(IS_ALIGNED(kHeaderSize, kObjectAlignment));
6.172 + STATIC_ASSERT(IS_ALIGNED(kFirstObject, kObjectAlignment));
6.173 }
6.174
6.175 public:
6.176 @@ -124,11 +150,10 @@
6.177 return end() - base();
6.178 }
6.179 Address first() {
6.180 - return reinterpret_cast<Address>(this) + offsetToFirst();
6.181 + return reinterpret_cast<Address>(this) + kFirstObject;
6.182 }
6.183 uint32 *markBits() {
6.184 - return reinterpret_cast<uint32 *>(reinterpret_cast<Address>(this) +
6.185 - offsetToMarkBits());
6.186 + return reinterpret_cast<uint32 *>(reinterpret_cast<Address>(this) + kMarkBitsOffset);
6.187 }
6.188 };
6.189
6.190 @@ -146,8 +171,23 @@
6.191 public:
6.192 inline Address allocate(size_t nbytes);
6.193 Address allocateSlow(size_t nbytes);
6.194 -};
6.195 -
6.196 -}
6.197 -
6.198 -#endif // _include_jitcraft_spaces_h_
6.199 +};
6.200 +
6.201 +class LargeObjectSpace
6.202 +{
6.203 + HeapChunk *first_;
6.204 + HeapChunk *last_;
6.205 +
6.206 + public:
6.207 + LargeObjectSpace();
6.208 + ~LargeObjectSpace();
6.209 +
6.210 + bool initialize();
6.211 +
6.212 + public:
6.213 + Address allocate(size_t nbytes);
6.214 +};
6.215 +
6.216 +}
6.217 +
6.218 +#endif // _include_jitcraft_spaces_h_
7.1 --- a/jitcraft/Utility.h Wed Jul 04 19:54:53 2012 -0400
7.2 +++ b/jitcraft/Utility.h Fri Jul 06 09:45:21 2012 -0400
7.3 @@ -1,4 +1,5 @@
7.4 -/*
7.5 +/* vim: set ts=4 sw=4 tw=99 et:
7.6 + *
7.7 * Copyright (C) 2012 David Anderson
7.8 *
7.9 * This file is part of JITCraft.
7.10 @@ -125,6 +126,8 @@
7.11 #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
7.12 #define STATIC_ASSERT(cond) extern int static_assert_f(int a[(cond) ? 1 : -1])
7.13
7.14 +#define IS_ALIGNED(addr, alignment) (!(uintptr_t(addr) & ((alignment) - 1)))
7.15 +
7.16 template <typename T>
7.17 static inline bool
7.18 IsAligned(T addr, size_t alignment)
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/tests/prototype/lifo.sp Fri Jul 06 09:45:21 2012 -0400
8.3 @@ -0,0 +1,13 @@
8.4 +q(&a)
8.5 +{
8.6 + return 5;
8.7 +}
8.8 +
8.9 +main()
8.10 +{
8.11 + for (new i = 0; i < 100; i++) {
8.12 + q(i);
8.13 + }
8.14 + return 5;
8.15 +}
8.16 +