/home/andy/git/oilshell/oil/mycpp/gc_slab.h
Line | Count | Source |
1 | | #ifndef GC_SLAB_H |
2 | | #define GC_SLAB_H |
3 | | |
4 | | // Return the size of a resizeable allocation. For now we just round up by |
5 | | // powers of 2. This could be optimized later. CPython has an interesting |
6 | | // policy in listobject.c. |
7 | | // |
8 | | // https://stackoverflow.com/questions/466204/rounding-up-to-next-power-of-2 |
9 | 1.06k | inline int RoundUp(int n) { |
10 | | // minimum size |
11 | 1.06k | if (n < 8) { |
12 | 485 | return 8; |
13 | 485 | } |
14 | | |
15 | | // TODO: what if int isn't 32 bits? |
16 | 583 | n--; |
17 | 583 | n |= n >> 1; |
18 | 583 | n |= n >> 2; |
19 | 583 | n |= n >> 4; |
20 | 583 | n |= n >> 8; |
21 | 583 | n |= n >> 16; |
22 | 583 | n++; |
23 | 583 | return n; |
24 | 1.06k | } |
25 | | |
26 | | template <typename T> |
27 | 169 | inline void InitSlabCell(Obj* obj) { |
28 | | // log("SCANNED"); |
29 | 169 | obj->heap_tag_ = Tag::Scanned; |
30 | 169 | } _Z12InitSlabCellIP3StrEvP3Obj Line | Count | Source | 27 | 124 | inline void InitSlabCell(Obj* obj) { | 28 | | // log("SCANNED"); | 29 | 124 | obj->heap_tag_ = Tag::Scanned; | 30 | 124 | } |
_Z12InitSlabCellIbEvP3Obj Line | Count | Source | 27 | 3 | inline void InitSlabCell(Obj* obj) { | 28 | | // log("SCANNED"); | 29 | 3 | obj->heap_tag_ = Tag::Scanned; | 30 | 3 | } |
_Z12InitSlabCellIdEvP3Obj Line | Count | Source | 27 | 2 | inline void InitSlabCell(Obj* obj) { | 28 | | // log("SCANNED"); | 29 | 2 | obj->heap_tag_ = Tag::Scanned; | 30 | 2 | } |
_Z12InitSlabCellIP6Tuple2IP3StriEEvP3Obj Line | Count | Source | 27 | 1 | inline void InitSlabCell(Obj* obj) { | 28 | | // log("SCANNED"); | 29 | 1 | obj->heap_tag_ = Tag::Scanned; | 30 | 1 | } |
_Z12InitSlabCellIP6Tuple2IiP3StrEEvP3Obj Line | Count | Source | 27 | 2 | inline void InitSlabCell(Obj* obj) { | 28 | | // log("SCANNED"); | 29 | 2 | obj->heap_tag_ = Tag::Scanned; | 30 | 2 | } |
_Z12InitSlabCellIPN10hnode_asdl5fieldEEvP3Obj Line | Count | Source | 27 | 34 | inline void InitSlabCell(Obj* obj) { | 28 | | // log("SCANNED"); | 29 | 34 | obj->heap_tag_ = Tag::Scanned; | 30 | 34 | } |
_Z12InitSlabCellIPN12runtime_asdl7value_tEEvP3Obj Line | Count | Source | 27 | 3 | inline void InitSlabCell(Obj* obj) { | 28 | | // log("SCANNED"); | 29 | 3 | obj->heap_tag_ = Tag::Scanned; | 30 | 3 | } |
|
31 | | |
32 | | template <> |
33 | 382 | inline void InitSlabCell<int>(Obj* obj) { |
34 | | // log("OPAQUE"); |
35 | 382 | obj->heap_tag_ = Tag::Opaque; |
36 | 382 | } |
37 | | |
38 | | // don't include items_[1] |
39 | | const int kSlabHeaderSize = sizeof(Obj); |
40 | | |
41 | | // Opaque slab, e.g. for List<int> |
42 | | template <typename T> |
43 | | class Slab : public Obj { |
44 | | public: |
45 | 551 | explicit Slab(int obj_len) : Obj(0, 0, obj_len) { |
46 | 551 | InitSlabCell<T>(this); |
47 | 551 | } Line | Count | Source | 45 | 124 | explicit Slab(int obj_len) : Obj(0, 0, obj_len) { | 46 | 124 | InitSlabCell<T>(this); | 47 | 124 | } |
Line | Count | Source | 45 | 382 | explicit Slab(int obj_len) : Obj(0, 0, obj_len) { | 46 | 382 | InitSlabCell<T>(this); | 47 | 382 | } |
Line | Count | Source | 45 | 3 | explicit Slab(int obj_len) : Obj(0, 0, obj_len) { | 46 | 3 | InitSlabCell<T>(this); | 47 | 3 | } |
Line | Count | Source | 45 | 2 | explicit Slab(int obj_len) : Obj(0, 0, obj_len) { | 46 | 2 | InitSlabCell<T>(this); | 47 | 2 | } |
_ZN4SlabIP6Tuple2IP3StriEEC2Ei Line | Count | Source | 45 | 1 | explicit Slab(int obj_len) : Obj(0, 0, obj_len) { | 46 | 1 | InitSlabCell<T>(this); | 47 | 1 | } |
_ZN4SlabIP6Tuple2IiP3StrEEC2Ei Line | Count | Source | 45 | 2 | explicit Slab(int obj_len) : Obj(0, 0, obj_len) { | 46 | 2 | InitSlabCell<T>(this); | 47 | 2 | } |
_ZN4SlabIPN10hnode_asdl5fieldEEC2Ei Line | Count | Source | 45 | 34 | explicit Slab(int obj_len) : Obj(0, 0, obj_len) { | 46 | 34 | InitSlabCell<T>(this); | 47 | 34 | } |
_ZN4SlabIPN12runtime_asdl7value_tEEC2Ei Line | Count | Source | 45 | 3 | explicit Slab(int obj_len) : Obj(0, 0, obj_len) { | 46 | 3 | InitSlabCell<T>(this); | 47 | 3 | } |
|
48 | | T items_[1]; // variable length |
49 | | }; |
50 | | |
51 | | template <typename T, int N> |
52 | | class GlobalSlab { |
53 | | // A template type with the same layout as Str with length N-1 (which needs a |
54 | | // buffer of size N). For initializing global constant instances. |
55 | | public: |
56 | | OBJ_HEADER() |
57 | | |
58 | | T items_[N]; |
59 | | |
60 | | DISALLOW_COPY_AND_ASSIGN(GlobalSlab) |
61 | | }; |
62 | | |
63 | | // Note: entries will be zero'd because the Heap is zero'd. |
64 | | template <typename T> |
65 | 551 | inline Slab<T>* NewSlab(int len) { |
66 | 551 | int obj_len = RoundUp(kSlabHeaderSize + len * sizeof(T)); |
67 | 551 | void* place = gHeap.Allocate(obj_len); |
68 | 551 | auto slab = new (place) Slab<T>(obj_len); // placement new |
69 | 551 | return slab; |
70 | 551 | } _Z7NewSlabIP3StrEP4SlabIT_Ei Line | Count | Source | 65 | 124 | inline Slab<T>* NewSlab(int len) { | 66 | 124 | int obj_len = RoundUp(kSlabHeaderSize + len * sizeof(T)); | 67 | 124 | void* place = gHeap.Allocate(obj_len); | 68 | 124 | auto slab = new (place) Slab<T>(obj_len); // placement new | 69 | 124 | return slab; | 70 | 124 | } |
Line | Count | Source | 65 | 382 | inline Slab<T>* NewSlab(int len) { | 66 | 382 | int obj_len = RoundUp(kSlabHeaderSize + len * sizeof(T)); | 67 | 382 | void* place = gHeap.Allocate(obj_len); | 68 | 382 | auto slab = new (place) Slab<T>(obj_len); // placement new | 69 | 382 | return slab; | 70 | 382 | } |
Line | Count | Source | 65 | 3 | inline Slab<T>* NewSlab(int len) { | 66 | 3 | int obj_len = RoundUp(kSlabHeaderSize + len * sizeof(T)); | 67 | 3 | void* place = gHeap.Allocate(obj_len); | 68 | 3 | auto slab = new (place) Slab<T>(obj_len); // placement new | 69 | 3 | return slab; | 70 | 3 | } |
Line | Count | Source | 65 | 2 | inline Slab<T>* NewSlab(int len) { | 66 | 2 | int obj_len = RoundUp(kSlabHeaderSize + len * sizeof(T)); | 67 | 2 | void* place = gHeap.Allocate(obj_len); | 68 | 2 | auto slab = new (place) Slab<T>(obj_len); // placement new | 69 | 2 | return slab; | 70 | 2 | } |
_Z7NewSlabIP6Tuple2IP3StriEEP4SlabIT_Ei Line | Count | Source | 65 | 1 | inline Slab<T>* NewSlab(int len) { | 66 | 1 | int obj_len = RoundUp(kSlabHeaderSize + len * sizeof(T)); | 67 | 1 | void* place = gHeap.Allocate(obj_len); | 68 | 1 | auto slab = new (place) Slab<T>(obj_len); // placement new | 69 | 1 | return slab; | 70 | 1 | } |
_Z7NewSlabIP6Tuple2IiP3StrEEP4SlabIT_Ei Line | Count | Source | 65 | 2 | inline Slab<T>* NewSlab(int len) { | 66 | 2 | int obj_len = RoundUp(kSlabHeaderSize + len * sizeof(T)); | 67 | 2 | void* place = gHeap.Allocate(obj_len); | 68 | 2 | auto slab = new (place) Slab<T>(obj_len); // placement new | 69 | 2 | return slab; | 70 | 2 | } |
_Z7NewSlabIPN10hnode_asdl5fieldEEP4SlabIT_Ei Line | Count | Source | 65 | 34 | inline Slab<T>* NewSlab(int len) { | 66 | 34 | int obj_len = RoundUp(kSlabHeaderSize + len * sizeof(T)); | 67 | 34 | void* place = gHeap.Allocate(obj_len); | 68 | 34 | auto slab = new (place) Slab<T>(obj_len); // placement new | 69 | 34 | return slab; | 70 | 34 | } |
_Z7NewSlabIPN12runtime_asdl7value_tEEP4SlabIT_Ei Line | Count | Source | 65 | 3 | inline Slab<T>* NewSlab(int len) { | 66 | 3 | int obj_len = RoundUp(kSlabHeaderSize + len * sizeof(T)); | 67 | 3 | void* place = gHeap.Allocate(obj_len); | 68 | 3 | auto slab = new (place) Slab<T>(obj_len); // placement new | 69 | 3 | return slab; | 70 | 3 | } |
|
71 | | |
72 | | #endif // GC_SLAB_H |