Skip to content

Commit e24d1dd

Browse files
committed
rewrite so that memory allocations have 0 overhead by default
1 parent 75b98a9 commit e24d1dd

File tree

2 files changed

+59
-25
lines changed

2 files changed

+59
-25
lines changed

src/rt/memory_region.cpp

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
#include "rust_internal.h"
22
#include "memory_region.h"
33

4-
// NB: please do not commit code with this uncommented. It's
5-
// hugely expensive and should only be used as a last resort.
6-
//
7-
// #define TRACK_ALLOCATIONS
8-
9-
#define PTR_SIZE (sizeof(void*))
10-
#define ALIGN_PTR(x) (((x)+PTR_SIZE-1)/PTR_SIZE*PTR_SIZE)
11-
#define HEADER_SIZE ALIGN_PTR(sizeof(alloc_header))
12-
#define MAGIC 0xbadc0ffe
4+
#if RUSTRT_TRACK_ALLOCATIONS >= 1
5+
# define PTR_SIZE (sizeof(void*))
6+
# define ALIGN_PTR(x) (((x)+PTR_SIZE-1)/PTR_SIZE*PTR_SIZE)
7+
# define HEADER_SIZE ALIGN_PTR(sizeof(alloc_header))
8+
# define MAGIC 0xbadc0ffe
9+
#else
10+
# define HEADER_SIZE 0
11+
#endif
1312

1413
memory_region::alloc_header *memory_region::get_header(void *mem) {
1514
return (alloc_header *)((char *)mem - HEADER_SIZE);
1615
}
1716

1817
void *memory_region::get_data(alloc_header *ptr) {
19-
assert(ptr->magic == MAGIC);
2018
return (void*)((char *)ptr + HEADER_SIZE);
2119
}
2220

