diff options
Diffstat (limited to 'src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c')
-rw-r--r-- | src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c b/src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c new file mode 100644 index 00000000..a89babf9 --- /dev/null +++ b/src/civetweb/src/third_party/duktape-1.8.0/examples/alloc-logging/duk_alloc_logging.c @@ -0,0 +1,138 @@ +/* + * Example memory allocator with machine parseable logging. + * + * Also sizes for reallocs and frees are logged so that the memory + * behavior can be essentially replayed to accurately determine e.g. + * optimal pool sizes for a pooled allocator. + * + * Allocation structure: + * + * [ alloc_hdr | user area ] + * + * ^ ^ + * | `--- pointer returned to Duktape + * `--- underlying malloc ptr + */ + +#include "duktape.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdint.h> + +#define ALLOC_LOG_FILE "/tmp/duk-alloc-log.txt" + +typedef struct { + /* The double value in the union is there to ensure alignment is + * good for IEEE doubles too. In many 32-bit environments 4 bytes + * would be sufficiently aligned and the double value is unnecessary. + */ + union { + size_t sz; + double d; + } u; +} alloc_hdr; + +static FILE *log_file = NULL; + +static void write_log(const char *fmt, ...) { + va_list ap; + + if (!log_file) { + log_file = fopen(ALLOC_LOG_FILE, "wb"); + if (!log_file) { + return; + } + } + + va_start(ap, fmt); + vfprintf(log_file, fmt, ap); + va_end(ap); +} + +void *duk_alloc_logging(void *udata, duk_size_t size) { + alloc_hdr *hdr; + void *ret; + + (void) udata; /* Suppress warning. */ + + if (size == 0) { + write_log("A NULL %ld\n", (long) size); + return NULL; + } + + hdr = (alloc_hdr *) malloc(size + sizeof(alloc_hdr)); + if (!hdr) { + write_log("A FAIL %ld\n", (long) size); + return NULL; + } + hdr->u.sz = size; + ret = (void *) (hdr + 1); + write_log("A %p %ld\n", ret, (long) size); + return ret; +} + +void *duk_realloc_logging(void *udata, void *ptr, duk_size_t size) { + alloc_hdr *hdr; + size_t old_size; + void *t; + void *ret; + + (void) udata; /* Suppress warning. */ + + /* Handle the ptr-NULL vs. size-zero cases explicitly to minimize + * platform assumptions. You can get away with much less in specific + * well-behaving environments. + */ + + if (ptr) { + hdr = (alloc_hdr *) (void *) ((unsigned char *) ptr - sizeof(alloc_hdr)); + old_size = hdr->u.sz; + + if (size == 0) { + write_log("R %p %ld NULL 0\n", ptr, (long) old_size); + free((void *) hdr); + return NULL; + } else { + t = realloc((void *) hdr, size + sizeof(alloc_hdr)); + if (!t) { + write_log("R %p %ld FAIL %ld\n", ptr, (long) old_size, (long) size); + return NULL; + } + hdr = (alloc_hdr *) t; + hdr->u.sz = size; + ret = (void *) (hdr + 1); + write_log("R %p %ld %p %ld\n", ptr, (long) old_size, ret, (long) size); + return ret; + } + } else { + if (size == 0) { + write_log("R NULL 0 NULL 0\n"); + return NULL; + } else { + hdr = (alloc_hdr *) malloc(size + sizeof(alloc_hdr)); + if (!hdr) { + write_log("R NULL 0 FAIL %ld\n", (long) size); + return NULL; + } + hdr->u.sz = size; + ret = (void *) (hdr + 1); + write_log("R NULL 0 %p %ld\n", ret, (long) size); + return ret; + } + } +} + +void duk_free_logging(void *udata, void *ptr) { + alloc_hdr *hdr; + + (void) udata; /* Suppress warning. */ + + if (!ptr) { + write_log("F NULL 0\n"); + return; + } + hdr = (alloc_hdr *) (void *) ((unsigned char *) ptr - sizeof(alloc_hdr)); + write_log("F %p %ld\n", ptr, (long) hdr->u.sz); + free((void *) hdr); +} |