alloc.con commit Merge branch 'maint' (66f467c)
   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(raw_commit, struct commit)
  51DEFINE_ALLOCATOR(tag, struct tag)
  52DEFINE_ALLOCATOR(object, union any_object)
  53
  54void *alloc_commit_node(void)
  55{
  56        static int commit_count;
  57        struct commit *c = alloc_raw_commit_node();
  58        c->index = commit_count++;
  59        return c;
  60}
  61
  62static void report(const char *name, unsigned int count, size_t size)
  63{
  64        fprintf(stderr, "%10s: %8u (%"PRIuMAX" kB)\n",
  65                        name, count, (uintmax_t) size);
  66}
  67
  68#define REPORT(name, type)      \
  69    report(#name, name##_allocs, name##_allocs * sizeof(type) >> 10)
  70
  71void alloc_report(void)
  72{
  73        REPORT(blob, struct blob);
  74        REPORT(tree, struct tree);
  75        REPORT(raw_commit, struct commit);
  76        REPORT(tag, struct tag);
  77        REPORT(object, union any_object);
  78}