alloc.con commit Merge branch 'jc/revision-range-unpeel' into maint (0faff47)
   1/*
   2 * alloc.c  - specialized allocator for internal objects
   3 *
   4 * Copyright (C) 2006 Linus Torvalds
   5 *
   6 * The standard malloc/free wastes too much space for objects, partly because
   7 * it maintains all the allocation infrastructure (which isn't needed, since
   8 * we never free an object descriptor anyway), but even more because it ends
   9 * up with maximal alignment because it doesn't know what the object alignment
  10 * for the new allocation is.
  11 */
  12#include "cache.h"
  13#include "object.h"
  14#include "blob.h"
  15#include "tree.h"
  16#include "commit.h"
  17#include "tag.h"
  18
  19#define BLOCKING 1024
  20
  21#define DEFINE_ALLOCATOR(name, type)                            \
  22static unsigned int name##_allocs;                              \
  23void *alloc_##name##_node(void)                                 \
  24{                                                               \
  25        static int nr;                                          \
  26        static type *block;                                     \
  27        void *ret;                                              \
  28                                                                \
  29        if (!nr) {                                              \
  30                nr = BLOCKING;                                  \
  31                block = xmalloc(BLOCKING * sizeof(type));       \
  32        }                                                       \
  33        nr--;                                                   \
  34        name##_allocs++;                                        \
  35        ret = block++;                                          \
  36        memset(ret, 0, sizeof(type));                           \
  37        return ret;                                             \
  38}
  39
  40union any_object {
  41        struct object object;
  42        struct blob blob;
  43        struct tree tree;
  44        struct commit commit;
  45        struct tag tag;
  46};
  47
  48DEFINE_ALLOCATOR(blob, struct blob)
  49DEFINE_ALLOCATOR(tree, struct tree)
  50DEFINE_ALLOCATOR(commit, struct commit)
  51DEFINE_ALLOCATOR(tag, struct tag)
  52DEFINE_ALLOCATOR(object, union any_object)
  53
  54static void report(const char *name, unsigned int count, size_t size)
  55{
  56        fprintf(stderr, "%10s: %8u (%"PRIuMAX" kB)\n",
  57                        name, count, (uintmax_t) size);
  58}
  59
  60#define REPORT(name)    \
  61    report(#name, name##_allocs, name##_allocs*sizeof(struct name) >> 10)
  62
  63void alloc_report(void)
  64{
  65        REPORT(blob);
  66        REPORT(tree);
  67        REPORT(commit);
  68        REPORT(tag);
  69}