3
3
#include < algorithm>
4
4
#include < cassert>
5
5
#include < cstdlib>
6
+ #include < new>
6
7
#include < stdint.h>
7
8
8
9
#include " rust_internal.h"
18
19
#define DPRINT (fmt,...)
19
20
20
21
// const size_t DEFAULT_CHUNK_SIZE = 4096;
21
- const size_t DEFAULT_CHUNK_SIZE = 300000 ;
22
+ const size_t DEFAULT_CHUNK_SIZE = 500000 ;
22
23
const size_t DEFAULT_ALIGNMENT = 16 ;
23
24
25
+ // A single type-tagged allocation in a chunk.
26
+ struct rust_obstack_alloc {
27
+ size_t len;
28
+ const type_desc *tydesc;
29
+ uint8_t data[];
30
+
31
+ rust_obstack_alloc (size_t in_len, const type_desc *in_tydesc)
32
+ : len(in_len), tydesc(in_tydesc) {}
33
+ };
34
+
35
+ // A contiguous set of allocations.
24
36
struct rust_obstack_chunk {
25
37
rust_obstack_chunk *prev;
26
38
size_t size;
@@ -31,22 +43,24 @@ struct rust_obstack_chunk {
31
43
rust_obstack_chunk (rust_obstack_chunk *in_prev, size_t in_size)
32
44
: prev(in_prev), size(in_size), alen(0 ) {}
33
45
34
- void *alloc (size_t len);
46
+ void *alloc (size_t len, type_desc *tydesc );
35
47
bool free (void *ptr);
48
+ void *mark ();
36
49
};
37
50
38
51
void *
39
- rust_obstack_chunk::alloc (size_t len) {
52
+ rust_obstack_chunk::alloc (size_t len, type_desc *tydesc ) {
40
53
alen = align_to (alen, DEFAULT_ALIGNMENT);
41
54
42
- if (len > size - alen) {
55
+ if (sizeof (rust_obstack_alloc) + len > size - alen) {
43
56
DPRINT (" Not enough space, len=%lu!\n " , len);
44
57
assert (0 );
45
58
return NULL ; // Not enough space.
46
59
}
47
- void *result = data + alen;
48
- alen += len;
49
- return result;
60
+
61
+ rust_obstack_alloc *a = new (data + alen) rust_obstack_alloc (len, tydesc);
62
+ alen += sizeof (*a) + len;
63
+ return &a->data ;
50
64
}
51
65
52
66
bool
@@ -59,14 +73,20 @@ rust_obstack_chunk::free(void *ptr) {
59
73
return true ;
60
74
}
61
75
76
+ void *
77
+ rust_obstack_chunk::mark () {
78
+ return data + alen;
79
+ }
80
+
62
81
// Allocates the given number of bytes in a new chunk.
63
82
void *
64
- rust_obstack::alloc_new (size_t len) {
65
- size_t chunk_size = std::max (len, DEFAULT_CHUNK_SIZE);
83
+ rust_obstack::alloc_new (size_t len, type_desc *tydesc) {
84
+ size_t chunk_size = std::max (sizeof (rust_obstack_alloc) + len,
85
+ DEFAULT_CHUNK_SIZE);
66
86
void *ptr = task->malloc (sizeof (chunk) + chunk_size, " obstack" );
67
87
DPRINT (" making new chunk at %p, len %lu\n " , ptr, chunk_size);
68
88
chunk = new (ptr) rust_obstack_chunk (chunk, chunk_size);
69
- return chunk->alloc (len);
89
+ return chunk->alloc (len, tydesc );
70
90
}
71
91
72
92
rust_obstack::~rust_obstack () {
@@ -78,14 +98,14 @@ rust_obstack::~rust_obstack() {
78
98
}
79
99
80
100
void *
81
- rust_obstack::alloc (size_t len) {
101
+ rust_obstack::alloc (size_t len, type_desc *tydesc ) {
82
102
if (!chunk)
83
- return alloc_new (len);
103
+ return alloc_new (len, tydesc );
84
104
85
105
DPRINT (" alloc sz %u" , (uint32_t )len);
86
106
87
- void *ptr = chunk->alloc (len);
88
- ptr = ptr ? ptr : alloc_new (len);
107
+ void *ptr = chunk->alloc (len, tydesc );
108
+ ptr = ptr ? ptr : alloc_new (len, tydesc );
89
109
90
110
return ptr;
91
111
}
@@ -107,3 +127,8 @@ rust_obstack::free(void *ptr) {
107
127
}
108
128
}
109
129
130
+ void *
131
+ rust_obstack::mark () {
132
+ return chunk ? chunk->mark () : NULL ;
133
+ }
134
+
0 commit comments