Skip to content

Commit 38cc6e4

Browse files
committed
Merge remote-tracking branch 'origin/develop'
2 parents e7d5b04 + 3a0b23d commit 38cc6e4

File tree

5 files changed

+192
-233
lines changed

5 files changed

+192
-233
lines changed

include/runtime/arena.h

Lines changed: 96 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,100 @@ extern "C" {
1010

1111
// An arena can be used to allocate objects that can then be deallocated all at
1212
// once.
13-
struct arena {
14-
char *first_block;
15-
char *block;
16-
char *block_start;
17-
char *block_end;
18-
char *first_collection_block;
19-
size_t num_blocks;
20-
size_t num_collection_blocks;
21-
char allocation_semispace_id;
22-
};
23-
24-
using memory_block_header = struct {
25-
char *next_block;
26-
char *next_superblock;
27-
char semispace;
13+
class arena {
14+
public:
15+
arena(char id)
16+
: allocation_semispace_id(id) { }
17+
18+
// Allocates the requested number of bytes as a contiguous region and returns a
19+
// pointer to the first allocated byte.
20+
// If called with requested size greater than the maximun single allocation
21+
// size, the space is allocated in a general (not garbage collected pool).
22+
void *kore_arena_alloc(size_t requested);
23+
24+
// Returns the address of the first byte that belongs in the given arena.
25+
// Returns 0 if nothing has been allocated ever in that arena.
26+
char *arena_start_ptr() const;
27+
28+
// Returns a pointer to a location holding the address of last allocated
29+
// byte in the given arena plus 1.
30+
// This address is 0 if nothing has been allocated ever in that arena.
31+
char **arena_end_ptr();
32+
33+
// return the total number of allocatable bytes currently in the arena in its
34+
// active semispace.
35+
size_t arena_size() const;
36+
37+
// Clears the current allocation space by setting its start back to its first
38+
// block. It is used during garbage collection to effectively collect all of the
39+
// arena.
40+
void arena_clear();
41+
42+
// Resizes the last allocation as long as the resize does not require a new
43+
// block allocation.
44+
// Returns the address of the byte following the last newlly allocated byte when
45+
// the resize succeeds, returns 0 otherwise.
46+
void *arena_resize_last_alloc(ssize_t increase);
47+
48+
// Returns the given arena's current collection semispace ID.
49+
// Each arena has 2 semispace IDs one equal to the arena ID and the other equal
50+
// to the 1's complement of the arena ID. At any time one of these semispaces
51+
// is used for allocation and the other is used for collection.
52+
char get_arena_collection_semispace_id() const;
53+
54+
// Exchanges the current allocation and collection semispaces and clears the new
55+
// current allocation semispace by setting its start back to its first block.
56+
// It is used before garbage collection.
57+
void arena_swap_and_clear();
58+
59+
// Given two pointers to objects allocated in the same arena, return the number
60+
// of bytes they are separated by within the virtual block of memory represented
61+
// by the blocks of that arena. This difference will include blocks containing
62+
// sentinel bytes. Undefined behavior will result if the pointers belong to
63+
// different arenas.
64+
static ssize_t ptr_diff(char *ptr1, char *ptr2);
65+
66+
// Given a starting pointer to an address allocated in an arena and a size in
67+
// bytes, this function returns a pointer to an address allocated in the
68+
// same arena after size bytes from the starting pointer.
69+
//
70+
// 1st argument: the starting pointer
71+
// 2nd argument: the size in bytes to add to the starting pointer
72+
// 3rd argument: the address of last allocated byte in the arena plus 1
73+
// Return value: the address allocated in the arena after size bytes from the
74+
// starting pointer, or 0 if this is equal to the 3rd argument.
75+
static char *move_ptr(char *ptr, size_t size, char const *arena_end_ptr);
76+
77+
// Returns the ID of the semispace where the given address was allocated.
78+
// The behavior is undefined if called with an address that has not been
79+
// allocated within an arena.
80+
static char get_arena_semispace_id_of_object(void *ptr);
81+
82+
private:
83+
struct memory_block_header {
84+
char *next_block;
85+
char semispace;
86+
};
87+
88+
void fresh_block();
89+
static memory_block_header *mem_block_header(void *ptr);
90+
91+
// helper function for `kore_arena_alloc`. Do not call directly.
92+
void *do_alloc_slow(size_t requested);
93+
94+
char *first_block; // beginning of first block
95+
char *block; // where allocations are being made in current block
96+
char *block_start; // start of current block
97+
char *block_end; // 1 past end of current block
98+
char *first_collection_block; // beginning of other semispace
99+
size_t num_blocks; // number of blocks in current semispace
100+
size_t num_collection_blocks; // number of blocks in other semispace
101+
char allocation_semispace_id; // id of current semispace
28102
};
29103

30104
// Macro to define a new arena with the given ID. Supports IDs ranging from 0 to
31105
// 127.
32-
#define REGISTER_ARENA(name, id) \
33-
static thread_local struct arena name = {.allocation_semispace_id = (id)}
106+
#define REGISTER_ARENA(name, id) static thread_local arena name(id)
34107

35108
#define MEM_BLOCK_START(ptr) \
36109
((char *)(((uintptr_t)(ptr)-1) & ~(BLOCK_SIZE - 1)))
@@ -46,92 +119,17 @@ extern thread_local bool time_for_collection;
46119

47120
size_t get_gc_threshold();
48121

49-
// Resets the given arena.
50-
void arena_reset(struct arena *);
51-
52-
// Returns the given arena's current allocation semispace ID.
53-
// Each arena has 2 semispace IDs one equal to the arena ID and the other equal
54-
// to the 1's complement of the arena ID. At any time one of these semispaces
55-
// is used for allocation and the other is used for collection.
56-
char get_arena_allocation_semispace_id(const struct arena *);
57-
58-
// Returns the given arena's current collection semispace ID.
59-
// See above for details.
60-
char get_arena_collection_semispace_id(const struct arena *);
61-
62-
// Returns the ID of the semispace where the given address was allocated.
63-
// The behavior is undefined if called with an address that has not been
64-
// allocated within an arena.
65-
char get_arena_semispace_id_of_object(void *);
66-
67-
// helper function for `kore_arena_alloc`. Do not call directly.
68-
void *do_alloc_slow(size_t, struct arena *);
69-
70-
// Allocates the requested number of bytes as a contiguous region and returns a
71-
// pointer to the first allocated byte.
72-
// If called with requested size greater than the maximun single allocation
73-
// size, the space is allocated in a general (not garbage collected pool).
74-
inline void *kore_arena_alloc(struct arena *arena, size_t requested) {
75-
if (arena->block + requested > arena->block_end) {
76-
return do_alloc_slow(requested, arena);
122+
inline void *arena::kore_arena_alloc(size_t requested) {
123+
if (block + requested > block_end) {
124+
return do_alloc_slow(requested);
77125
}
78-
void *result = arena->block;
79-
arena->block += requested;
126+
void *result = block;
127+
block += requested;
80128
MEM_LOG(
81129
"Allocation at %p (size %zd), next alloc at %p (if it fits)\n", result,
82-
requested, arena->block);
130+
requested, block);
83131
return result;
84132
}
85-
86-
// Resizes the last allocation as long as the resize does not require a new
87-
// block allocation.
88-
// Returns the address of the byte following the last newlly allocated byte when
89-
// the resize succeeds, returns 0 otherwise.
90-
void *arena_resize_last_alloc(struct arena *, ssize_t);
91-
92-
// Exchanges the current allocation and collection semispaces and clears the new
93-
// current allocation semispace by setting its start back to its first block.
94-
// It is used before garbage collection.
95-
void arena_swap_and_clear(struct arena *);
96-
97-
// Clears the current allocation space by setting its start back to its first
98-
// block. It is used during garbage collection to effectively collect all of the
99-
// arena.
100-
void arena_clear(struct arena *);
101-
102-
// Returns the address of the first byte that belongs in the given arena.
103-
// Returns 0 if nothing has been allocated ever in that arena.
104-
char *arena_start_ptr(const struct arena *);
105-
106-
// Returns a pointer to a location holding the address of last allocated
107-
// byte in the given arena plus 1.
108-
// This address is 0 if nothing has been allocated ever in that arena.
109-
char **arena_end_ptr(struct arena *);
110-
111-
// Given a starting pointer to an address allocated in an arena and a size in
112-
// bytes, this function returns a pointer to an address allocated in the
113-
// same arena after size bytes from the starting pointer.
114-
//
115-
// 1st argument: the starting pointer
116-
// 2nd argument: the size in bytes to add to the starting pointer
117-
// 3rd argument: the address of last allocated byte in the arena plus 1
118-
// Return value: the address allocated in the arena after size bytes from the
119-
// starting pointer, or 0 if this is equal to the 3rd argument.
120-
char *move_ptr(char *, size_t, char const *);
121-
122-
// Given two pointers to objects allocated in the same arena, return the number
123-
// of bytes they are separated by within the virtual block of memory represented
124-
// by the blocks of that arena. This difference will include blocks containing
125-
// sentinel bytes. Undefined behavior will result if the pointers belong to
126-
// different arenas.
127-
ssize_t ptr_diff(char *, char *);
128-
129-
// return the total number of allocatable bytes currently in the arena in its
130-
// active semispace.
131-
size_t arena_size(const struct arena *);
132-
133-
// Deallocates all the memory allocated for registered arenas.
134-
void free_all_memory(void);
135133
}
136134

137135
#endif // ARENA_H

0 commit comments

Comments
 (0)