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() functionmaint
commit
10b944b37b
95
alloc.c
95
alloc.c
|
@ -18,25 +18,6 @@
|
||||||
|
|
||||||
#define BLOCKING 1024
|
#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 {
|
union any_object {
|
||||||
struct object object;
|
struct object object;
|
||||||
struct blob blob;
|
struct blob blob;
|
||||||
|
@ -45,17 +26,73 @@ union any_object {
|
||||||
struct tag tag;
|
struct tag tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_ALLOCATOR(blob, struct blob)
|
struct alloc_state {
|
||||||
DEFINE_ALLOCATOR(tree, struct tree)
|
int count; /* total number of nodes allocated */
|
||||||
DEFINE_ALLOCATOR(raw_commit, struct commit)
|
int nr; /* number of nodes left in current allocation */
|
||||||
DEFINE_ALLOCATOR(tag, struct tag)
|
void *p; /* first free node in current allocation */
|
||||||
DEFINE_ALLOCATOR(object, union any_object)
|
};
|
||||||
|
|
||||||
|
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)
|
void *alloc_commit_node(void)
|
||||||
{
|
{
|
||||||
static int commit_count;
|
struct commit *c = alloc_node(&commit_state, sizeof(struct commit));
|
||||||
struct commit *c = alloc_raw_commit_node();
|
c->object.type = OBJ_COMMIT;
|
||||||
c->index = commit_count++;
|
c->index = alloc_commit_index();
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,13 +103,13 @@ static void report(const char *name, unsigned int count, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define REPORT(name, type) \
|
#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)
|
void alloc_report(void)
|
||||||
{
|
{
|
||||||
REPORT(blob, struct blob);
|
REPORT(blob, struct blob);
|
||||||
REPORT(tree, struct tree);
|
REPORT(tree, struct tree);
|
||||||
REPORT(raw_commit, struct commit);
|
REPORT(commit, struct commit);
|
||||||
REPORT(tag, struct tag);
|
REPORT(tag, struct tag);
|
||||||
REPORT(object, union any_object);
|
REPORT(object, union any_object);
|
||||||
}
|
}
|
||||||
|
|
11
blob.c
11
blob.c
|
@ -7,15 +7,8 @@ struct blob *lookup_blob(const unsigned char *sha1)
|
||||||
{
|
{
|
||||||
struct object *obj = lookup_object(sha1);
|
struct object *obj = lookup_object(sha1);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return create_object(sha1, OBJ_BLOB, alloc_blob_node());
|
return create_object(sha1, alloc_blob_node());
|
||||||
if (!obj->type)
|
return object_as_type(obj, OBJ_BLOB, 0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)
|
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)
|
||||||
|
|
|
@ -2287,7 +2287,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
|
||||||
commit = alloc_commit_node();
|
commit = alloc_commit_node();
|
||||||
commit->object.parsed = 1;
|
commit->object.parsed = 1;
|
||||||
commit->date = now;
|
commit->date = now;
|
||||||
commit->object.type = OBJ_COMMIT;
|
|
||||||
parent_tail = &commit->parents;
|
parent_tail = &commit->parents;
|
||||||
|
|
||||||
if (!resolve_ref_unsafe("HEAD", head_sha1, 1, NULL))
|
if (!resolve_ref_unsafe("HEAD", head_sha1, 1, NULL))
|
||||||
|
|
|
@ -68,9 +68,7 @@ static int diff_tree_stdin(char *line)
|
||||||
line[len-1] = 0;
|
line[len-1] = 0;
|
||||||
if (get_sha1_hex(line, sha1))
|
if (get_sha1_hex(line, sha1))
|
||||||
return -1;
|
return -1;
|
||||||
obj = lookup_unknown_object(sha1);
|
obj = parse_object(sha1);
|
||||||
if (!obj || !obj->parsed)
|
|
||||||
obj = parse_object(sha1);
|
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return -1;
|
return -1;
|
||||||
if (obj->type == OBJ_COMMIT)
|
if (obj->type == OBJ_COMMIT)
|
||||||
|
|
1
cache.h
1
cache.h
|
@ -1402,6 +1402,7 @@ extern void *alloc_commit_node(void);
|
||||||
extern void *alloc_tag_node(void);
|
extern void *alloc_tag_node(void);
|
||||||
extern void *alloc_object_node(void);
|
extern void *alloc_object_node(void);
|
||||||
extern void alloc_report(void);
|
extern void alloc_report(void);
|
||||||
|
extern unsigned int alloc_commit_index(void);
|
||||||
|
|
||||||
/* pkt-line.c */
|
/* pkt-line.c */
|
||||||
void packet_trace_identity(const char *prog);
|
void packet_trace_identity(const char *prog);
|
||||||
|
|
25
commit.c
25
commit.c
|
@ -18,19 +18,6 @@ int save_commit_buffer = 1;
|
||||||
|
|
||||||
const char *commit_type = "commit";
|
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,
|
struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
|
||||||
int quiet)
|
int quiet)
|
||||||
{
|
{
|
||||||
|
@ -38,7 +25,7 @@ struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
|
||||||
|
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return NULL;
|
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)
|
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 commit *lookup_commit(const unsigned char *sha1)
|
||||||
{
|
{
|
||||||
struct object *obj = lookup_object(sha1);
|
struct object *obj = lookup_object(sha1);
|
||||||
if (!obj) {
|
if (!obj)
|
||||||
struct commit *c = alloc_commit_node();
|
return create_object(sha1, alloc_commit_node());
|
||||||
return create_object(sha1, OBJ_COMMIT, c);
|
return object_as_type(obj, OBJ_COMMIT, 0);
|
||||||
}
|
|
||||||
if (!obj->type)
|
|
||||||
obj->type = OBJ_COMMIT;
|
|
||||||
return check_commit(obj, sha1, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct commit *lookup_commit_reference_by_name(const char *name)
|
struct commit *lookup_commit_reference_by_name(const char *name)
|
||||||
|
|
26
object.c
26
object.c
|
@ -130,13 +130,12 @@ static void grow_object_hash(void)
|
||||||
obj_hash_size = new_hash_size;
|
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;
|
struct object *obj = o;
|
||||||
|
|
||||||
obj->parsed = 0;
|
obj->parsed = 0;
|
||||||
obj->used = 0;
|
obj->used = 0;
|
||||||
obj->type = type;
|
|
||||||
obj->flags = 0;
|
obj->flags = 0;
|
||||||
hashcpy(obj->sha1, sha1);
|
hashcpy(obj->sha1, sha1);
|
||||||
|
|
||||||
|
@ -148,11 +147,30 @@ void *create_object(const unsigned char *sha1, int type, void *o)
|
||||||
return obj;
|
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 *lookup_unknown_object(const unsigned char *sha1)
|
||||||
{
|
{
|
||||||
struct object *obj = lookup_object(sha1);
|
struct object *obj = lookup_object(sha1);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
obj = create_object(sha1, OBJ_NONE, alloc_object_node());
|
obj = create_object(sha1, alloc_object_node());
|
||||||
return obj;
|
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);
|
warning("object %s has unknown type id %d", sha1_to_hex(sha1), type);
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
}
|
}
|
||||||
if (obj && obj->type == OBJ_NONE)
|
|
||||||
obj->type = type;
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
object.h
4
object.h
|
@ -79,7 +79,9 @@ extern struct object *get_indexed_object(unsigned int);
|
||||||
*/
|
*/
|
||||||
struct object *lookup_object(const unsigned char *sha1);
|
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.
|
* Returns the object, having parsed it to find out what it is.
|
||||||
|
|
3
refs.c
3
refs.c
|
@ -1741,9 +1741,8 @@ static enum peel_status peel_object(const unsigned char *name, unsigned char *sh
|
||||||
|
|
||||||
if (o->type == OBJ_NONE) {
|
if (o->type == OBJ_NONE) {
|
||||||
int type = sha1_object_info(name, NULL);
|
int type = sha1_object_info(name, NULL);
|
||||||
if (type < 0)
|
if (type < 0 || !object_as_type(o, type, 0))
|
||||||
return PEEL_INVALID;
|
return PEEL_INVALID;
|
||||||
o->type = type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (o->type != OBJ_TAG)
|
if (o->type != OBJ_TAG)
|
||||||
|
|
11
tag.c
11
tag.c
|
@ -40,15 +40,8 @@ struct tag *lookup_tag(const unsigned char *sha1)
|
||||||
{
|
{
|
||||||
struct object *obj = lookup_object(sha1);
|
struct object *obj = lookup_object(sha1);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return create_object(sha1, OBJ_TAG, alloc_tag_node());
|
return create_object(sha1, alloc_tag_node());
|
||||||
if (!obj->type)
|
return object_as_type(obj, OBJ_TAG, 0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long parse_tag_date(const char *buf, const char *tail)
|
static unsigned long parse_tag_date(const char *buf, const char *tail)
|
||||||
|
|
11
tree.c
11
tree.c
|
@ -183,15 +183,8 @@ struct tree *lookup_tree(const unsigned char *sha1)
|
||||||
{
|
{
|
||||||
struct object *obj = lookup_object(sha1);
|
struct object *obj = lookup_object(sha1);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
return create_object(sha1, OBJ_TREE, alloc_tree_node());
|
return create_object(sha1, alloc_tree_node());
|
||||||
if (!obj->type)
|
return object_as_type(obj, OBJ_TREE, 0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
|
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)
|
||||||
|
|
Loading…
Reference in New Issue