2 * alloc.c - specialized allocator for internal objects
4 * Copyright (C) 2006 Linus Torvalds
6 * The standard malloc/free wastes too much space for objects, partly because
7 * it maintains all the allocation infrastructure, but even more because it ends
8 * up with maximal alignment because it doesn't know what the object alignment
9 * for the new allocation is.
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 */
34 /* bookkeeping of allocations */
36 int slab_nr
, slab_alloc
;
39 void *allocate_alloc_state(void)
41 return xcalloc(1, sizeof(struct alloc_state
));
44 void clear_alloc_state(struct alloc_state
*s
)
46 while (s
->slab_nr
> 0) {
48 free(s
->slabs
[s
->slab_nr
]);
51 FREE_AND_NULL(s
->slabs
);
54 static inline void *alloc_node(struct alloc_state
*s
, size_t node_size
)
60 s
->p
= xmalloc(BLOCKING
* node_size
);
62 ALLOC_GROW(s
->slabs
, s
->slab_nr
+ 1, s
->slab_alloc
);
63 s
->slabs
[s
->slab_nr
++] = s
->p
;
68 s
->p
= (char *)s
->p
+ node_size
;
69 memset(ret
, 0, node_size
);
74 void *alloc_blob_node(struct repository
*r
)
76 struct blob
*b
= alloc_node(r
->parsed_objects
->blob_state
, sizeof(struct blob
));
77 b
->object
.type
= OBJ_BLOB
;
81 void *alloc_tree_node(struct repository
*r
)
83 struct tree
*t
= alloc_node(r
->parsed_objects
->tree_state
, sizeof(struct tree
));
84 t
->object
.type
= OBJ_TREE
;
88 void *alloc_tag_node(struct repository
*r
)
90 struct tag
*t
= alloc_node(r
->parsed_objects
->tag_state
, sizeof(struct tag
));
91 t
->object
.type
= OBJ_TAG
;
95 void *alloc_object_node(struct repository
*r
)
97 struct object
*obj
= alloc_node(r
->parsed_objects
->object_state
, sizeof(union any_object
));
102 unsigned int alloc_commit_index(struct repository
*r
)
104 return r
->parsed_objects
->commit_count
++;
107 void *alloc_commit_node(struct repository
*r
)
109 struct commit
*c
= alloc_node(r
->parsed_objects
->commit_state
, sizeof(struct commit
));
110 c
->object
.type
= OBJ_COMMIT
;
111 c
->index
= alloc_commit_index(r
);
115 static void report(const char *name
, unsigned int count
, size_t size
)
117 fprintf(stderr
, "%10s: %8u (%"PRIuMAX
" kB)\n",
118 name
, count
, (uintmax_t) size
);
121 #define REPORT(name, type) \
122 report(#name, r->parsed_objects->name##_state->count, \
123 r->parsed_objects->name##_state->count * sizeof(type) >> 10)
125 void alloc_report(struct repository
*r
)
127 REPORT(blob
, struct blob
);
128 REPORT(tree
, struct tree
);
129 REPORT(commit
, struct commit
);
130 REPORT(tag
, struct tag
);
131 REPORT(object
, union any_object
);