Skip to content

Commit 885a86a

Browse files
Linus TorvaldsJunio C Hamano
authored andcommitted
Shrink "struct object" a bit
This shrinks "struct object" by a small amount, by getting rid of the "struct type *" pointer and replacing it with a 3-bit bitfield instead. In addition, we merge the bitfields and the "flags" field, which incidentally should also remove a useless 4-byte padding from the object when in 64-bit mode. Now, our "struct object" is still too damn large, but it's now less obviously bloated, and of the remaining fields, only the "util" (which is not used by most things) is clearly something that should be eventually discarded. This shrinks the "git-rev-list --all" memory use by about 2.5% on the kernel archive (and, perhaps more importantly, on the larger mozilla archive). That may not sound like much, but I suspect it's more on a 64-bit platform. There are other remaining inefficiencies (the parent lists, for example, probably have horrible malloc overhead), but this was pretty obvious. Most of the patch is just changing the comparison of the "type" pointer from one of the constant string pointers to the appropriate new TYPE_xxx small integer constant. Signed-off-by: Linus Torvalds <torvalds@osdl.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 210a0be commit 885a86a

21 files changed

+113
-96
lines changed

blob.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ struct blob *lookup_blob(const unsigned char *sha1)
1010
if (!obj) {
1111
struct blob *ret = xcalloc(1, sizeof(struct blob));
1212
created_object(sha1, &ret->object);
13-
ret->object.type = blob_type;
13+
ret->object.type = TYPE_BLOB;
1414
return ret;
1515
}
1616
if (!obj->type)
17-
obj->type = blob_type;
18-
if (obj->type != blob_type) {
19-
error("Object %s is a %s, not a blob",
20-
sha1_to_hex(sha1), obj->type);
17+
obj->type = TYPE_BLOB;
18+
if (obj->type != TYPE_BLOB) {
19+
error("Object %s is a %s, not a blob",
20+
sha1_to_hex(sha1), typename(obj->type));
2121
return NULL;
2222
}
2323
return (struct blob *) obj;

builtin-diff.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,9 @@ int cmd_diff(int argc, const char **argv, char **envp)
303303
obj = deref_tag(obj, NULL, 0);
304304
if (!obj)
305305
die("invalid object '%s' given.", name);
306-
if (!strcmp(obj->type, commit_type))
306+
if (obj->type == TYPE_COMMIT)
307307
obj = &((struct commit *)obj)->tree->object;
308-
if (!strcmp(obj->type, tree_type)) {
308+
if (obj->type == TYPE_TREE) {
309309
if (ARRAY_SIZE(ent) <= ents)
310310
die("more than %d trees given: '%s'",
311311
(int) ARRAY_SIZE(ent), name);
@@ -315,7 +315,7 @@ int cmd_diff(int argc, const char **argv, char **envp)
315315
ents++;
316316
continue;
317317
}
318-
if (!strcmp(obj->type, blob_type)) {
318+
if (obj->type == TYPE_BLOB) {
319319
if (2 <= blobs)
320320
die("more than two blobs given: '%s'", name);
321321
memcpy(blob[blobs].sha1, obj->sha1, 20);

builtin-grep.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -630,10 +630,9 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
630630
static int grep_object(struct grep_opt *opt, const char **paths,
631631
struct object *obj, const char *name)
632632
{
633-
if (!strcmp(obj->type, blob_type))
633+
if (obj->type == TYPE_BLOB)
634634
return grep_sha1(opt, obj->sha1, name);
635-
if (!strcmp(obj->type, commit_type) ||
636-
!strcmp(obj->type, tree_type)) {
635+
if (obj->type == TYPE_COMMIT || obj->type == TYPE_TREE) {
637636
struct tree_desc tree;
638637
void *data;
639638
int hit;
@@ -646,7 +645,7 @@ static int grep_object(struct grep_opt *opt, const char **paths,
646645
free(data);
647646
return hit;
648647
}
649-
die("unable to grep from object of type %s", obj->type);
648+
die("unable to grep from object of type %s", typename(obj->type));
650649
}
651650

652651
static const char builtin_grep_usage[] =

builtin-rev-list.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,16 @@ static void show_commit_list(struct rev_info *revs)
158158
const char *name = pending->name;
159159
if (obj->flags & (UNINTERESTING | SEEN))
160160
continue;
161-
if (obj->type == tag_type) {
161+
if (obj->type == TYPE_TAG) {
162162
obj->flags |= SEEN;
163163
p = add_object(obj, p, NULL, name);
164164
continue;
165165
}
166-
if (obj->type == tree_type) {
166+
if (obj->type == TYPE_TREE) {
167167
p = process_tree((struct tree *)obj, p, NULL, name);
168168
continue;
169169
}
170-
if (obj->type == blob_type) {
170+
if (obj->type == TYPE_BLOB) {
171171
p = process_blob((struct blob *)obj, p, NULL, name);
172172
continue;
173173
}

builtin-show-branch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ static const char **default_arg = NULL;
1515
#define UNINTERESTING 01
1616

1717
#define REV_SHIFT 2
18-
#define MAX_REVS 29 /* should not exceed bits_per_int - REV_SHIFT */
18+
#define MAX_REVS (FLAG_BITS - REV_SHIFT) /* should not exceed bits_per_int - REV_SHIFT */
1919

2020
static struct commit *interesting(struct commit_list *list)
2121
{

commit.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ static struct commit *check_commit(struct object *obj,
5656
const unsigned char *sha1,
5757
int quiet)
5858
{
59-
if (obj->type != commit_type) {
59+
if (obj->type != TYPE_COMMIT) {
6060
if (!quiet)
6161
error("Object %s is a %s, not a commit",
62-
sha1_to_hex(sha1), obj->type);
62+
sha1_to_hex(sha1), typename(obj->type));
6363
return NULL;
6464
}
6565
return (struct commit *) obj;
@@ -86,11 +86,11 @@ struct commit *lookup_commit(const unsigned char *sha1)
8686
if (!obj) {
8787
struct commit *ret = xcalloc(1, sizeof(struct commit));
8888
created_object(sha1, &ret->object);
89-
ret->object.type = commit_type;
89+
ret->object.type = TYPE_COMMIT;
9090
return ret;
9191
}
9292
if (!obj->type)
93-
obj->type = commit_type;
93+
obj->type = TYPE_COMMIT;
9494
return check_commit(obj, sha1, 0);
9595
}
9696

describe.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static int get_name(const char *path, const unsigned char *sha1)
6767
* Otherwise only annotated tags are used.
6868
*/
6969
if (!strncmp(path, "refs/tags/", 10)) {
70-
if (object->type == tag_type)
70+
if (object->type == TYPE_TAG)
7171
prio = 2;
7272
else
7373
prio = 1;

fetch-pack.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static int rev_list_insert_ref(const char *path, const unsigned char *sha1)
4646
{
4747
struct object *o = deref_tag(parse_object(sha1), path, 0);
4848

49-
if (o && o->type == commit_type)
49+
if (o && o->type == TYPE_COMMIT)
5050
rev_list_push((struct commit *)o, SEEN);
5151

5252
return 0;
@@ -251,14 +251,14 @@ static int mark_complete(const char *path, const unsigned char *sha1)
251251
{
252252
struct object *o = parse_object(sha1);
253253

254-
while (o && o->type == tag_type) {
254+
while (o && o->type == TYPE_TAG) {
255255
struct tag *t = (struct tag *) o;
256256
if (!t->tagged)
257257
break; /* broken repository */
258258
o->flags |= COMPLETE;
259259
o = parse_object(t->tagged->sha1);
260260
}
261-
if (o && o->type == commit_type) {
261+
if (o && o->type == TYPE_COMMIT) {
262262
struct commit *commit = (struct commit *)o;
263263
commit->object.flags |= COMPLETE;
264264
insert_by_date(commit, &complete);
@@ -352,7 +352,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
352352
* in sync with the other side at some time after
353353
* that (it is OK if we guess wrong here).
354354
*/
355-
if (o->type == commit_type) {
355+
if (o->type == TYPE_COMMIT) {
356356
struct commit *commit = (struct commit *)o;
357357
if (!cutoff || cutoff < commit->date)
358358
cutoff = commit->date;
@@ -371,7 +371,7 @@ static int everything_local(struct ref **refs, int nr_match, char **match)
371371
struct object *o = deref_tag(lookup_object(ref->old_sha1),
372372
NULL, 0);
373373

374-
if (!o || o->type != commit_type || !(o->flags & COMPLETE))
374+
if (!o || o->type != TYPE_COMMIT || !(o->flags & COMPLETE))
375375
continue;
376376

377377
if (!(o->flags & SEEN)) {

fetch.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,27 +118,27 @@ static struct object_list **process_queue_end = &process_queue;
118118

119119
static int process_object(struct object *obj)
120120
{
121-
if (obj->type == commit_type) {
121+
if (obj->type == TYPE_COMMIT) {
122122
if (process_commit((struct commit *)obj))
123123
return -1;
124124
return 0;
125125
}
126-
if (obj->type == tree_type) {
126+
if (obj->type == TYPE_TREE) {
127127
if (process_tree((struct tree *)obj))
128128
return -1;
129129
return 0;
130130
}
131-
if (obj->type == blob_type) {
131+
if (obj->type == TYPE_BLOB) {
132132
return 0;
133133
}
134-
if (obj->type == tag_type) {
134+
if (obj->type == TYPE_TAG) {
135135
if (process_tag((struct tag *)obj))
136136
return -1;
137137
return 0;
138138
}
139139
return error("Unable to determine requirements "
140140
"of type %s for %s",
141-
obj->type, sha1_to_hex(obj->sha1));
141+
typename(obj->type), sha1_to_hex(obj->sha1));
142142
}
143143

144144
static int process(struct object *obj)
@@ -179,9 +179,7 @@ static int loop(void)
179179
*/
180180
if (! (obj->flags & TO_SCAN)) {
181181
if (fetch(obj->sha1)) {
182-
report_missing(obj->type
183-
? obj->type
184-
: "object", obj->sha1);
182+
report_missing(typename(obj->type), obj->sha1);
185183
return -1;
186184
}
187185
}

fsck-objects.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ static void objreport(struct object *obj, const char *severity,
3434
const char *err, va_list params)
3535
{
3636
fprintf(stderr, "%s in %s %s: ",
37-
severity, obj->type, sha1_to_hex(obj->sha1));
37+
severity, typename(obj->type), sha1_to_hex(obj->sha1));
3838
vfprintf(stderr, err, params);
3939
fputs("\n", stderr);
4040
}
@@ -74,7 +74,7 @@ static void check_connectivity(void)
7474
; /* it is in pack */
7575
else
7676
printf("missing %s %s\n",
77-
obj->type, sha1_to_hex(obj->sha1));
77+
typename(obj->type), sha1_to_hex(obj->sha1));
7878
continue;
7979
}
8080

@@ -87,20 +87,20 @@ static void check_connectivity(void)
8787
(has_sha1_file(ref->sha1)))
8888
continue;
8989
printf("broken link from %7s %s\n",
90-
obj->type, sha1_to_hex(obj->sha1));
90+
typename(obj->type), sha1_to_hex(obj->sha1));
9191
printf(" to %7s %s\n",
92-
ref->type, sha1_to_hex(ref->sha1));
92+
typename(ref->type), sha1_to_hex(ref->sha1));
9393
}
9494
}
9595

9696
if (show_unreachable && !(obj->flags & REACHABLE)) {
9797
printf("unreachable %s %s\n",
98-
obj->type, sha1_to_hex(obj->sha1));
98+
typename(obj->type), sha1_to_hex(obj->sha1));
9999
continue;
100100
}
101101

102102
if (!obj->used) {
103-
printf("dangling %s %s\n", obj->type,
103+
printf("dangling %s %s\n", typename(obj->type),
104104
sha1_to_hex(obj->sha1));
105105
}
106106
}
@@ -282,7 +282,7 @@ static int fsck_tag(struct tag *tag)
282282
if (!show_tags)
283283
return 0;
284284

285-
printf("tagged %s %s", tagged->type, sha1_to_hex(tagged->sha1));
285+
printf("tagged %s %s", typename(tagged->type), sha1_to_hex(tagged->sha1));
286286
printf(" (%s) in %s\n", tag->tag, sha1_to_hex(tag->object.sha1));
287287
return 0;
288288
}
@@ -295,16 +295,16 @@ static int fsck_sha1(unsigned char *sha1)
295295
if (obj->flags & SEEN)
296296
return 0;
297297
obj->flags |= SEEN;
298-
if (obj->type == blob_type)
298+
if (obj->type == TYPE_BLOB)
299299
return 0;
300-
if (obj->type == tree_type)
300+
if (obj->type == TYPE_TREE)
301301
return fsck_tree((struct tree *) obj);
302-
if (obj->type == commit_type)
302+
if (obj->type == TYPE_COMMIT)
303303
return fsck_commit((struct commit *) obj);
304-
if (obj->type == tag_type)
304+
if (obj->type == TYPE_TAG)
305305
return fsck_tag((struct tag *) obj);
306306
/* By now, parse_object() would've returned NULL instead. */
307-
return objerror(obj, "unknown type '%s' (internal fsck error)", obj->type);
307+
return objerror(obj, "unknown type '%d' (internal fsck error)", obj->type);
308308
}
309309

310310
/*
@@ -470,7 +470,7 @@ static int fsck_cache_tree(struct cache_tree *it)
470470
}
471471
mark_reachable(obj, REACHABLE);
472472
obj->used = 1;
473-
if (obj->type != tree_type)
473+
if (obj->type != TYPE_TREE)
474474
err |= objerror(obj, "non-tree in cache-tree");
475475
}
476476
for (i = 0; i < it->subtree_nr; i++)

0 commit comments

Comments
 (0)