Merge branch 'jk/alloc-commit-id'

Make sure all in-core commit objects are assigned a unique number
so that they can be annotated using the commit-slab API.

* jk/alloc-commit-id:
  diff-tree: avoid lookup_unknown_object
  object_as_type: set commit index
  alloc: factor out commit index
  add object_as_type helper for casting objects
  parse_object_buffer: do not set object type
  move setting of object->type to alloc_* functions
  alloc: write out allocator definitions
  alloc.c: remove the alloc_raw_commit_node() function
This commit is contained in:
Junio C Hamano 2014-07-22 10:59:24 -07:00
commit 10b944b37b
11 changed files with 103 additions and 89 deletions

95
alloc.c
View File

@ -18,25 +18,6 @@
#define BLOCKING 1024
#define DEFINE_ALLOCATOR(name, type) \
static unsigned int name##_allocs; \
void *alloc_##name##_node(void) \
{ \
static int nr; \
static type *block; \
void *ret; \
\
if (!nr) { \
nr = BLOCKING; \
block = xmalloc(BLOCKING * sizeof(type)); \
} \
nr--; \
name##_allocs++; \
ret = block++; \
memset(ret, 0, sizeof(type)); \
return ret; \
}
union any_object {
struct object object;
struct blob blob;
@ -45,17 +26,73 @@ union any_object {
struct tag tag;
};
DEFINE_ALLOCATOR(blob, struct blob)
DEFINE_ALLOCATOR(tree, struct tree)
DEFINE_ALLOCATOR(raw_commit, struct commit)
DEFINE_ALLOCATOR(tag, struct tag)
DEFINE_ALLOCATOR(object, union any_object)
struct alloc_state {
int count; /* total number of nodes allocated */
int nr; /* number of nodes left in current allocation */
void *p; /* first free node in current allocation */
};
static inline void *alloc_node(struct alloc_state *s, size_t node_size)
{
void *ret;
if (!s->nr) {
s->nr = BLOCKING;
s->p = xmalloc(BLOCKING * node_size);
}
s->nr--;
s->count++;
ret = s->p;
s->p = (char *)s->p + node_size;
memset(ret, 0, node_size);
return ret;
}
static struct alloc_state blob_state;
void *alloc_blob_node(void)
{
struct blob *b = alloc_node(&blob_state, sizeof(struct blob));
b->object.type = OBJ_BLOB;
return b;
}
static struct alloc_state tree_state;
void *alloc_tree_node(void)
{
struct tree *t = alloc_node(&tree_state, sizeof(struct tree));
t->object.type = OBJ_TREE;
return t;
}
static struct alloc_state tag_state;
void *alloc_tag_node(void)
{
struct tag *t = alloc_node(&tag_state, sizeof(struct tag));
t->object.type = OBJ_TAG;
return t;
}
static struct alloc_state object_state;
void *alloc_object_node(void)
{
struct object *obj = alloc_node(&object_state, sizeof(union any_object));
obj->type = OBJ_NONE;
return obj;
}
static struct alloc_state commit_state;
unsigned int alloc_commit_index(void)
{
static unsigned int count;
return count++;
}
void *alloc_commit_node(void)
{
static int commit_count;
struct commit *c = alloc_raw_commit_node();
c->index = commit_count++;
struct commit *c = alloc_node(&commit_state, sizeof(struct commit));
c->object.type = OBJ_COMMIT;
c->index = alloc_commit_index();
return c;
}
@ -66,13 +103,13 @@ static void report(const char *name, unsigned int count, size_t size)
}
#define REPORT(name, type) \
report(#name, name##_allocs, name##_allocs * sizeof(type) >> 10)
report(#name, name##_state.count, name##_state.count * sizeof(type) >> 10)
void alloc_report(void)
{
REPORT(blob, struct blob);
REPORT(tree, struct tree);
REPORT(raw_commit, struct commit);
REPORT(commit, struct commit);
REPORT(tag, struct tag);
REPORT(object, union any_object);
}

11
blob.c
View File

@ -7,15 +7,8 @@ struct blob *lookup_blob(const unsigned char *sha1)
{
struct object *obj = lookup_object(sha1);
if (!obj)
return create_object(sha1, OBJ_BLOB, alloc_blob_node());
if (!obj->type)
obj->type = OBJ_BLOB;
if (obj->type != OBJ_BLOB) {
error("Object %s is a %s, not a blob",
sha1_to_hex(sha1), typename(obj->type));
return NULL;
}
return (struct blob *) obj;
return create_object(sha1, alloc_blob_node());
return object_as_type(obj, OBJ_BLOB, 0);
}
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)

View File

@ -2287,7 +2287,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
commit = alloc_commit_node();
commit->object.parsed = 1;
commit->date = now;
commit->object.type = OBJ_COMMIT;
parent_tail = &commit->parents;
if (!resolve_ref_unsafe("HEAD", head_sha1, 1, NULL))

View File

@ -68,8 +68,6 @@ static int diff_tree_stdin(char *line)
line[len-1] = 0;
if (get_sha1_hex(line, sha1))
return -1;
obj = lookup_unknown_object(sha1);
if (!obj || !obj->parsed)
obj = parse_object(sha1);
if (!obj)
return -1;

View File

@ -1402,6 +1402,7 @@ extern void *alloc_commit_node(void);
extern void *alloc_tag_node(void);
extern void *alloc_object_node(void);
extern void alloc_report(void);
extern unsigned int alloc_commit_index(void);
/* pkt-line.c */
void packet_trace_identity(const char *prog);

View File

@ -18,19 +18,6 @@ int save_commit_buffer = 1;
const char *commit_type = "commit";
static struct commit *check_commit(struct object *obj,
const unsigned char *sha1,
int quiet)
{
if (obj->type != OBJ_COMMIT) {
if (!quiet)
error("Object %s is a %s, not a commit",
sha1_to_hex(sha1), typename(obj->type));
return NULL;
}
return (struct commit *) obj;
}
struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
int quiet)
{
@ -38,7 +25,7 @@ struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
if (!obj)
return NULL;
return check_commit(obj, sha1, quiet);
return object_as_type(obj, OBJ_COMMIT, quiet);
}
struct commit *lookup_commit_reference(const unsigned char *sha1)
@ -61,13 +48,9 @@ struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_n
struct commit *lookup_commit(const unsigned char *sha1)
{
struct object *obj = lookup_object(sha1);
if (!obj) {
struct commit *c = alloc_commit_node();
return create_object(sha1, OBJ_COMMIT, c);
}
if (!obj->type)
obj->type = OBJ_COMMIT;
return check_commit(obj, sha1, 0);
if (!obj)
return create_object(sha1, alloc_commit_node());
return object_as_type(obj, OBJ_COMMIT, 0);
}
struct commit *lookup_commit_reference_by_name(const char *name)

