Skip to content

Commit

Permalink
use tagged pointers to optimize arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
graphitemaster committed Aug 20, 2023
1 parent 9eec6c8 commit 5397033
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 10 deletions.
7 changes: 5 additions & 2 deletions src/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "context.h"
#include "allocator.h"

Ptr array_create(Context *context) {
static Ptr array_create_(Context *context) {
Allocator *allocator = &context->allocator;
Array *array = allocator_allocate(allocator, sizeof *array);
if (!array) {
Expand All @@ -16,6 +16,9 @@ Ptr array_create(Context *context) {

void array_grow(void **const array, Size elements, Size type_size) {
ASSERT(*array);
if (!array_valid(*array)) {
*array = array_create_(tagptr_ptr(*array));
}
Array *meta = array_meta(*array);
Context *const context = meta->context;
Allocator *const allocator = &context->allocator;
Expand All @@ -33,7 +36,7 @@ void array_grow(void **const array, Size elements, Size type_size) {
}

void array_delete(void *const array) {
ASSERT(array);
if (!array) return;
Array *const meta = array_meta(array);
Context *const context = meta->context;
Allocator *const allocator = &context->allocator;
Expand Down
18 changes: 10 additions & 8 deletions src/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,24 @@ struct ALIGN(16) Array {
#define Array(T) T*

#define array_make(context) \
array_create(context)
tagptr(context, 0x1)

#define array_valid(array) \
(tagptr_tag(array) != 0x1)

#define array_meta(array) \
(&RCAST(Array*, (array))[-1])

#define array_try_grow(array, size_) \
(((array) && array_meta(array)->size + (size_) < array_meta(array)->capacity) \
((array_valid(array) && array_meta(array)->size + (size_) < array_meta(array)->capacity) \
? true \
: (array_grow(RCAST(void **, &(array)), (size_), sizeof *(array)), true))

#define array_size(array) \
((array) ? array_meta(array)->size : 0)
(array_valid(array) ? array_meta(array)->size : 0)

#define array_capacity(array) \
((arrray) ? array_meta(array)->capacity : 0)
(array_valid(array) ? array_meta(array)->capacity : 0)

#define array_expand(array, size_) \
(array_try_grow((array), (size_)) \
Expand All @@ -50,10 +53,10 @@ struct ALIGN(16) Array {
: false)

#define array_free(array) \
(void)((array) ? (array_delete(array), (array) = 0) : 0)
(void)(array_valid(array) ? (array_delete(array), (array) = 0) : 0)

#define array_resize(array, size_) \
((array) \
(array_valid(array) \
? (array_meta(array)->size >= (size_) \
? (array_meta(array)->size = (size_), true) \
: array_expand((array), (size_) - array_meta(array)->size)) \
Expand All @@ -65,10 +68,9 @@ struct ALIGN(16) Array {
((array)[array_size(array) - 1])

#define array_clear(array) \
(void)((array) ? array_meta(array)->size = 0 : 0)
(void)(array_valid(array) ? array_meta(array)->size = 0 : 0)

void array_grow(void **const array, Size elements, Size type_size);
void array_delete(void *const array);
Ptr array_create(Context *context);

#endif // CODIN_ARRAY_H
17 changes: 17 additions & 0 deletions src/support.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,12 @@ struct Ptr {
constexpr operator bool() const noexcept { return p; }
void *p = 0;
};
#define PTR_TO_BITS(ptr) RCAST(Uint64, (ptr).p)
#define PTR_FROM_BITS(bits) Ptr(RCAST(void *, (bits)))
#else
typedef void *Ptr;
#define PTR_TO_BITS(ptr) RCAST(Uint64, ptr)
#define PTR_FROM_BITS(bits) RCAST(Ptr, (bits))
#endif

// Support bitwise operators on enumerators in C++ like C.
Expand Down Expand Up @@ -188,6 +192,19 @@ constexpr T& operator^= (T& a, T b) noexcept {
}
#endif

// Tagged pointer helpers assuming 16-byte aligned pointers
static FORCE_INLINE Ptr tagptr(Ptr ptr, Uint8 tag) {
return PTR_FROM_BITS(PTR_TO_BITS(ptr) | tag);
}

static FORCE_INLINE Uint8 tagptr_tag(Ptr ptr) {
return PTR_TO_BITS(ptr) & 15;
}

static FORCE_INLINE Ptr tagptr_ptr(Ptr ptr) {
return PTR_FROM_BITS(PTR_TO_BITS(ptr) & ~15);
}

#if defined(__clang__) && defined(__cplusplus)
#define THREAD_ATTRIBUTE(x) __attribute__((x))
#else
Expand Down

0 comments on commit 5397033

Please sign in to comment.