@@ -27,32 +27,21 @@ class arena {
27
27
void *kore_arena_alloc (size_t requested);
28
28
29
29
// Returns the address of the first byte that belongs in the given arena.
30
- // Returns 0 if nothing has been allocated ever in that arena.
31
- char *arena_start_ptr () const {
32
- return current_addr_ptr ? current_addr_ptr + sizeof (memory_block_header)
33
- : nullptr ;
34
- }
30
+ // Returns nullptr if nothing has been allocated ever in that arena.
31
+ char *arena_start_ptr () const { return current_addr_ptr; }
35
32
36
33
// Returns a pointer to a location holding the address of last allocated
37
34
// byte in the given arena plus 1.
38
- // This address is 0 if nothing has been allocated ever in that arena.
35
+ // This address is nullptr if nothing has been allocated ever in that arena.
39
36
char **arena_end_ptr () { return &allocation_ptr; }
40
37
41
- // return the total number of allocatable bytes currently in the arena in its
42
- // active semispace.
43
- size_t arena_size () const {
44
- update_num_blocks ();
45
- return BLOCK_SIZE * std::max (num_blocks, num_collection_blocks);
46
- }
47
-
48
38
// Clears the current allocation space by setting its start back to its first
49
39
// block. It is used during garbage collection to effectively collect all of the
50
- // arena.
40
+ // arena. Resets the tripwire.
51
41
void arena_clear ();
52
42
53
- // Resizes the last allocation as long as the resize does not require a new
54
- // block allocation.
55
- // Returns the address of the byte following the last newlly allocated byte.
43
+ // Resizes the last allocation.
44
+ // Returns the address of the byte following the last newly allocated byte.
56
45
void *arena_resize_last_alloc (ssize_t increase) {
57
46
return (allocation_ptr += increase);
58
47
}
@@ -71,10 +60,8 @@ class arena {
71
60
void arena_swap_and_clear ();
72
61
73
62
// Given two pointers to objects allocated in the same arena, return the number
74
- // of bytes they are separated by within the virtual block of memory represented
75
- // by the blocks of that arena. This difference will include blocks containing
76
- // sentinel bytes. Undefined behavior will result if the pointers belong to
77
- // different arenas.
63
+ // of bytes they are apart. Undefined behavior will result if the pointers
64
+ // don't belong to the same arena
78
65
static ssize_t ptr_diff (char *ptr1, char *ptr2) { return ptr1 - ptr2; }
79
66
80
67
// Given a starting pointer to an address allocated in an arena and a size in
@@ -84,11 +71,11 @@ class arena {
84
71
// 1st argument: the starting pointer
85
72
// 2nd argument: the size in bytes to add to the starting pointer
86
73
// 3rd argument: the address of last allocated byte in the arena plus 1
87
- // Return value: the address allocated in the arena after size bytes from the
88
- // starting pointer, or 0 if this is equal to the 3rd argument.
74
+ // Return value: starting pointer + size unless this points to unallocated space
75
+ // in which case nullptr is returned
89
76
static char *move_ptr (char *ptr, size_t size, char const *arena_end_ptr) {
90
77
char *next_ptr = ptr + size;
91
- return (next_ptr == arena_end_ptr) ? 0 : next_ptr;
78
+ return (next_ptr == arena_end_ptr) ? nullptr : next_ptr;
92
79
}
93
80
94
81
// Returns the ID of the semispace where the given address was allocated.
@@ -97,15 +84,6 @@ class arena {
97
84
static char get_arena_semispace_id_of_object (void *ptr);
98
85
99
86
private:
100
- union memory_block_header {
101
- //
102
- // Currently the header just holds the semispace id. But we need it to be a
103
- // multiple of sizeof(char*) for alignment purposes so we add a dummy char*.
104
- //
105
- char semispace;
106
- char *alignment_dummy;
107
- };
108
-
109
87
//
110
88
// We update the number of 1MB blocks actually written to, only when we need this value,
111
89
// or before a garbage collection rather than trying to determine when we write to a fresh block.
@@ -121,13 +99,6 @@ class arena {
121
99
}
122
100
123
101
void initialize_semispace ();
124
-
125
- static memory_block_header *mem_block_header (void *ptr) {
126
- uintptr_t address = reinterpret_cast <uintptr_t >(ptr);
127
- return reinterpret_cast <arena::memory_block_header *>(
128
- (address - 1 ) & ~(HYPERBLOCK_SIZE - 1 ));
129
- }
130
-
131
102
//
132
103
// Current semispace where allocations are being made.
133
104
//
@@ -146,6 +117,19 @@ class arena {
146
117
= 0 ; // notional number of BLOCK_SIZE blocks in collection semispace
147
118
};
148
119
120
+ inline char arena::get_arena_semispace_id_of_object (void *ptr) {
121
+ //
122
+ // We don't have to deal with the "1 past the end of block" case because
123
+ // a valid pointer will always point into our hyperblock - we will never return
124
+ // an allocation anywhere near the end of our hyperblock.
125
+ //
126
+ // Set the low bits to 1 to get the address of the last byte in the hyperblock.
127
+ //
128
+ uintptr_t end_address
129
+ = reinterpret_cast <uintptr_t >(ptr) | (HYPERBLOCK_SIZE - 1 );
130
+ return *reinterpret_cast <char *>(end_address);
131
+ }
132
+
149
133
// Macro to define a new arena with the given ID. Supports IDs ranging from 0 to
150
134
// 127.
151
135
#define REGISTER_ARENA (name, id ) static thread_local arena name (id)
@@ -169,8 +153,11 @@ inline void *arena::kore_arena_alloc(size_t requested) {
169
153
// collect when allowed.
170
154
//
171
155
time_for_collection = true ;
172
- tripwire = current_addr_ptr
173
- + HYPERBLOCK_SIZE; // won't trigger again until arena swap
156
+ //
157
+ // We move the tripwire to 1 past the end of our hyperblock so that we have
158
+ // a well defined comparison that will always be false until the next arena swap.
159
+ //
160
+ tripwire = current_addr_ptr + HYPERBLOCK_SIZE;
174
161
}
175
162
void *result = allocation_ptr;
176
163
allocation_ptr += requested;
0 commit comments