Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add zfree_with_size to optimize sdsfree since we can get zmalloc_size from the header #453

Merged
merged 11 commits into from
Jun 19, 2024
13 changes: 9 additions & 4 deletions src/sds.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ sds sdsdup(const sds s) {
/* Free an sds string. No operation is performed if 's' is NULL. */
void sdsfree(sds s) {
if (s == NULL) return;
s_free((char *)s - sdsHdrSize(s[-1]));
s_free_with_size(sdsAllocPtr(s), sdsAllocSize(s));
madolson marked this conversation as resolved.
Show resolved Hide resolved
}

/* Set the sds string length to the length as obtained with strlen(), so
Expand Down Expand Up @@ -369,7 +369,7 @@ sds sdsResize(sds s, size_t size, int would_regrow) {
* We aim to avoid calling realloc() when using Jemalloc if there is no
* change in the allocation size, as it incurs a cost even if the
* allocation size stays the same. */
bufsize = zmalloc_size(sh);
bufsize = sdsAllocSize(s);
alloc_already_optimal = (je_nallocx(newlen, 0) == bufsize);
#endif
if (!alloc_already_optimal) {
Expand Down Expand Up @@ -412,8 +412,13 @@ sds sdsResize(sds s, size_t size, int would_regrow) {
* 4) The implicit null term.
*/
size_t sdsAllocSize(sds s) {
size_t alloc = sdsalloc(s);
return sdsHdrSize(s[-1]) + alloc + 1;
char type = s[-1] & SDS_TYPE_MASK;
/* SDS_TYPE_5 header doesn't contain the size of the allocation */
if (type == SDS_TYPE_5) {
return s_malloc_size(sdsAllocPtr(s));
madolson marked this conversation as resolved.
Show resolved Hide resolved
} else {
return sdsHdrSize(type) + sdsalloc(s) + 1;
}
}

/* Return the pointer of the actual SDS allocation (normally SDS strings
Expand Down
1 change: 1 addition & 0 deletions src/sdsalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#define s_trymalloc ztrymalloc
#define s_tryrealloc ztryrealloc
#define s_free zfree
#define s_free_with_size zfree_with_size
#define s_malloc_usable zmalloc_usable
#define s_realloc_usable zrealloc_usable
#define s_trymalloc_usable ztrymalloc_usable
Expand Down
31 changes: 21 additions & 10 deletions src/zmalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -361,22 +361,33 @@ size_t zmalloc_usable_size(void *ptr) {
}
#endif

void zfree(void *ptr) {
#ifndef HAVE_MALLOC_SIZE
void *realptr;
size_t oldsize;
/* Frees the memory buffer pointed by ptr and updates statistics.
* ptr must already point to the start of the buffer. On systems where we store
poiuj marked this conversation as resolved.
Show resolved Hide resolved
* an additional header, the caller must do the necessary adjustments.
madolson marked this conversation as resolved.
Show resolved Hide resolved
* ptr must not be NULL. With jemalloc this function uses the fast track by
poiuj marked this conversation as resolved.
Show resolved Hide resolved
* specifying the buffer size */
void zfree_with_size(void *ptr, size_t size) {
update_zmalloc_stat_free(size);

#ifdef USE_JEMALLOC
je_sdallocx(ptr, size, 0);
#else
free(ptr);
#endif
}

void zfree(void *ptr) {
if (ptr == NULL) return;

#ifdef HAVE_MALLOC_SIZE
update_zmalloc_stat_free(zmalloc_size(ptr));
free(ptr);
size_t size = zmalloc_size(ptr);
#else
realptr = (char *)ptr - PREFIX_SIZE;
oldsize = *((size_t *)realptr);
update_zmalloc_stat_free(oldsize + PREFIX_SIZE);
free(realptr);
ptr = (char *)ptr - PREFIX_SIZE;
size_t data_size = *((size_t *)ptr);
size_t size = data_size + PREFIX_SIZE;
#endif

zfree_with_size(ptr, size);
}

char *zstrdup(const char *s) {
Expand Down
1 change: 1 addition & 0 deletions src/zmalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ __attribute__((malloc, alloc_size(1), noinline)) void *ztrymalloc(size_t size);
__attribute__((malloc, alloc_size(1), noinline)) void *ztrycalloc(size_t size);
__attribute__((alloc_size(2), noinline)) void *ztryrealloc(void *ptr, size_t size);
void zfree(void *ptr);
void zfree_with_size(void *ptr, size_t size);
void *zmalloc_usable(size_t size, size_t *usable);
void *zcalloc_usable(size_t size, size_t *usable);
void *zrealloc_usable(void *ptr, size_t size, size_t *usable);
Expand Down
Loading