+++ /dev/null
-/*
- * 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);
-}