| 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
 |