/home/uke/oil/mycpp/gc_alloc.h
Line | Count | Source (jump to first uncovered line) |
1 | | // gc_alloc.h: Functions that wrap gHeap.Allocate() |
2 | | |
3 | | #ifndef MYCPP_GC_ALLOC_H |
4 | | #define MYCPP_GC_ALLOC_H |
5 | | |
6 | | #include <string.h> // strlen |
7 | | |
8 | | #include <new> // placement new |
9 | | #include <utility> // std::forward |
10 | | |
11 | | #include "mycpp/gc_obj.h" // for RawObject, ObjHeader |
12 | | #include "mycpp/gc_slab.h" // for NewSlab() |
13 | | #include "mycpp/gc_str.h" // for NewStr() |
14 | | |
15 | | #if defined(BUMP_LEAK) |
16 | | #include "mycpp/bump_leak_heap.h" |
17 | | extern BumpLeakHeap gHeap; |
18 | | #elif defined(MARK_SWEEP) |
19 | | #include "mycpp/mark_sweep_heap.h" |
20 | | extern MarkSweepHeap gHeap; |
21 | | #endif |
22 | | |
23 | | #define VALIDATE_ROOTS 0 |
24 | | |
25 | | #if VALIDATE_ROOTS |
26 | | static void ValidateRoot(const RawObject* obj) { |
27 | | if (obj == nullptr) { |
28 | | return; |
29 | | } |
30 | | |
31 | | ObjHeader* header = ObjHeader::FromObject(obj); |
32 | | // log("obj %p header %p", obj, header); |
33 | | |
34 | | switch (header->heap_tag) { |
35 | | case HeapTag::Global: |
36 | | case HeapTag::Opaque: |
37 | | case HeapTag::Scanned: |
38 | | case HeapTag::FixedSize: |
39 | | break; |
40 | | |
41 | | default: |
42 | | log("root %p heap %d type %d mask %d len %d", obj, header->heap_tag, |
43 | | header->type_tag, header->u_mask_npointers); |
44 | | FAIL(kShouldNotGetHere); |
45 | | break; |
46 | | } |
47 | | } |
48 | | #endif |
49 | | |
50 | | // mycpp generates code that keeps track of the root set |
51 | | class StackRoot { |
52 | | public: |
53 | 0 | StackRoot(void* root) { |
54 | 0 | RawObject** obj = reinterpret_cast<RawObject**>(root); |
55 | 0 | #if VALIDATE_ROOTS |
56 | 0 | ValidateRoot(*obj); |
57 | 0 | #endif |
58 | 0 | gHeap.PushRoot(obj); |
59 | 0 | } |
60 | | |
61 | 0 | ~StackRoot() { |
62 | 0 | gHeap.PopRoot(); |
63 | 0 | } |
64 | | }; |
65 | | |
66 | | // sugar for tests |
67 | | class StackRoots { |
68 | | public: |
69 | | // Note: void** seems logical, because these are pointers to pointers, but |
70 | | // the C++ compiler doesn't like it. |
71 | 54.0k | StackRoots(std::initializer_list<void*> roots) { |
72 | 54.0k | n_ = roots.size(); |
73 | | |
74 | | #if VALIDATE_ROOTS |
75 | | int i = 0; |
76 | | #endif |
77 | | |
78 | 54.1k | for (auto root : roots) { // can't use roots[i] |
79 | 54.1k | RawObject** obj = reinterpret_cast<RawObject**>(root); |
80 | | #if VALIDATE_ROOTS |
81 | | ValidateRoot(*obj); |
82 | | i++; |
83 | | #endif |
84 | | |
85 | 54.1k | gHeap.PushRoot(obj); |
86 | 54.1k | } |
87 | 54.0k | } |
88 | | |
89 | 54.0k | ~StackRoots() { |
90 | 108k | for (int i = 0; i < n_; ++i) { |
91 | 54.1k | gHeap.PopRoot(); |
92 | 54.1k | } |
93 | 54.0k | } |
94 | | |
95 | | private: |
96 | | int n_; |
97 | | }; |
98 | | |
99 | | // Note: |
100 | | // - This function causes code bloat due to template expansion on hundreds of |
101 | | // types. Could switch to a GC_NEW() macro |
102 | | // - GCC generates slightly larger code if you factor out void* place and new |
103 | | // (place) T() |
104 | | // |
105 | | // Variadic templates: |
106 | | // https://eli.thegreenplace.net/2014/variadic-templates-in-c/ |
107 | | template <typename T, typename... Args> |
108 | 456 | T* Alloc(Args&&... args) { |
109 | | // Alloc() allocates space for both a header and object and guarantees that |
110 | | // they're adjacent in memory (so that they're at known offsets from one |
111 | | // another). However, this means that the address that the object is |
112 | | // constructed at is offset from the address returned by the memory allocator |
113 | | // (by the size of the header), and therefore may not be sufficiently aligned. |
114 | | // Here we assert that the object will be sufficiently aligned by making the |
115 | | // equivalent assertion that zero padding would be required to align it. |
116 | | // Note: the required padding is given by the following (according to |
117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): |
118 | | // `padding = -offset & (align - 1)`. |
119 | 456 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, |
120 | 456 | "Expected no padding"); |
121 | | |
122 | 456 | DCHECK(gHeap.is_initialized_); |
123 | | |
124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); |
125 | 456 | #if MARK_SWEEP |
126 | 456 | int obj_id; |
127 | 456 | int pool_id; |
128 | 456 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); |
129 | | #else |
130 | | void* place = gHeap.Allocate(num_bytes); |
131 | | #endif |
132 | 456 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); |
133 | 456 | #if MARK_SWEEP |
134 | 456 | header->obj_id = obj_id; |
135 | 456 | #ifndef NO_POOL_ALLOC |
136 | 456 | header->pool_id = pool_id; |
137 | 456 | #endif |
138 | 456 | #endif |
139 | 456 | void* obj = header->ObjectAddress(); |
140 | | // mycpp doesn't generated constructors that initialize every field |
141 | 456 | memset(obj, 0, sizeof(T)); |
142 | 456 | return new (obj) T(std::forward<Args>(args)...); |
143 | 456 | } _Z5AllocI6Tuple2IP6BigStriEJS2_iEEPT_DpOT0_ Line | Count | Source | 108 | 5 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 5 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 5 | "Expected no padding"); | 121 | | | 122 | 5 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 5 | #if MARK_SWEEP | 126 | 5 | int obj_id; | 127 | 5 | int pool_id; | 128 | 5 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 5 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 5 | #if MARK_SWEEP | 134 | 5 | header->obj_id = obj_id; | 135 | 5 | #ifndef NO_POOL_ALLOC | 136 | 5 | header->pool_id = pool_id; | 137 | 5 | #endif | 138 | 5 | #endif | 139 | 5 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 5 | memset(obj, 0, sizeof(T)); | 142 | 5 | return new (obj) T(std::forward<Args>(args)...); | 143 | 5 | } |
_Z5AllocI10ValueErrorJEEPT_DpOT0_ Line | Count | Source | 108 | 7 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 7 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 7 | "Expected no padding"); | 121 | | | 122 | 7 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 7 | #if MARK_SWEEP | 126 | 7 | int obj_id; | 127 | 7 | int pool_id; | 128 | 7 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 7 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 7 | #if MARK_SWEEP | 134 | 7 | header->obj_id = obj_id; | 135 | 7 | #ifndef NO_POOL_ALLOC | 136 | 7 | header->pool_id = pool_id; | 137 | 7 | #endif | 138 | 7 | #endif | 139 | 7 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 7 | memset(obj, 0, sizeof(T)); | 142 | 7 | return new (obj) T(std::forward<Args>(args)...); | 143 | 7 | } |
_Z5AllocI10ValueErrorJRP6BigStrEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI10IndexErrorJEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI7OSErrorJiEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI12RuntimeErrorJRP6BigStrEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI12UnicodeErrorJP6BigStrEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI7IOErrorJiEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI4ListIiEJEEPT_DpOT0_ Line | Count | Source | 108 | 326 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 326 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 326 | "Expected no padding"); | 121 | | | 122 | 326 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 326 | #if MARK_SWEEP | 126 | 326 | int obj_id; | 127 | 326 | int pool_id; | 128 | 326 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 326 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 326 | #if MARK_SWEEP | 134 | 326 | header->obj_id = obj_id; | 135 | 326 | #ifndef NO_POOL_ALLOC | 136 | 326 | header->pool_id = pool_id; | 137 | 326 | #endif | 138 | 326 | #endif | 139 | 326 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 326 | memset(obj, 0, sizeof(T)); | 142 | 326 | return new (obj) T(std::forward<Args>(args)...); | 143 | 326 | } |
_Z5AllocIN5mylib5CFileEJRP8_IO_FILEEEPT_DpOT0_ Line | Count | Source | 108 | 7 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 7 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 7 | "Expected no padding"); | 121 | | | 122 | 7 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 7 | #if MARK_SWEEP | 126 | 7 | int obj_id; | 127 | 7 | int pool_id; | 128 | 7 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 7 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 7 | #if MARK_SWEEP | 134 | 7 | header->obj_id = obj_id; | 135 | 7 | #ifndef NO_POOL_ALLOC | 136 | 7 | header->pool_id = pool_id; | 137 | 7 | #endif | 138 | 7 | #endif | 139 | 7 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 7 | memset(obj, 0, sizeof(T)); | 142 | 7 | return new (obj) T(std::forward<Args>(args)...); | 143 | 7 | } |
Unexecuted instantiation: _Z5AllocI7IOErrorJRiEEPT_DpOT0_ _Z5AllocI4ListIP6BigStrEJEEPT_DpOT0_ Line | Count | Source | 108 | 46 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 46 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 46 | "Expected no padding"); | 121 | | | 122 | 46 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 46 | #if MARK_SWEEP | 126 | 46 | int obj_id; | 127 | 46 | int pool_id; | 128 | 46 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 46 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 46 | #if MARK_SWEEP | 134 | 46 | header->obj_id = obj_id; | 135 | 46 | #ifndef NO_POOL_ALLOC | 136 | 46 | header->pool_id = pool_id; | 137 | 46 | #endif | 138 | 46 | #endif | 139 | 46 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 46 | memset(obj, 0, sizeof(T)); | 142 | 46 | return new (obj) T(std::forward<Args>(args)...); | 143 | 46 | } |
_Z5AllocI4DictIiP6BigStrEJSt16initializer_listIiES4_IS2_EEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
Unexecuted instantiation: _Z5AllocI8KeyErrorJEEPT_DpOT0_ _Z5AllocI4DictIP6BigStriEJSt16initializer_listIS2_ES4_IiEEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI4DictIiP6BigStrEJEEPT_DpOT0_ Line | Count | Source | 108 | 4 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 4 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 4 | "Expected no padding"); | 121 | | | 122 | 4 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 4 | #if MARK_SWEEP | 126 | 4 | int obj_id; | 127 | 4 | int pool_id; | 128 | 4 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 4 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 4 | #if MARK_SWEEP | 134 | 4 | header->obj_id = obj_id; | 135 | 4 | #ifndef NO_POOL_ALLOC | 136 | 4 | header->pool_id = pool_id; | 137 | 4 | #endif | 138 | 4 | #endif | 139 | 4 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 4 | memset(obj, 0, sizeof(T)); | 142 | 4 | return new (obj) T(std::forward<Args>(args)...); | 143 | 4 | } |
_Z5AllocI4DictIP6BigStriEJEEPT_DpOT0_ Line | Count | Source | 108 | 8 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 8 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 8 | "Expected no padding"); | 121 | | | 122 | 8 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 8 | #if MARK_SWEEP | 126 | 8 | int obj_id; | 127 | 8 | int pool_id; | 128 | 8 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 8 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 8 | #if MARK_SWEEP | 134 | 8 | header->obj_id = obj_id; | 135 | 8 | #ifndef NO_POOL_ALLOC | 136 | 8 | header->pool_id = pool_id; | 137 | 8 | #endif | 138 | 8 | #endif | 139 | 8 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 8 | memset(obj, 0, sizeof(T)); | 142 | 8 | return new (obj) T(std::forward<Args>(args)...); | 143 | 8 | } |
_Z5AllocI4DictIP6BigStrS2_EJEEPT_DpOT0_ Line | Count | Source | 108 | 3 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 3 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 3 | "Expected no padding"); | 121 | | | 122 | 3 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 3 | #if MARK_SWEEP | 126 | 3 | int obj_id; | 127 | 3 | int pool_id; | 128 | 3 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 3 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 3 | #if MARK_SWEEP | 134 | 3 | header->obj_id = obj_id; | 135 | 3 | #ifndef NO_POOL_ALLOC | 136 | 3 | header->pool_id = pool_id; | 137 | 3 | #endif | 138 | 3 | #endif | 139 | 3 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 3 | memset(obj, 0, sizeof(T)); | 142 | 3 | return new (obj) T(std::forward<Args>(args)...); | 143 | 3 | } |
_Z5AllocI4DictIiiEJEEPT_DpOT0_ Line | Count | Source | 108 | 8 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 8 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 8 | "Expected no padding"); | 121 | | | 122 | 8 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 8 | #if MARK_SWEEP | 126 | 8 | int obj_id; | 127 | 8 | int pool_id; | 128 | 8 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 8 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 8 | #if MARK_SWEEP | 134 | 8 | header->obj_id = obj_id; | 135 | 8 | #ifndef NO_POOL_ALLOC | 136 | 8 | header->pool_id = pool_id; | 137 | 8 | #endif | 138 | 8 | #endif | 139 | 8 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 8 | memset(obj, 0, sizeof(T)); | 142 | 8 | return new (obj) T(std::forward<Args>(args)...); | 143 | 8 | } |
_Z5AllocI4ListIP6Tuple2IiiEEJEEPT_DpOT0_ Line | Count | Source | 108 | 2 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 2 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 2 | "Expected no padding"); | 121 | | | 122 | 2 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 2 | #if MARK_SWEEP | 126 | 2 | int obj_id; | 127 | 2 | int pool_id; | 128 | 2 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 2 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 2 | #if MARK_SWEEP | 134 | 2 | header->obj_id = obj_id; | 135 | 2 | #ifndef NO_POOL_ALLOC | 136 | 2 | header->pool_id = pool_id; | 137 | 2 | #endif | 138 | 2 | #endif | 139 | 2 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 2 | memset(obj, 0, sizeof(T)); | 142 | 2 | return new (obj) T(std::forward<Args>(args)...); | 143 | 2 | } |
_Z5AllocI6Tuple2IiiEJiiEEPT_DpOT0_ Line | Count | Source | 108 | 8 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 8 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 8 | "Expected no padding"); | 121 | | | 122 | 8 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 8 | #if MARK_SWEEP | 126 | 8 | int obj_id; | 127 | 8 | int pool_id; | 128 | 8 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 8 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 8 | #if MARK_SWEEP | 134 | 8 | header->obj_id = obj_id; | 135 | 8 | #ifndef NO_POOL_ALLOC | 136 | 8 | header->pool_id = pool_id; | 137 | 8 | #endif | 138 | 8 | #endif | 139 | 8 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 8 | memset(obj, 0, sizeof(T)); | 142 | 8 | return new (obj) T(std::forward<Args>(args)...); | 143 | 8 | } |
_Z5AllocI4DictIP6Tuple2IiiEiEJEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI4DictIP6Tuple2IP6BigStriEiEJEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI5PointJiiEEPT_DpOT0_ Line | Count | Source | 108 | 2 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 2 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 2 | "Expected no padding"); | 121 | | | 122 | 2 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 2 | #if MARK_SWEEP | 126 | 2 | int obj_id; | 127 | 2 | int pool_id; | 128 | 2 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 2 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 2 | #if MARK_SWEEP | 134 | 2 | header->obj_id = obj_id; | 135 | 2 | #ifndef NO_POOL_ALLOC | 136 | 2 | header->pool_id = pool_id; | 137 | 2 | #endif | 138 | 2 | #endif | 139 | 2 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 2 | memset(obj, 0, sizeof(T)); | 142 | 2 | return new (obj) T(std::forward<Args>(args)...); | 143 | 2 | } |
_Z5AllocI4LineJEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI10DerivedObjJEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI4ListIbEJEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI4ListIPiEJEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI4ListIdEJEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocIN5mylib9BufWriterEJEEPT_DpOT0_ Line | Count | Source | 108 | 4 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 4 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 4 | "Expected no padding"); | 121 | | | 122 | 4 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 4 | #if MARK_SWEEP | 126 | 4 | int obj_id; | 127 | 4 | int pool_id; | 128 | 4 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 4 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 4 | #if MARK_SWEEP | 134 | 4 | header->obj_id = obj_id; | 135 | 4 | #ifndef NO_POOL_ALLOC | 136 | 4 | header->pool_id = pool_id; | 137 | 4 | #endif | 138 | 4 | #endif | 139 | 4 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 4 | memset(obj, 0, sizeof(T)); | 142 | 4 | return new (obj) T(std::forward<Args>(args)...); | 143 | 4 | } |
_Z5AllocIN5mylib13BufLineReaderEJRP6BigStrEEPT_DpOT0_ Line | Count | Source | 108 | 3 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 3 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 3 | "Expected no padding"); | 121 | | | 122 | 3 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 3 | #if MARK_SWEEP | 126 | 3 | int obj_id; | 127 | 3 | int pool_id; | 128 | 3 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 3 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 3 | #if MARK_SWEEP | 134 | 3 | header->obj_id = obj_id; | 135 | 3 | #ifndef NO_POOL_ALLOC | 136 | 3 | header->pool_id = pool_id; | 137 | 3 | #endif | 138 | 3 | #endif | 139 | 3 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 3 | memset(obj, 0, sizeof(T)); | 142 | 3 | return new (obj) T(std::forward<Args>(args)...); | 143 | 3 | } |
_Z5AllocI6Tuple2IiP6BigStrEJiS2_EEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI6Tuple3IiP6BigStrS2_EJiS2_S2_EEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI6Tuple4IiP6BigStrS2_iEJiS2_S2_iEEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI6Tuple2IiP6BigStrEJiRS2_EEPT_DpOT0_ Line | Count | Source | 108 | 2 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 2 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 2 | "Expected no padding"); | 121 | | | 122 | 2 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 2 | #if MARK_SWEEP | 126 | 2 | int obj_id; | 127 | 2 | int pool_id; | 128 | 2 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 2 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 2 | #if MARK_SWEEP | 134 | 2 | header->obj_id = obj_id; | 135 | 2 | #ifndef NO_POOL_ALLOC | 136 | 2 | header->pool_id = pool_id; | 137 | 2 | #endif | 138 | 2 | #endif | 139 | 2 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 2 | memset(obj, 0, sizeof(T)); | 142 | 2 | return new (obj) T(std::forward<Args>(args)...); | 143 | 2 | } |
_Z5AllocI6Tuple2IiPS0_IiP6BigStrEEJiRS4_EEPT_DpOT0_ Line | Count | Source | 108 | 1 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 1 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 1 | "Expected no padding"); | 121 | | | 122 | 1 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 1 | #if MARK_SWEEP | 126 | 1 | int obj_id; | 127 | 1 | int pool_id; | 128 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 1 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 1 | #if MARK_SWEEP | 134 | 1 | header->obj_id = obj_id; | 135 | 1 | #ifndef NO_POOL_ALLOC | 136 | 1 | header->pool_id = pool_id; | 137 | 1 | #endif | 138 | 1 | #endif | 139 | 1 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 1 | memset(obj, 0, sizeof(T)); | 142 | 1 | return new (obj) T(std::forward<Args>(args)...); | 143 | 1 | } |
_Z5AllocI4NodeJEEPT_DpOT0_ Line | Count | Source | 108 | 2 | T* Alloc(Args&&... args) { | 109 | | // Alloc() allocates space for both a header and object and guarantees that | 110 | | // they're adjacent in memory (so that they're at known offsets from one | 111 | | // another). However, this means that the address that the object is | 112 | | // constructed at is offset from the address returned by the memory allocator | 113 | | // (by the size of the header), and therefore may not be sufficiently aligned. | 114 | | // Here we assert that the object will be sufficiently aligned by making the | 115 | | // equivalent assertion that zero padding would be required to align it. | 116 | | // Note: the required padding is given by the following (according to | 117 | | // https://en.wikipedia.org/wiki/Data_structure_alignment): | 118 | | // `padding = -offset & (align - 1)`. | 119 | 2 | static_assert((-sizeof(ObjHeader) & (alignof(T) - 1)) == 0, | 120 | 2 | "Expected no padding"); | 121 | | | 122 | 2 | DCHECK(gHeap.is_initialized_); | 123 | | | 124 | 0 | constexpr size_t num_bytes = sizeof(ObjHeader) + sizeof(T); | 125 | 2 | #if MARK_SWEEP | 126 | 2 | int obj_id; | 127 | 2 | int pool_id; | 128 | 2 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 129 | | #else | 130 | | void* place = gHeap.Allocate(num_bytes); | 131 | | #endif | 132 | 2 | ObjHeader* header = new (place) ObjHeader(T::obj_header()); | 133 | 2 | #if MARK_SWEEP | 134 | 2 | header->obj_id = obj_id; | 135 | 2 | #ifndef NO_POOL_ALLOC | 136 | 2 | header->pool_id = pool_id; | 137 | 2 | #endif | 138 | 2 | #endif | 139 | 2 | void* obj = header->ObjectAddress(); | 140 | | // mycpp doesn't generated constructors that initialize every field | 141 | 2 | memset(obj, 0, sizeof(T)); | 142 | 2 | return new (obj) T(std::forward<Args>(args)...); | 143 | 2 | } |
|
144 | | |
145 | | // |
146 | | // String "Constructors". We need these because of the "flexible array" |
147 | | // pattern. I don't think "new BigStr()" can do that, and placement new would |
148 | | // require mycpp to generate 2 statements everywhere. |
149 | | // |
150 | | |
151 | 2.10k | inline BigStr* NewStr(int len) { |
152 | 2.10k | if (len == 0) { // e.g. BufLineReader::readline() can use this optimization |
153 | 188 | return kEmptyString; |
154 | 188 | } |
155 | | |
156 | 1.91k | int obj_len = kStrHeaderSize + len + 1; // NUL terminator |
157 | 1.91k | const size_t num_bytes = sizeof(ObjHeader) + obj_len; |
158 | 1.91k | #if MARK_SWEEP |
159 | 1.91k | int obj_id; |
160 | 1.91k | int pool_id; |
161 | 1.91k | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); |
162 | | #else |
163 | | void* place = gHeap.Allocate(num_bytes); |
164 | | #endif |
165 | 1.91k | ObjHeader* header = new (place) ObjHeader(BigStr::obj_header()); |
166 | | |
167 | 1.91k | auto s = new (header->ObjectAddress()) BigStr(); |
168 | | |
169 | 1.91k | s->data_[len] = '\0'; // NUL terminate |
170 | 1.91k | s->len_ = len; |
171 | 1.91k | s->hash_ = 0; |
172 | 1.91k | s->is_hashed_ = 0; |
173 | | |
174 | 1.91k | #if MARK_SWEEP |
175 | 1.91k | header->obj_id = obj_id; |
176 | 1.91k | #ifndef NO_POOL_ALLOC |
177 | 1.91k | header->pool_id = pool_id; |
178 | 1.91k | #endif |
179 | 1.91k | #endif |
180 | 1.91k | return s; |
181 | 2.10k | } |
182 | | |
183 | | // Call OverAllocatedStr() when you don't know the length of the string up |
184 | | // front, e.g. with snprintf(). CALLER IS RESPONSIBLE for calling |
185 | | // s->MaybeShrink() afterward! |
186 | 28 | inline BigStr* OverAllocatedStr(int len) { |
187 | 28 | int obj_len = kStrHeaderSize + len + 1; // NUL terminator |
188 | 28 | const size_t num_bytes = sizeof(ObjHeader) + obj_len; |
189 | 28 | #if MARK_SWEEP |
190 | 28 | int obj_id; |
191 | 28 | int pool_id; |
192 | 28 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); |
193 | | #else |
194 | | void* place = gHeap.Allocate(num_bytes); |
195 | | #endif |
196 | 28 | ObjHeader* header = new (place) ObjHeader(BigStr::obj_header()); |
197 | 28 | auto s = new (header->ObjectAddress()) BigStr(); |
198 | 28 | s->hash_ = 0; |
199 | 28 | s->is_hashed_ = 0; |
200 | | |
201 | 28 | #if MARK_SWEEP |
202 | 28 | header->obj_id = obj_id; |
203 | 28 | #ifndef NO_POOL_ALLOC |
204 | 28 | header->pool_id = pool_id; |
205 | 28 | #endif |
206 | 28 | #endif |
207 | 28 | return s; |
208 | 28 | } |
209 | | |
210 | | // Copy C string into the managed heap. |
211 | 964 | inline BigStr* StrFromC(const char* data, int len) { |
212 | | // Optimization that could be taken out once we have SmallStr |
213 | 964 | if (len == 0) { |
214 | 79 | return kEmptyString; |
215 | 79 | } |
216 | 885 | BigStr* s = NewStr(len); |
217 | 885 | memcpy(s->data_, data, len); |
218 | 885 | DCHECK(s->data_[len] == '\0'); // should be true because Heap was zeroed |
219 | | |
220 | 0 | return s; |
221 | 964 | } |
222 | | |
223 | 592 | inline BigStr* StrFromC(const char* data) { |
224 | 592 | return StrFromC(data, strlen(data)); |
225 | 592 | } |
226 | | |
227 | | // Create a slab with a number of entries of a certain type. |
228 | | // Note: entries will be zero'd because we use calloc(). TODO: Consider |
229 | | // zeroing them separately. |
230 | | template <typename T> |
231 | 513 | inline Slab<T>* NewSlab(int len) { |
232 | 513 | int obj_len = len * sizeof(T); |
233 | 513 | const size_t num_bytes = sizeof(ObjHeader) + obj_len; |
234 | 513 | #if MARK_SWEEP |
235 | 513 | int obj_id; |
236 | 513 | int pool_id; |
237 | 513 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); |
238 | | #else |
239 | | void* place = gHeap.Allocate(num_bytes); |
240 | | #endif |
241 | 513 | ObjHeader* header = new (place) ObjHeader(Slab<T>::obj_header(len)); |
242 | 513 | void* obj = header->ObjectAddress(); |
243 | 513 | if (std::is_pointer<T>()) { |
244 | 76 | memset(obj, 0, obj_len); |
245 | 76 | } |
246 | 513 | auto slab = new (obj) Slab<T>(len); |
247 | 513 | #if MARK_SWEEP |
248 | 513 | header->obj_id = obj_id; |
249 | 513 | #ifndef NO_POOL_ALLOC |
250 | 513 | header->pool_id = pool_id; |
251 | 513 | #endif |
252 | 513 | #endif |
253 | 513 | return slab; |
254 | 513 | } Line | Count | Source | 231 | 435 | inline Slab<T>* NewSlab(int len) { | 232 | 435 | int obj_len = len * sizeof(T); | 233 | 435 | const size_t num_bytes = sizeof(ObjHeader) + obj_len; | 234 | 435 | #if MARK_SWEEP | 235 | 435 | int obj_id; | 236 | 435 | int pool_id; | 237 | 435 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 238 | | #else | 239 | | void* place = gHeap.Allocate(num_bytes); | 240 | | #endif | 241 | 435 | ObjHeader* header = new (place) ObjHeader(Slab<T>::obj_header(len)); | 242 | 435 | void* obj = header->ObjectAddress(); | 243 | 435 | if (std::is_pointer<T>()) { | 244 | 0 | memset(obj, 0, obj_len); | 245 | 0 | } | 246 | 435 | auto slab = new (obj) Slab<T>(len); | 247 | 435 | #if MARK_SWEEP | 248 | 435 | header->obj_id = obj_id; | 249 | 435 | #ifndef NO_POOL_ALLOC | 250 | 435 | header->pool_id = pool_id; | 251 | 435 | #endif | 252 | 435 | #endif | 253 | 435 | return slab; | 254 | 435 | } |
_Z7NewSlabIP6BigStrEP4SlabIT_Ei Line | Count | Source | 231 | 72 | inline Slab<T>* NewSlab(int len) { | 232 | 72 | int obj_len = len * sizeof(T); | 233 | 72 | const size_t num_bytes = sizeof(ObjHeader) + obj_len; | 234 | 72 | #if MARK_SWEEP | 235 | 72 | int obj_id; | 236 | 72 | int pool_id; | 237 | 72 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 238 | | #else | 239 | | void* place = gHeap.Allocate(num_bytes); | 240 | | #endif | 241 | 72 | ObjHeader* header = new (place) ObjHeader(Slab<T>::obj_header(len)); | 242 | 72 | void* obj = header->ObjectAddress(); | 243 | 72 | if (std::is_pointer<T>()) { | 244 | 72 | memset(obj, 0, obj_len); | 245 | 72 | } | 246 | 72 | auto slab = new (obj) Slab<T>(len); | 247 | 72 | #if MARK_SWEEP | 248 | 72 | header->obj_id = obj_id; | 249 | 72 | #ifndef NO_POOL_ALLOC | 250 | 72 | header->pool_id = pool_id; | 251 | 72 | #endif | 252 | 72 | #endif | 253 | 72 | return slab; | 254 | 72 | } |
_Z7NewSlabIP6Tuple2IiiEEP4SlabIT_Ei Line | Count | Source | 231 | 3 | inline Slab<T>* NewSlab(int len) { | 232 | 3 | int obj_len = len * sizeof(T); | 233 | 3 | const size_t num_bytes = sizeof(ObjHeader) + obj_len; | 234 | 3 | #if MARK_SWEEP | 235 | 3 | int obj_id; | 236 | 3 | int pool_id; | 237 | 3 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 238 | | #else | 239 | | void* place = gHeap.Allocate(num_bytes); | 240 | | #endif | 241 | 3 | ObjHeader* header = new (place) ObjHeader(Slab<T>::obj_header(len)); | 242 | 3 | void* obj = header->ObjectAddress(); | 243 | 3 | if (std::is_pointer<T>()) { | 244 | 3 | memset(obj, 0, obj_len); | 245 | 3 | } | 246 | 3 | auto slab = new (obj) Slab<T>(len); | 247 | 3 | #if MARK_SWEEP | 248 | 3 | header->obj_id = obj_id; | 249 | 3 | #ifndef NO_POOL_ALLOC | 250 | 3 | header->pool_id = pool_id; | 251 | 3 | #endif | 252 | 3 | #endif | 253 | 3 | return slab; | 254 | 3 | } |
_Z7NewSlabIP6Tuple2IP6BigStriEEP4SlabIT_Ei Line | Count | Source | 231 | 1 | inline Slab<T>* NewSlab(int len) { | 232 | 1 | int obj_len = len * sizeof(T); | 233 | 1 | const size_t num_bytes = sizeof(ObjHeader) + obj_len; | 234 | 1 | #if MARK_SWEEP | 235 | 1 | int obj_id; | 236 | 1 | int pool_id; | 237 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 238 | | #else | 239 | | void* place = gHeap.Allocate(num_bytes); | 240 | | #endif | 241 | 1 | ObjHeader* header = new (place) ObjHeader(Slab<T>::obj_header(len)); | 242 | 1 | void* obj = header->ObjectAddress(); | 243 | 1 | if (std::is_pointer<T>()) { | 244 | 1 | memset(obj, 0, obj_len); | 245 | 1 | } | 246 | 1 | auto slab = new (obj) Slab<T>(len); | 247 | 1 | #if MARK_SWEEP | 248 | 1 | header->obj_id = obj_id; | 249 | 1 | #ifndef NO_POOL_ALLOC | 250 | 1 | header->pool_id = pool_id; | 251 | 1 | #endif | 252 | 1 | #endif | 253 | 1 | return slab; | 254 | 1 | } |
Line | Count | Source | 231 | 1 | inline Slab<T>* NewSlab(int len) { | 232 | 1 | int obj_len = len * sizeof(T); | 233 | 1 | const size_t num_bytes = sizeof(ObjHeader) + obj_len; | 234 | 1 | #if MARK_SWEEP | 235 | 1 | int obj_id; | 236 | 1 | int pool_id; | 237 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 238 | | #else | 239 | | void* place = gHeap.Allocate(num_bytes); | 240 | | #endif | 241 | 1 | ObjHeader* header = new (place) ObjHeader(Slab<T>::obj_header(len)); | 242 | 1 | void* obj = header->ObjectAddress(); | 243 | 1 | if (std::is_pointer<T>()) { | 244 | 0 | memset(obj, 0, obj_len); | 245 | 0 | } | 246 | 1 | auto slab = new (obj) Slab<T>(len); | 247 | 1 | #if MARK_SWEEP | 248 | 1 | header->obj_id = obj_id; | 249 | 1 | #ifndef NO_POOL_ALLOC | 250 | 1 | header->pool_id = pool_id; | 251 | 1 | #endif | 252 | 1 | #endif | 253 | 1 | return slab; | 254 | 1 | } |
Line | Count | Source | 231 | 1 | inline Slab<T>* NewSlab(int len) { | 232 | 1 | int obj_len = len * sizeof(T); | 233 | 1 | const size_t num_bytes = sizeof(ObjHeader) + obj_len; | 234 | 1 | #if MARK_SWEEP | 235 | 1 | int obj_id; | 236 | 1 | int pool_id; | 237 | 1 | void* place = gHeap.Allocate(num_bytes, &obj_id, &pool_id); | 238 | | #else | 239 | | void* place = gHeap.Allocate(num_bytes); | 240 | | #endif | 241 | 1 | ObjHeader* header = new (place) ObjHeader(Slab<T>::obj_header(len)); | 242 | 1 | void* obj = header->ObjectAddress(); | 243 | 1 | if (std::is_pointer<T>()) { | 244 | 0 | memset(obj, 0, obj_len); | 245 | 0 | } | 246 | 1 | auto slab = new (obj) Slab<T>(len); | 247 | 1 | #if MARK_SWEEP | 248 | 1 | header->obj_id = obj_id; | 249 | 1 | #ifndef NO_POOL_ALLOC | 250 | 1 | header->pool_id = pool_id; | 251 | 1 | #endif | 252 | 1 | #endif | 253 | 1 | return slab; | 254 | 1 | } |
|
255 | | |
256 | | #endif // MYCPP_GC_ALLOC_H |