Skip to content

Commit 5d7c37a

Browse files
committed
Merge branch 'jk/alloc-commit-id-maint' into maint
* jk/alloc-commit-id-maint: 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
2 parents 740c281 + b794ebe commit 5d7c37a

File tree

11 files changed

+103
-89
lines changed

11 files changed

+103
-89
lines changed

alloc.c

Lines changed: 66 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,6 @@
1818

1919
#define BLOCKING 1024
2020

21-
#define DEFINE_ALLOCATOR(name, type) \
22-
static unsigned int name##_allocs; \
23-
void *alloc_##name##_node(void) \
24-
{ \
25-
static int nr; \
26-
static type *block; \
27-
void *ret; \
28-
\
29-
if (!nr) { \
30-
nr = BLOCKING; \
31-
block = xmalloc(BLOCKING * sizeof(type)); \
32-
} \
33-
nr--; \
34-
name##_allocs++; \
35-
ret = block++; \
36-
memset(ret, 0, sizeof(type)); \
37-
return ret; \
38-
}
39-
4021
union any_object {
4122
struct object object;
4223
struct blob blob;
@@ -45,17 +26,73 @@ union any_object {
4526
struct tag tag;
4627
};
4728

48-
DEFINE_ALLOCATOR(blob, struct blob)
49-
DEFINE_ALLOCATOR(tree, struct tree)
50-
DEFINE_ALLOCATOR(raw_commit, struct commit)
51-
DEFINE_ALLOCATOR(tag, struct tag)
52-
DEFINE_ALLOCATOR(object, union any_object)
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+
}
82+
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+
}
5390

5491
void *alloc_commit_node(void)
5592
{
56-
static int commit_count;
57-
struct commit *c = alloc_raw_commit_node();
58-
c->index = commit_count++;
93+
struct commit *c = alloc_node(&commit_state, sizeof(struct commit));
94+
c->object.type = OBJ_COMMIT;
95+
c->index = alloc_commit_index();
5996
return c;
6097
}
6198

@@ -66,13 +103,13 @@ static void report(const char *name, unsigned int count, size_t size)
66103
}
67104

68105
#define REPORT(name, type) \
69-
report(#name, name##_allocs, name##_allocs * sizeof(type) >> 10)
106+
report(#name, name##_state.count, name##_state.count * sizeof(type) >> 10)
70107

71108
void alloc_report(void)
72109
{
73110
REPORT(blob, struct blob);
74111
REPORT(tree, struct tree);
75-
REPORT(raw_commit, struct commit);
112+
REPORT(commit, struct commit);
76113
REPORT(tag, struct tag);
77114
REPORT(object, union any_object);
78115
}

blob.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,8 @@ struct blob *lookup_blob(const unsigned char *sha1)
77
{
88
struct object *obj = lookup_object(sha1);
99
if (!obj)
10-
return create_object(sha1, OBJ_BLOB, alloc_blob_node());
11-
if (!obj->type)
12-
obj->type = OBJ_BLOB;
13-
if (obj->type != OBJ_BLOB) {
14-
error("Object %s is a %s, not a blob",
15-
sha1_to_hex(sha1), typename(obj->type));
16-
return NULL;
17-
}
18-
return (struct blob *) obj;
10+
return create_object(sha1, alloc_blob_node());
11+
return object_as_type(obj, OBJ_BLOB, 0);
1912
}
2013

2114
int parse_blob_buffer(struct blob *item, void *buffer, unsigned long size)

builtin/blame.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2041,7 +2041,6 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
20412041
commit = alloc_commit_node();
20422042
commit->object.parsed = 1;
20432043
commit->date = now;
2044-
commit->object.type = OBJ_COMMIT;
20452044
parent_tail = &commit->parents;
20462045

20472046
if (!resolve_ref_unsafe("HEAD", head_sha1, 1, NULL))

builtin/diff-tree.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,7 @@ static int diff_tree_stdin(char *line)
7272
line[len-1] = 0;
7373
if (get_sha1_hex(line, sha1))
7474
return -1;
75-
obj = lookup_unknown_object(sha1);
76-
if (!obj || !obj->parsed)
77-
obj = parse_object(sha1);
75+
obj = parse_object(sha1);
7876
if (!obj)
7977
return -1;
8078
if (obj->type == OBJ_COMMIT)

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1354,6 +1354,7 @@ extern void *alloc_commit_node(void);
13541354
extern void *alloc_tag_node(void);
13551355
extern void *alloc_object_node(void);
13561356
extern void alloc_report(void);
1357+
extern unsigned int alloc_commit_index(void);
13571358

13581359
/* trace.c */
13591360
__attribute__((format (printf, 1, 2)))

commit.c

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,14 @@ int save_commit_buffer = 1;
1818

1919
const char *commit_type = "commit";
2020

21-
static struct commit *check_commit(struct object *obj,
22-
const unsigned char *sha1,
23-
int quiet)
24-
{
25-
if (obj->type != OBJ_COMMIT) {
26-
if (!quiet)
27-
error("Object %s is a %s, not a commit",
28-
sha1_to_hex(sha1), typename(obj->type));
29-
return NULL;
30-
}
31-
return (struct commit *) obj;
32-
}
33-
3421
struct commit *lookup_commit_reference_gently(const unsigned char *sha1,
3522
int quiet)
3623
{
3724
struct object *obj = deref_tag(parse_object(sha1), NULL, 0);
3825

3926
if (!obj)
4027
return NULL;
41-
return check_commit(obj, sha1, quiet);
28+
return object_as_type(obj, OBJ_COMMIT, quiet);
4229
}
4330

4431
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
6148
struct commit *lookup_commit(const unsigned char *sha1)
6249
{
6350
struct object *obj = lookup_object(sha1);
64-
if (!obj) {
65-
struct commit *c = alloc_commit_node();
66-
return create_object(sha1, OBJ_COMMIT, c);
67-
}
68-
if (!obj->type)
69-
obj->type = OBJ_COMMIT;
70-
return check_commit(obj, sha1, 0);
51+
if (!obj)
52+
return create_object(sha1, alloc_commit_node());
53+
return object_as_type(obj, OBJ_COMMIT, 0);
7154
}
7255

7356
struct commit *lookup_commit_reference_by_name(const char *name)

object.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,12 @@ static void grow_object_hash(void)
141141
obj_hash_size = new_hash_size;
142142
}
143143

144-
void *create_object(const unsigned char *sha1, int type, void *o)
144+
void *create_object(const unsigned char *sha1, void *o)
145145
{
146146
struct object *obj = o;
147147

148148
obj->parsed = 0;
149149
obj->used = 0;
150-
obj->type = type;
151150
obj->flags = 0;
152151
hashcpy(obj->sha1, sha1);
153152

@@ -159,11 +158,30 @@ void *create_object(const unsigned char *sha1, int type, void *o)
159158
return obj;
160159
}
161160

161+
void *object_as_type(struct object *obj, enum object_type type, int quiet)
162+
{
163+
if (obj->type == type)
164+
return obj;
165+
else if (obj->type == OBJ_NONE) {
166+
if (type == OBJ_COMMIT)
167+
((struct commit *)obj)->index = alloc_commit_index();
168+
obj->type = type;
169+
return obj;
170+
}
171+
else {
172+
if (!quiet)
173+
error("object %s is a %s, not a %s",
174+
sha1_to_hex(obj->sha1),
175+
typename(obj->type), typename(type));
176+
return NULL;
177+
}
178+
}
179+
162180
struct object *lookup_unknown_object(const unsigned char *sha1)
163181
{
164182
struct object *obj = lookup_object(sha1);
165183
if (!obj)
166-
obj = create_object(sha1, OBJ_NONE, alloc_object_node());
184+
obj = create_object(sha1, alloc_object_node());
167185
return obj;
168186
}
169187

@@ -214,8 +232,6 @@ struct object *parse_object_buffer(const unsigned char *sha1, enum object_type t
214232
warning("object %s has unknown type id %d", sha1_to_hex(sha1), type);
215233
obj = NULL;
216234
}
217-
if (obj && obj->type == OBJ_NONE)
218-
obj->type = type;
219235
return obj;
220236
}
221237

