mycpp

Coverage Report

Created: 2024-06-09 04:56

/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
}
_Z7NewSlabIiEP4SlabIT_Ei
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
}
_Z7NewSlabIbEP4SlabIT_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
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
}
_Z7NewSlabIdEP4SlabIT_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
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