Hash :
9865cd16
Author :
Date :
2018-03-20T14:23:49
alloc: make memory allocators use function pointers Currently, our memory allocators are being redirected to the correct implementation at compile time by simply using macros. In order to make them swappable at runtime, this commit reshuffles that by instead making use of a global "git_allocator" structure, whose pointers are set up to reference the allocator functions. Like this, it becomes easy to swap out allocators by simply setting these function pointers. In order to initialize a "git_allocator", our provided allocators "stdalloc" and "crtdbg" both provide an init function. This is being called to initialize a passed in allocator struct and set up its members correctly. No support is yet included to enable users of libgit2 to switch out the memory allocator at a global level.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "stdalloc.h"
static void *stdalloc__malloc(size_t len, const char *file, int line)
{
void *ptr = malloc(len);
GIT_UNUSED(file);
GIT_UNUSED(line);
if (!ptr) giterr_set_oom();
return ptr;
}
static void *stdalloc__calloc(size_t nelem, size_t elsize, const char *file, int line)
{
void *ptr = calloc(nelem, elsize);
GIT_UNUSED(file);
GIT_UNUSED(line);
if (!ptr) giterr_set_oom();
return ptr;
}
static char *stdalloc__strdup(const char *str, const char *file, int line)
{
char *ptr = strdup(str);
GIT_UNUSED(file);
GIT_UNUSED(line);
if (!ptr) giterr_set_oom();
return ptr;
}
static char *stdalloc__strndup(const char *str, size_t n, const char *file, int line)
{
size_t length = 0, alloclength;
char *ptr;
length = p_strnlen(str, n);
if (GIT_ADD_SIZET_OVERFLOW(&alloclength, length, 1) ||
!(ptr = stdalloc__malloc(alloclength, file, line)))
return NULL;
if (length)
memcpy(ptr, str, length);
ptr[length] = '\0';
return ptr;
}
static char *stdalloc__substrdup(const char *start, size_t n, const char *file, int line)
{
char *ptr;
size_t alloclen;
if (GIT_ADD_SIZET_OVERFLOW(&alloclen, n, 1) ||
!(ptr = stdalloc__malloc(alloclen, file, line)))
return NULL;
memcpy(ptr, start, n);
ptr[n] = '\0';
return ptr;
}
static void *stdalloc__realloc(void *ptr, size_t size, const char *file, int line)
{
void *new_ptr = realloc(ptr, size);
GIT_UNUSED(file);
GIT_UNUSED(line);
if (!new_ptr) giterr_set_oom();
return new_ptr;
}
static void *stdalloc__reallocarray(void *ptr, size_t nelem, size_t elsize, const char *file, int line)
{
size_t newsize;
GIT_UNUSED(file);
GIT_UNUSED(line);
return GIT_MULTIPLY_SIZET_OVERFLOW(&newsize, nelem, elsize) ?
NULL : realloc(ptr, newsize);
}
static void *stdalloc__mallocarray(size_t nelem, size_t elsize, const char *file, int line)
{
return stdalloc__reallocarray(NULL, nelem, elsize, file, line);
}
static void stdalloc__free(void *ptr)
{
free(ptr);
}
int git_stdalloc_init_allocator(git_allocator *allocator)
{
allocator->gmalloc = stdalloc__malloc;
allocator->gcalloc = stdalloc__calloc;
allocator->gstrdup = stdalloc__strdup;
allocator->gstrndup = stdalloc__strndup;
allocator->gsubstrdup = stdalloc__substrdup;
allocator->grealloc = stdalloc__realloc;
allocator->greallocarray = stdalloc__reallocarray;
allocator->gmallocarray = stdalloc__mallocarray;
allocator->gfree = stdalloc__free;
return 0;
}