object.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ extern struct object *get_indexed_object(unsigned int);
7979
*/
8080
struct object *lookup_object(const unsigned char *sha1);
8181

82-
extern void *create_object(const unsigned char *sha1, int type, void *obj);
82+
extern void *create_object(const unsigned char *sha1, void *obj);
83+
84+
void *object_as_type(struct object *obj, enum object_type type, int quiet);
8385

8486
/*
8587
* Returns the object, having parsed it to find out what it is.

refs.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1520,9 +1520,8 @@ static enum peel_status peel_object(const unsigned char *name, unsigned char *sh
15201520

15211521
if (o->type == OBJ_NONE) {
15221522
int type = sha1_object_info(name, NULL);
1523-
if (type < 0)
1523+
if (type < 0 || !object_as_type(o, type, 0))
15241524
return PEEL_INVALID;
1525-
o->type = type;
15261525
}
15271526

15281527
if (o->type != OBJ_TAG)

tag.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,8 @@ struct tag *lookup_tag(const unsigned char *sha1)
4040
{
4141
struct object *obj = lookup_object(sha1);
4242
if (!obj)
43-
return create_object(sha1, OBJ_TAG, alloc_tag_node());
44-
if (!obj->type)
45-
obj->type = OBJ_TAG;
46-
if (obj->type != OBJ_TAG) {
47-
error("Object %s is a %s, not a tag",
48-
sha1_to_hex(sha1), typename(obj->type));
49-
return NULL;
50-
}
51-
return (struct tag *) obj;
43+
return create_object(sha1, alloc_tag_node());
44+
return object_as_type(obj, OBJ_TAG, 0);
5245
}
5346

5447
static unsigned long parse_tag_date(const char *buf, const char *tail)

tree.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,8 @@ struct tree *lookup_tree(const unsigned char *sha1)
183183
{
184184
struct object *obj = lookup_object(sha1);
185185
if (!obj)
186-
return create_object(sha1, OBJ_TREE, alloc_tree_node());
187-
if (!obj->type)
188-
obj->type = OBJ_TREE;
189-
if (obj->type != OBJ_TREE) {
190-
error("Object %s is a %s, not a tree",
191-
sha1_to_hex(sha1), typename(obj->type));
192-
return NULL;
193-
}
194-
return (struct tree *) obj;
186+
return create_object(sha1, alloc_tree_node());
187+
return object_as_type(obj, OBJ_TREE, 0);
195188
}
196189

197190
int parse_tree_buffer(struct tree *item, void *buffer, unsigned long size)

0 commit comments

Comments
 (0)