From fee51980b141f59066ac701489c4f8c46901285f Mon Sep 17 00:00:00 2001 From: Steven Eker Date: Wed, 4 Dec 2024 01:04:03 +0100 Subject: [PATCH 1/5] deleted dead code youngspace_size() and arena_size() --- include/runtime/alloc.h | 2 +- include/runtime/arena.h | 7 ------- runtime/lto/alloc.cpp | 4 ---- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/include/runtime/alloc.h b/include/runtime/alloc.h index d94ed0c5b..d2eeb1fc1 100644 --- a/include/runtime/alloc.h +++ b/include/runtime/alloc.h @@ -15,7 +15,7 @@ extern "C" { char youngspace_collection_id(void); char oldspace_collection_id(void); -size_t youngspace_size(void); + //size_t youngspace_size(void); // allocates exactly requested bytes into the young generation void *kore_alloc(size_t requested); diff --git a/include/runtime/arena.h b/include/runtime/arena.h index 3f71445e4..ad7aade12 100644 --- a/include/runtime/arena.h +++ b/include/runtime/arena.h @@ -38,13 +38,6 @@ class arena { // This address is 0 if nothing has been allocated ever in that arena. char **arena_end_ptr() { return &allocation_ptr; } - // return the total number of allocatable bytes currently in the arena in its - // active semispace. - size_t arena_size() const { - update_num_blocks(); - return BLOCK_SIZE * std::max(num_blocks, num_collection_blocks); - } - // Clears the current allocation space by setting its start back to its first // block. It is used during garbage collection to effectively collect all of the // arena. diff --git a/runtime/lto/alloc.cpp b/runtime/lto/alloc.cpp index 0cd79a3f8..2928ad62f 100644 --- a/runtime/lto/alloc.cpp +++ b/runtime/lto/alloc.cpp @@ -39,10 +39,6 @@ char oldspace_collection_id() { return oldspace.get_arena_collection_semispace_id(); } -size_t youngspace_size(void) { - return youngspace.arena_size(); -} - void kore_alloc_swap(bool swap_old) { youngspace.arena_swap_and_clear(); if (swap_old) { From a8581b728f7460b2d81514ef4ed6733761e35a03 Mon Sep 17 00:00:00 2001 From: Steven Eker Date: Wed, 4 Dec 2024 03:58:51 +0100 Subject: [PATCH 2/5] replaced memory_block_header and associated functionality --- include/runtime/arena.h | 42 +++++++++++++++++++---------------------- runtime/alloc/arena.cpp | 14 ++++---------- 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/include/runtime/arena.h b/include/runtime/arena.h index ad7aade12..c030f7e3c 100644 --- a/include/runtime/arena.h +++ b/include/runtime/arena.h @@ -28,10 +28,7 @@ class arena { // Returns the address of the first byte that belongs in the given arena. // Returns 0 if nothing has been allocated ever in that arena. - char *arena_start_ptr() const { - return current_addr_ptr ? current_addr_ptr + sizeof(memory_block_header) - : nullptr; - } + char *arena_start_ptr() const { return current_addr_ptr; } // Returns a pointer to a location holding the address of last allocated // byte in the given arena plus 1. @@ -40,7 +37,7 @@ class arena { // Clears the current allocation space by setting its start back to its first // block. It is used during garbage collection to effectively collect all of the - // arena. + // arena. Resets the tripwire. void arena_clear(); // Resizes the last allocation as long as the resize does not require a new @@ -90,15 +87,6 @@ class arena { static char get_arena_semispace_id_of_object(void *ptr); private: - union memory_block_header { - // - // Currently the header just holds the semispace id. But we need it to be a - // multiple of sizeof(char*) for alignment purposes so we add a dummy char*. - // - char semispace; - char *alignment_dummy; - }; - // // We update the number of 1MB blocks actually written to, only when we need this value, // or before a garbage collection rather than trying to determine when we write to a fresh block. @@ -114,13 +102,6 @@ class arena { } void initialize_semispace(); - - static memory_block_header *mem_block_header(void *ptr) { - uintptr_t address = reinterpret_cast(ptr); - return reinterpret_cast( - (address - 1) & ~(HYPERBLOCK_SIZE - 1)); - } - // // Current semispace where allocations are being made. // @@ -139,6 +120,18 @@ class arena { = 0; // notional number of BLOCK_SIZE blocks in collection semispace }; +inline char arena::get_arena_semispace_id_of_object(void *ptr) { + // + // We don't have to deal with the "1 past the end of block" case because + // a valid pointer will always point into our hyperblock - we will never return + // an allocation anywhere near the end of our hyperblock. + // + // Set the low bits to 1 to get the address of the last byte in the hyperblock. + // + uintptr_t end_address = reinterpret_cast(ptr) | (HYPERBLOCK_SIZE - 1); + return *reinterpret_cast(end_address); +} + // Macro to define a new arena with the given ID. Supports IDs ranging from 0 to // 127. #define REGISTER_ARENA(name, id) static thread_local arena name(id) @@ -162,8 +155,11 @@ inline void *arena::kore_arena_alloc(size_t requested) { // collect when allowed. // time_for_collection = true; - tripwire = current_addr_ptr - + HYPERBLOCK_SIZE; // won't trigger again until arena swap + // + // We move the tripwire to 1 past the end of our hyperblock so that we have + // a well defined comparison that will always be false until the next arena swap. + // + tripwire = current_addr_ptr + HYPERBLOCK_SIZE; } void *result = allocation_ptr; allocation_ptr += requested; diff --git a/runtime/alloc/arena.cpp b/runtime/alloc/arena.cpp index 9fbde8bf9..94fdb85af 100644 --- a/runtime/alloc/arena.cpp +++ b/runtime/alloc/arena.cpp @@ -11,11 +11,6 @@ extern size_t const VAR_BLOCK_SIZE = BLOCK_SIZE; -__attribute__((always_inline)) char -arena::get_arena_semispace_id_of_object(void *ptr) { - return mem_block_header(ptr)->semispace; -} - #ifdef __MACH__ // // thread_local disabled for Apple @@ -53,12 +48,11 @@ void arena::initialize_semispace() { current_addr_ptr = reinterpret_cast( std::align(HYPERBLOCK_SIZE, HYPERBLOCK_SIZE, addr, request)); // - // We put a memory_block_header at the beginning so we can identify the semispace a pointer belongs to - // id by masking off the low bits to access this memory_block_header. + // We put a semispace id in the last byte of the hyperblock so we can identify which semispace a pointer + // belongs to by setting the low bits to 1 to access this id. // - auto *header = reinterpret_cast(current_addr_ptr); - header->semispace = allocation_semispace_id; - allocation_ptr = current_addr_ptr + sizeof(arena::memory_block_header); + current_addr_ptr[HYPERBLOCK_SIZE - 1] = allocation_semispace_id; + allocation_ptr = current_addr_ptr; // // We set the tripwire for this space so we get trigger a garbage collection when we pass BLOCK_SIZE of memory // allocated from this space. From a8a289058c1a30985e83c3ead9f5c8fd48572d13 Mon Sep 17 00:00:00 2001 From: Steven Eker Date: Wed, 4 Dec 2024 20:29:07 +0100 Subject: [PATCH 3/5] fix formatting; clean code and comments --- include/runtime/arena.h | 24 +++++++++++------------- runtime/alloc/arena.cpp | 5 +++-- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/include/runtime/arena.h b/include/runtime/arena.h index c030f7e3c..bac3968a3 100644 --- a/include/runtime/arena.h +++ b/include/runtime/arena.h @@ -27,12 +27,12 @@ class arena { void *kore_arena_alloc(size_t requested); // Returns the address of the first byte that belongs in the given arena. - // Returns 0 if nothing has been allocated ever in that arena. + // Returns nullptr if nothing has been allocated ever in that arena. char *arena_start_ptr() const { return current_addr_ptr; } // Returns a pointer to a location holding the address of last allocated // byte in the given arena plus 1. - // This address is 0 if nothing has been allocated ever in that arena. + // This address is nullptr if nothing has been allocated ever in that arena. char **arena_end_ptr() { return &allocation_ptr; } // Clears the current allocation space by setting its start back to its first @@ -40,9 +40,8 @@ class arena { // arena. Resets the tripwire. void arena_clear(); - // Resizes the last allocation as long as the resize does not require a new - // block allocation. - // Returns the address of the byte following the last newlly allocated byte. + // Resizes the last allocation. + // Returns the address of the byte following the last newly allocated byte. void *arena_resize_last_alloc(ssize_t increase) { return (allocation_ptr += increase); } @@ -61,10 +60,8 @@ class arena { void arena_swap_and_clear(); // Given two pointers to objects allocated in the same arena, return the number - // of bytes they are separated by within the virtual block of memory represented - // by the blocks of that arena. This difference will include blocks containing - // sentinel bytes. Undefined behavior will result if the pointers belong to - // different arenas. + // of bytes they are apart. Undefined behavior will result if the pointers + // don't belong to the same arena static ssize_t ptr_diff(char *ptr1, char *ptr2) { return ptr1 - ptr2; } // Given a starting pointer to an address allocated in an arena and a size in @@ -74,11 +71,11 @@ class arena { // 1st argument: the starting pointer // 2nd argument: the size in bytes to add to the starting pointer // 3rd argument: the address of last allocated byte in the arena plus 1 - // Return value: the address allocated in the arena after size bytes from the - // starting pointer, or 0 if this is equal to the 3rd argument. + // Return value: starting pointer + size unless this points to unallocated space + // in which case nullptr is returned static char *move_ptr(char *ptr, size_t size, char const *arena_end_ptr) { char *next_ptr = ptr + size; - return (next_ptr == arena_end_ptr) ? 0 : next_ptr; + return (next_ptr == arena_end_ptr) ? nullptr : next_ptr; } // Returns the ID of the semispace where the given address was allocated. @@ -128,7 +125,8 @@ inline char arena::get_arena_semispace_id_of_object(void *ptr) { // // Set the low bits to 1 to get the address of the last byte in the hyperblock. // - uintptr_t end_address = reinterpret_cast(ptr) | (HYPERBLOCK_SIZE - 1); + uintptr_t end_address + = reinterpret_cast(ptr) | (HYPERBLOCK_SIZE - 1); return *reinterpret_cast(end_address); } diff --git a/runtime/alloc/arena.cpp b/runtime/alloc/arena.cpp index 94fdb85af..c657dada4 100644 --- a/runtime/alloc/arena.cpp +++ b/runtime/alloc/arena.cpp @@ -41,14 +41,15 @@ void arena::initialize_semispace() { } // // We allocated 2 * HYPERBLOCK_SIZE worth of address space but we're only going to use 1, aligned on a - // HYPERBLOCK_SIZE boundry. This is so we can get the start of the hyperblock by masking any address within it. + // HYPERBLOCK_SIZE boundry. This is so we can get end of the hyperblock by setting the low bits of any + // address within the space to 1. // We don't worry about unused address space either side of our aligned address space because there will be no // memory mapped to it. // current_addr_ptr = reinterpret_cast( std::align(HYPERBLOCK_SIZE, HYPERBLOCK_SIZE, addr, request)); // - // We put a semispace id in the last byte of the hyperblock so we can identify which semispace a pointer + // We put a semispace id in the last byte of the hyperblock so we can identify which semispace an address // belongs to by setting the low bits to 1 to access this id. // current_addr_ptr[HYPERBLOCK_SIZE - 1] = allocation_semispace_id; From e47b8a9dae3455bdc6fc64fa3d3b5226a6e1c87b Mon Sep 17 00:00:00 2001 From: Steven Eker Date: Wed, 4 Dec 2024 20:51:53 +0100 Subject: [PATCH 4/5] fix formatting --- include/runtime/alloc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/runtime/alloc.h b/include/runtime/alloc.h index d2eeb1fc1..4b10e4779 100644 --- a/include/runtime/alloc.h +++ b/include/runtime/alloc.h @@ -15,7 +15,7 @@ extern "C" { char youngspace_collection_id(void); char oldspace_collection_id(void); - //size_t youngspace_size(void); +//size_t youngspace_size(void); // allocates exactly requested bytes into the young generation void *kore_alloc(size_t requested); From cbcafadcee03f5c24f929bd56af0158073ec6da2 Mon Sep 17 00:00:00 2001 From: Steven Eker Date: Fri, 6 Dec 2024 22:56:23 +0100 Subject: [PATCH 5/5] deleted commented out code --- include/runtime/alloc.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/runtime/alloc.h b/include/runtime/alloc.h index 4b10e4779..9208e5ee8 100644 --- a/include/runtime/alloc.h +++ b/include/runtime/alloc.h @@ -15,7 +15,6 @@ extern "C" { char youngspace_collection_id(void); char oldspace_collection_id(void); -//size_t youngspace_size(void); // allocates exactly requested bytes into the young generation void *kore_alloc(size_t requested);