@@ -46,7 +44,11 @@ void memory_region::free(void *mem) {
4644
// printf("free: ptr 0x%" PRIxPTR" region=%p\n", (uintptr_t) mem, this);
4745
if (!mem) { return; }
4846
alloc_header *alloc = get_header(mem);
47+
48+
# if RUSTRT_TRACK_ALLOCATIONS >= 1
4949
assert(alloc->magic == MAGIC);
50+
# endif
51+
5052
if (_live_allocations < 1) {
5153
_srv->fatal("live_allocs < 1", __FILE__, __LINE__, "");
5254
}
@@ -56,18 +58,22 @@ void memory_region::free(void *mem) {
5658
}
5759

5860
void *
59-
memory_region::realloc(void *mem, size_t size) {
61+
memory_region::realloc(void *mem, size_t orig_size) {
6062
if (_synchronized) { _lock.lock(); }
6163
if (!mem) {
6264
add_alloc();
6365
}
64-
size_t old_size = size;
65-
size += HEADER_SIZE;
66+
6667
alloc_header *alloc = get_header(mem);
67-
assert(alloc->magic == MAGIC);
68-
alloc->size = old_size;
68+
size_t size = orig_size + HEADER_SIZE;
6969
alloc_header *newMem = (alloc_header *)_srv->realloc(alloc, size);
70-
#ifdef TRACK_ALLOCATIONS
70+
71+
# if RUSTRT_TRACK_ALLOCATIONS >= 1
72+
assert(alloc->magic == MAGIC);
73+
newMem->size = orig_size;
74+
# endif
75+
76+
# if RUSTRT_TRACK_ALLOCATIONS >= 2
7177
if (_allocation_list[newMem->index] != alloc) {
7278
printf("at index %d, found %p, expected %p\n",
7379
alloc->index, _allocation_list[alloc->index], alloc);
@@ -80,7 +86,8 @@ memory_region::realloc(void *mem, size_t size) {
8086
// printf("realloc: stored %p at index %d, replacing %p\n",
8187
// newMem, index, mem);
8288
}
83-
#endif
89+
# endif
90+
8491
if (_synchronized) { _lock.unlock(); }
8592
return get_data(newMem);
8693
}
@@ -90,10 +97,13 @@ memory_region::malloc(size_t size, const char *tag, bool zero) {
9097
size_t old_size = size;
9198
size += HEADER_SIZE;
9299
alloc_header *mem = (alloc_header *)_srv->malloc(size);
100+
101+
# if RUSTRT_TRACK_ALLOCATIONS >= 1
93102
mem->magic = MAGIC;
94103
mem->tag = tag;
95104
mem->index = -1;
96105
mem->size = old_size;
106+
# endif
97107

98108
void *data = get_data(mem);
99109
claim_alloc(data);
@@ -122,7 +132,8 @@ memory_region::~memory_region() {
122132
"leaked memory in rust main loop (%d objects)",
123133
_live_allocations);
124134
}
125-
#ifdef TRACK_ALLOCATIONS
135+
136+
# if RUSTRT_TRACK_ALLOCATIONS >= 2
126137
if (_detailed_leaks) {
127138
int leak_count = 0;
128139
for (size_t i = 0; i < _allocation_list.size(); i++) {
@@ -136,7 +147,8 @@ memory_region::~memory_region() {
136147
}
137148
assert(leak_count == _live_allocations);
138149
}
139-
#endif
150+
# endif
151+
140152
if (_live_allocations > 0) {
141153
_srv->fatal(msg, __FILE__, __LINE__,
142154
"%d objects", _live_allocations);
@@ -146,10 +158,12 @@ memory_region::~memory_region() {
146158

147159
void
148160
memory_region::release_alloc(void *mem) {
161+
# if RUSTRT_TRACK_ALLOCATIONS >= 1
149162
alloc_header *alloc = get_header(mem);
150163
assert(alloc->magic == MAGIC);
164+
# endif
151165

152-
#ifdef TRACK_ALLOCATIONS
166+
# if RUSTRT_TRACK_ALLOCATIONS >= 2
153167
if (_synchronized) { _lock.lock(); }
154168
if (_allocation_list[alloc->index] != alloc) {
155169
printf("free: ptr 0x%" PRIxPTR " (%s) is not in allocation_list\n",
@@ -162,19 +176,24 @@ memory_region::release_alloc(void *mem) {
162176
alloc->index = -1;
163177
}
164178
if (_synchronized) { _lock.unlock(); }
165-
#endif
179+
# endif
180+
166181
dec_alloc();
167182
}
168183

169184
void
170185
memory_region::claim_alloc(void *mem) {
186+
# if RUSTRT_TRACK_ALLOCATIONS >= 1
171187
alloc_header *alloc = get_header(mem);
172188
assert(alloc->magic == MAGIC);
173-
#ifdef TRACK_ALLOCATIONS
189+
# endif
190+
191+
# if RUSTRT_TRACK_ALLOCATIONS >= 2
174192
if (_synchronized) { _lock.lock(); }
175193
alloc->index = _allocation_list.append(alloc);
176194
if (_synchronized) { _lock.unlock(); }
177-
#endif
195+
# endif
196+
178197
add_alloc();
179198
}
180199

@@ -190,8 +209,10 @@ memory_region::maybe_poison(void *mem) {
190209
if (!poison)
191210
return;
192211

212+
# if RUSTRT_TRACK_ALLOCATIONS >= 1
193213
alloc_header *alloc = get_header(mem);
194214
memset(mem, '\xcd', alloc->size);
215+
# endif
195216
}
196217

197218
//

src/rt/memory_region.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,32 @@
1111

1212
#include "sync/lock_and_signal.h"
1313

14+
// There are three levels of debugging:
15+
//
16+
// 0 --- no headers, no debugging support
17+
// 1 --- support poison, but do not track allocations
18+
// 2 --- track allocations in deatil
19+
//
20+
// NB: please do not commit code with level 2. It's
21+
// hugely expensive and should only be used as a last resort.
22+
#define RUSTRT_TRACK_ALLOCATIONS 0
23+
1424
class rust_srv;
1525

1626
class memory_region {
1727
private:
1828
struct alloc_header {
29+
# if RUSTRT_TRACK_ALLOCATIONS > 0
1930
uint32_t magic;
2031
int index;
2132
const char *tag;
2233
uint32_t size;
34+
# endif
2335
};
2436

25-
alloc_header *get_header(void *mem);
26-
void *get_data(alloc_header *);
37+
inline alloc_header *get_header(void *mem);
38+
inline void *get_data(alloc_header *);
39+
2740

2841
rust_srv *_srv;
2942
memory_region *_parent;

0 commit comments

Comments
 (0)