diff --git a/alloc.c b/alloc.c index 460db192d5..216c23a6f8 100644 --- a/alloc.c +++ b/alloc.c @@ -18,26 +18,38 @@ #define BLOCKING 1024 -#define DEFINE_ALLOCATOR(name) \ +#define DEFINE_ALLOCATOR(name, type) \ static unsigned int name##_allocs; \ -struct name *alloc_##name##_node(void) \ +void *alloc_##name##_node(void) \ { \ static int nr; \ - static struct name *block; \ + static type *block; \ + void *ret; \ \ if (!nr) { \ nr = BLOCKING; \ - block = xcalloc(BLOCKING, sizeof(struct name)); \ + block = xmalloc(BLOCKING * sizeof(type)); \ } \ nr--; \ name##_allocs++; \ - return block++; \ + ret = block++; \ + memset(ret, 0, sizeof(type)); \ + return ret; \ } -DEFINE_ALLOCATOR(blob) -DEFINE_ALLOCATOR(tree) -DEFINE_ALLOCATOR(commit) -DEFINE_ALLOCATOR(tag) +union any_object { + struct object object; + struct blob blob; + struct tree tree; + struct commit commit; + struct tag tag; +}; + +DEFINE_ALLOCATOR(blob, struct blob) +DEFINE_ALLOCATOR(tree, struct tree) +DEFINE_ALLOCATOR(commit, struct commit) +DEFINE_ALLOCATOR(tag, struct tag) +DEFINE_ALLOCATOR(object, union any_object) #ifdef NO_C99_FORMAT #define SZ_FMT "%u" diff --git a/blob.c b/blob.c index 0a9ea417b8..bd7d078e1a 100644 --- a/blob.c +++ b/blob.c @@ -6,12 +6,8 @@ const char *blob_type = "blob"; struct blob *lookup_blob(const unsigned char *sha1) { struct object *obj = lookup_object(sha1); - if (!obj) { - struct blob *ret = alloc_blob_node(); - created_object(sha1, &ret->object); - ret->object.type = OBJ_BLOB; - return ret; - } + if (!obj) + return create_object(sha1, OBJ_BLOB, alloc_blob_node()); if (!obj->type) obj->type = OBJ_BLOB; if (obj->type != OBJ_BLOB) { diff --git a/cache.h b/cache.h index 05f188558b..89aaf0022d 100644 --- a/cache.h +++ b/cache.h @@ -499,14 +499,11 @@ int decode_85(char *dst, const char *line, int linelen); void encode_85(char *buf, const unsigned char *data, int bytes); /* alloc.c */ -struct blob; -struct tree; -struct commit; -struct tag; -extern struct blob *alloc_blob_node(void); -extern struct tree *alloc_tree_node(void); -extern struct commit *alloc_commit_node(void); -extern struct tag *alloc_tag_node(void); +extern void *alloc_blob_node(void); +extern void *alloc_tree_node(void); +extern void *alloc_commit_node(void); +extern void *alloc_tag_node(void); +extern void *alloc_object_node(void); extern void alloc_report(void); /* trace.c */ diff --git a/commit.c b/commit.c index 952095faa7..10466c4ae0 100644 --- a/commit.c +++ b/commit.c @@ -98,12 +98,8 @@ struct commit *lookup_commit_reference(const unsigned char *sha1) struct commit *lookup_commit(const unsigned char *sha1) { struct object *obj = lookup_object(sha1); - if (!obj) { - struct commit *ret = alloc_commit_node(); - created_object(sha1, &ret->object); - ret->object.type = OBJ_COMMIT; - return ret; - } + if (!obj) + return create_object(sha1, OBJ_COMMIT, alloc_commit_node()); if (!obj->type) obj->type = OBJ_COMMIT; return check_commit(obj, sha1, 0); diff --git a/object.c b/object.c index 78a44a6ef4..7bd3fec556 100644 --- a/object.c +++ b/object.c @@ -105,11 +105,13 @@ static void grow_object_hash(void) obj_hash_size = new_hash_size; } -void created_object(const unsigned char *sha1, struct object *obj) +void *create_object(const unsigned char *sha1, int type, void *o) { + struct object *obj = o; + obj->parsed = 0; obj->used = 0; - obj->type = OBJ_NONE; + obj->type = type; obj->flags = 0; hashcpy(obj->sha1, sha1); @@ -118,25 +120,14 @@ void created_object(const unsigned char *sha1, struct object *obj) insert_obj_hash(obj, obj_hash, obj_hash_size); nr_objs++; + return obj; } -union any_object { - struct object object; - struct commit commit; - struct tree tree; - struct blob blob; - struct tag tag; -}; - struct object *lookup_unknown_object(const unsigned char *sha1) { struct object *obj = lookup_object(sha1); - if (!obj) { - union any_object *ret = xcalloc(1, sizeof(*ret)); - created_object(sha1, &ret->object); - ret->object.type = OBJ_NONE; - return &ret->object; - } + if (!obj) + obj = create_object(sha1, OBJ_NONE, alloc_object_node()); return obj; } diff --git a/object.h b/object.h index bdbbc1889c..3e26a0e8b9 100644 --- a/object.h +++ b/object.h @@ -46,7 +46,7 @@ extern struct object_refs *lookup_object_refs(struct object *); /** Internal only **/ struct object *lookup_object(const unsigned char *sha1); -void created_object(const unsigned char *sha1, struct object *obj); +extern void *create_object(const unsigned char *sha1, int type, void *obj); /** Returns the object, having parsed it to find out what it is. **/ struct object *parse_object(const unsigned char *sha1); diff --git a/tag.c b/tag.c index 56a49f4fe1..330d287924 100644 --- a/tag.c +++ b/tag.c @@ -20,13 +20,9 @@ struct object *deref_tag(struct object *o, const char *warn, int warnlen) struct tag *lookup_tag(const unsigned char *sha1) { - struct object *obj = lookup_object(sha1); - if (!obj) { - struct tag *ret = alloc_tag_node(); - created_object(sha1, &ret->object); - ret->object.type = OBJ_TAG; - return ret; - } + struct object *obj = lookup_object(sha1); + if (!obj) + return create_object(sha1, OBJ_TAG, alloc_tag_node()); if (!obj->type) obj->type = OBJ_TAG; if (obj->type != OBJ_TAG) { diff --git a/tree.c b/tree.c index dbb63fc525..e4a39aa3c3 100644 --- a/tree.c +++ b/tree.c @@ -127,12 +127,8 @@ int read_tree(struct tree *tree, int stage, const char **match) struct tree *lookup_tree(const unsigned char *sha1) { struct object *obj = lookup_object(sha1); - if (!obj) { - struct tree *ret = alloc_tree_node(); - created_object(sha1, &ret->object); - ret->object.type = OBJ_TREE; - return ret; - } + if (!obj) + return create_object(sha1, OBJ_TREE, alloc_tree_node()); if (!obj->type) obj->type = OBJ_TREE; if (obj->type != OBJ_TREE) {