| 1 | #ifndef GC_SLAB_H
|
| 2 | #define GC_SLAB_H
|
| 3 |
|
| 4 | #include <utility> // std::is_pointer
|
| 5 |
|
| 6 | #include "mycpp/common.h" // DISALLOW_COPY_AND_ASSIGN
|
| 7 | #include "mycpp/gc_obj.h"
|
| 8 |
|
| 9 | // Return the size of a resizeable allocation. Just round up to the nearest
|
| 10 | // power of 2. (CPython has an interesting policy in listobject.c.)
|
| 11 | //
|
| 12 | // https://stackoverflow.com/questions/466204/rounding-up-to-next-power-of-2
|
| 13 | //
|
| 14 | // Used by List<T> and Dict<K, V>.
|
| 15 |
|
| 16 | inline int RoundUp(int n) {
|
| 17 | // TODO: what if int isn't 32 bits?
|
| 18 | n--;
|
| 19 | n |= n >> 1;
|
| 20 | n |= n >> 2;
|
| 21 | n |= n >> 4;
|
| 22 | n |= n >> 8;
|
| 23 | n |= n >> 16;
|
| 24 | n++;
|
| 25 | return n;
|
| 26 | }
|
| 27 |
|
| 28 | template <typename T>
|
| 29 | class Slab {
|
| 30 | // Slabs of pointers are scanned; slabs of ints/bools are opaque.
|
| 31 | public:
|
| 32 | explicit Slab(unsigned num_items) {
|
| 33 | }
|
| 34 |
|
| 35 | static constexpr ObjHeader obj_header(unsigned num_items) {
|
| 36 | return ObjHeader::Slab(
|
| 37 | std::is_pointer<T>() ? HeapTag::Scanned : HeapTag::Opaque, num_items);
|
| 38 | }
|
| 39 |
|
| 40 | T items_[1]; // variable length
|
| 41 |
|
| 42 | DISALLOW_COPY_AND_ASSIGN(Slab);
|
| 43 | };
|
| 44 |
|
| 45 | template <typename T, int N>
|
| 46 | class GlobalSlab {
|
| 47 | // A template type with the same layout as Slab of length N. For
|
| 48 | // initializing global constant List.
|
| 49 | public:
|
| 50 | T items_[N];
|
| 51 |
|
| 52 | DISALLOW_COPY_AND_ASSIGN(GlobalSlab)
|
| 53 | };
|
| 54 |
|
| 55 | // XXX(watk): Does this make sense?
|
| 56 | const int kSlabHeaderSize = sizeof(ObjHeader);
|
| 57 |
|
| 58 | #endif // GC_SLAB_H
|