-
Notifications
You must be signed in to change notification settings - Fork 0
Permalink
git/alloc.c
Newer
100644
115 lines (100 sloc)
2.57 KB
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
union any_object {
22
struct object object;
23
struct blob blob;
24
struct tree tree;
25
struct commit commit;
26
struct tag tag;
27
};
28
29
struct alloc_state {
30
int count; /* total number of nodes allocated */
31
int nr; /* number of nodes left in current allocation */
32
void *p; /* first free node in current allocation */
33
};
34
35
static inline void *alloc_node(struct alloc_state *s, size_t node_size)
36
{
37
void *ret;
38
39
if (!s->nr) {
40
s->nr = BLOCKING;
41
s->p = xmalloc(BLOCKING * node_size);
42
}
43
s->nr--;
44
s->count++;
45
ret = s->p;
46
s->p = (char *)s->p + node_size;
47
memset(ret, 0, node_size);
48
return ret;
49
}
50
51
static struct alloc_state blob_state;
52
void *alloc_blob_node(void)
53
{
54
struct blob *b = alloc_node(&blob_state, sizeof(struct blob));
55
b->object.type = OBJ_BLOB;
56
return b;
57
}
58
59
static struct alloc_state tree_state;
60
void *alloc_tree_node(void)
61
{
62
struct tree *t = alloc_node(&tree_state, sizeof(struct tree));
63
t->object.type = OBJ_TREE;
64
return t;
65
}
66
67
static struct alloc_state tag_state;
68
void *alloc_tag_node(void)
69
{
70
struct tag *t = alloc_node(&tag_state, sizeof(struct tag));
71
t->object.type = OBJ_TAG;
72
return t;
73
}
74
75
static struct alloc_state object_state;
76
void *alloc_object_node(void)
77
{
78
struct object *obj = alloc_node(&object_state, sizeof(union any_object));
79
obj->type = OBJ_NONE;
80
return obj;
81
}
83
static struct alloc_state commit_state;
84
85
unsigned int alloc_commit_index(void)
86
{
87
static unsigned int count;
88
return count++;
89
}
90
91
void *alloc_commit_node(void)
92
{
93
struct commit *c = alloc_node(&commit_state, sizeof(struct commit));
94
c->object.type = OBJ_COMMIT;
95
c->index = alloc_commit_index();
96
return c;
97
}
98
99
static void report(const char *name, unsigned int count, size_t size)
100
{
101
fprintf(stderr, "%10s: %8u (%"PRIuMAX" kB)\n",
102
name, count, (uintmax_t) size);
103
}
104
105
#define REPORT(name, type) \
106
report(#name, name##_state.count, name##_state.count * sizeof(type) >> 10)
110
REPORT(blob, struct blob);
111
REPORT(tree, struct tree);
112
REPORT(commit, struct commit);
113
REPORT(tag, struct tag);
114
REPORT(object, union any_object);