View File

@ -130,13 +130,12 @@ static void grow_object_hash(void)
obj_hash_size = new_hash_size;
}
void *create_object(const unsigned char *sha1, int type, void *o)
void *create_object(const unsigned char *sha1, void *o)
{
struct object *obj = o;
obj->parsed = 0;
obj->used = 0;
obj->type = type;
obj->flags = 0;
hashcpy(obj->sha1, sha1);
@ -148,11 +147,30 @@ void *create_object(const unsigned char *sha1, int type, void *o)
return obj;
}
void *object_as_type(struct object *obj, enum object_type type, int quiet)
{
if (obj->type == type)
return obj;
else if (obj->type == OBJ_NONE) {
if (type == OBJ_COMMIT)
((struct commit *)obj)->index = alloc_commit_index();
obj->type = type;
return obj;
}
else {
if (!quiet)
error("object %s is a %s, not a %s",
sha1_to_hex(obj->sha1),
typename(obj->type), typename(type));
return NULL;
}
}
struct object *lookup_unknown_object(const unsigned char *sha1)
{
struct object *obj = lookup_object(sha1);
if (!obj)
obj = create_object(sha1, OBJ_NONE, alloc_object_node());
obj = create_object(sha1, alloc_object_node());
return obj;
}
@ -203,8 +221,6 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
warning("object %s has unknown type id %d", sha1_to_hex(sha1), type);
obj = NULL;
}
if (obj && obj->type == OBJ_NONE)
obj->type = type;
return obj;
}

View File

@ -79,7 +79,9 @@ extern struct object *get_indexed_object(unsigned int);
*/
struct object *lookup_object(const unsigned char *sha1);
extern void *create_object(const unsigned char *sha1, int type, void *obj);
extern void *create_object(const unsigned char *sha1, void *obj);
void *object_as_type(struct object *obj, enum object_type type, int quiet);
/*
* Returns the object, having parsed it to find out what it is.

3
refs.c
View File

@ -1741,9 +1741,8 @@ static enum peel_status peel_object(const unsigned char *name, unsigned char *sh
if (o->type == OBJ_NONE) {
int type = sha1_object_info(name, NULL);
if (type < 0)
if (type < 0 || !object_as_type(o, type, 0))
return PEEL_INVALID;
o->type = type;
}
if (o->type != OBJ_TAG)

11
tag.c
View File

@ -40,15 +40,8 @@ struct tag *lookup_tag(const unsigned char *sha1)
{
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) {
error("Object %s is a %s, not a tag",
sha1_to_hex(sha1), typename(obj->type));
return NULL;
}
return (struct tag *) obj;
return create_object(sha1, alloc_tag_node());
return object_as_type(obj, OBJ_TAG, 0);
}
static unsigned long parse_tag_date(const char *buf, const char *tail)

11
tree.c
View File

@ -183,15 +183,8 @@ struct tree *lookup_tree(const unsigned char *sha1)
{
struct object *obj = lookup_object(sha1);
if (!obj)
return create_object(sha1, OBJ_TREE, alloc_tree_node());
if (!obj->type)
obj->type = OBJ_TREE;
if (obj->type != OBJ_TREE) {
error("Object %s is a %s, not a tree",
sha1_to_hex(sha1), typename(obj->type));
return NULL;
}
return (struct tree *) obj;
return create_object(sha1, alloc_tree_node());
return object_as_type(obj, OBJ_TREE, 0);
}
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)