Skip to content

Commit

Permalink
Merge branch 'jk/commit-buffer-length'
Browse files Browse the repository at this point in the history
Move "commit->buffer" out of the in-core commit object and keep
track of their lengths.  Use this to optimize the code paths to
validate GPG signatures in commit objects.

* jk/commit-buffer-length:
  reuse cached commit buffer when parsing signatures
  commit: record buffer length in cache
  commit: convert commit->buffer to a slab
  commit-slab: provide a static initializer
  use get_commit_buffer everywhere
  convert logmsg_reencode to get_commit_buffer
  use get_commit_buffer to avoid duplicate code
  use get_cached_commit_buffer where appropriate
  provide helpers to access the commit buffer
  provide a helper to set the commit buffer
  provide a helper to free commit buffer
  sequencer: use logmsg_reencode in get_message
  logmsg_reencode: return const buffer
  do not create "struct commit" with xcalloc
  commit: push commit_index update into alloc_commit_node
  alloc: include any-object allocations in alloc_report
  replace dangerous uses of strbuf_attach
  commit_tree: take a pointer/len pair rather than a const strbuf
  • Loading branch information
Junio C Hamano committed Jul 2, 2014
2 parents 95acfc2 + 218aa3a commit 8061ae8
Show file tree
Hide file tree
Showing 27 changed files with 284 additions and 197 deletions.
23 changes: 16 additions & 7 deletions alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,32 @@ union any_object {

DEFINE_ALLOCATOR(blob, struct blob)
DEFINE_ALLOCATOR(tree, struct tree)
DEFINE_ALLOCATOR(commit, struct commit)
DEFINE_ALLOCATOR(raw_commit, struct commit)
DEFINE_ALLOCATOR(tag, struct tag)
DEFINE_ALLOCATOR(object, union any_object)

void *alloc_commit_node(void)
{
static int commit_count;
struct commit *c = alloc_raw_commit_node();
c->index = commit_count++;
return c;
}

static void report(const char *name, unsigned int count, size_t size)
{
fprintf(stderr, "%10s: %8u (%"PRIuMAX" kB)\n",
name, count, (uintmax_t) size);
}

#define REPORT(name) \
report(#name, name##_allocs, name##_allocs * sizeof(struct name) >> 10)
#define REPORT(name, type) \
report(#name, name##_allocs, name##_allocs * sizeof(type) >> 10)

void alloc_report(void)
{
REPORT(blob);
REPORT(tree);
REPORT(commit);
REPORT(tag);
REPORT(blob, struct blob);
REPORT(tree, struct tree);
REPORT(raw_commit, struct commit);
REPORT(tag, struct tag);
REPORT(object, union any_object);
}
22 changes: 17 additions & 5 deletions builtin/blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,7 @@ static void get_commit_info(struct commit *commit,
{
int len;
const char *subject, *encoding;
char *message;
const char *message;

commit_info_init(ret);

Expand All @@ -1666,7 +1666,7 @@ static void get_commit_info(struct commit *commit,
&ret->author_time, &ret->author_tz);

if (!detailed) {
logmsg_free(message, commit);
unuse_commit_buffer(commit, message);
return;
}

Expand All @@ -1680,7 +1680,7 @@ static void get_commit_info(struct commit *commit,
else
strbuf_addf(&ret->summary, "(%s)", sha1_to_hex(commit->object.sha1));

logmsg_free(message, commit);
unuse_commit_buffer(commit, message);
}

/*
Expand Down Expand Up @@ -2251,6 +2251,18 @@ static void append_merge_parents(struct commit_list **tail)
strbuf_release(&line);
}

/*
* This isn't as simple as passing sb->buf and sb->len, because we
* want to transfer ownership of the buffer to the commit (so we
* must use detach).
*/
static void set_commit_buffer_from_strbuf(struct commit *c, struct strbuf *sb)
{
size_t len;
void *buf = strbuf_detach(sb, &len);
set_commit_buffer(c, buf, len);
}

/*
* Prepare a dummy commit that represents the work tree (or staged) item.
* Note that annotating work tree item never works in the reverse.
Expand All @@ -2272,7 +2284,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
struct strbuf msg = STRBUF_INIT;

time(&now);
commit = xcalloc(1, sizeof(*commit));
commit = alloc_commit_node();
commit->object.parsed = 1;
commit->date = now;
commit->object.type = OBJ_COMMIT;
Expand All @@ -2299,7 +2311,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
ident, ident, path,
(!contents_from ? path :
(!strcmp(contents_from, "-") ? "standard input" : contents_from)));
commit->buffer = strbuf_detach(&msg, NULL);
set_commit_buffer_from_strbuf(commit, &msg);

if (!contents_from || strcmp("-", contents_from)) {
struct stat st;
Expand Down
4 changes: 2 additions & 2 deletions builtin/commit-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
die_errno("git commit-tree: failed to read");
}

if (commit_tree(&buffer, tree_sha1, parents, commit_sha1,
NULL, sign_commit)) {
if (commit_tree(buffer.buf, buffer.len, tree_sha1, parents,
commit_sha1, NULL, sign_commit)) {
strbuf_release(&buffer);
return 1;
}
Expand Down
4 changes: 2 additions & 2 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1745,8 +1745,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
append_merge_tag_headers(parents, &tail);
}

if (commit_tree_extended(&sb, active_cache_tree->sha1, parents, sha1,
author_ident.buf, sign_commit, extra)) {
if (commit_tree_extended(sb.buf, sb.len, active_cache_tree->sha1,
parents, sha1, author_ident.buf, sign_commit, extra)) {
rollback_index_files();
die(_("failed to write commit object"));
}
Expand Down
5 changes: 4 additions & 1 deletion builtin/fast-export.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ static const char *find_encoding(const char *begin, const char *end)
static void handle_commit(struct commit *commit, struct rev_info *rev)
{
int saved_output_format = rev->diffopt.output_format;
const char *commit_buffer;
const char *author, *author_end, *committer, *committer_end;
const char *encoding, *message;
char *reencoded = NULL;
Expand All @@ -291,7 +292,8 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
rev->diffopt.output_format = DIFF_FORMAT_CALLBACK;

parse_commit_or_die(commit);
author = strstr(commit->buffer, "\nauthor ");
commit_buffer = get_commit_buffer(commit, NULL);
author = strstr(commit_buffer, "\nauthor ");
if (!author)
die ("Could not find author in commit %s",
sha1_to_hex(commit->object.sha1));
Expand Down Expand Up @@ -338,6 +340,7 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
? strlen(message) : 0),
reencoded ? reencoded : message ? message : "");
free(reencoded);
unuse_commit_buffer(commit, commit_buffer);

for (i = 0, p = commit->parents; p; p = p->next) {
int mark = get_object_mark(&p->item->object);
Expand Down
5 changes: 4 additions & 1 deletion builtin/fmt-merge-msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,12 +230,14 @@ static void add_branch_desc(struct strbuf *out, const char *name)
static void record_person(int which, struct string_list *people,
struct commit *commit)
{
const char *buffer;
char *name_buf, *name, *name_end;
struct string_list_item *elem;
const char *field;

field = (which == 'a') ? "\nauthor " : "\ncommitter ";
name = strstr(commit->buffer, field);
buffer = get_commit_buffer(commit, NULL);
name = strstr(buffer, field);
if (!name)
return;
name += strlen(field);
Expand All @@ -247,6 +249,7 @@ static void record_person(int which, struct string_list *people,
if (name_end < name)
return;
name_buf = xmemdupz(name, name_end - name + 1);
unuse_commit_buffer(commit, buffer);

elem = string_list_lookup(people, name_buf);
if (!elem) {
Expand Down
3 changes: 1 addition & 2 deletions builtin/fsck.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,8 +310,7 @@ static int fsck_obj(struct object *obj)
if (obj->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *) obj;

free(commit->buffer);
commit->buffer = NULL;
free_commit_buffer(commit);

if (!commit->parents && show_root)
printf("root %s\n", sha1_to_hex(commit->object.sha1));
Expand Down
3 changes: 2 additions & 1 deletion builtin/index-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,8 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
}
if (obj->type == OBJ_COMMIT) {
struct commit *commit = (struct commit *) obj;
commit->buffer = NULL;
if (detach_commit_buffer(commit, NULL) != data)
die("BUG: parse_object_buffer transmogrified our buffer");
}
obj->flags |= FLAG_CHECKED;
}
Expand Down
13 changes: 7 additions & 6 deletions builtin/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,7 @@ static int cmd_log_walk(struct rev_info *rev)
rev->max_count++;
if (!rev->reflog_info) {
/* we allow cycles in reflog ancestry */
free(commit->buffer);
commit->buffer = NULL;
free_commit_buffer(commit);
}
free_commit_list(commit->parents);
commit->parents = NULL;
Expand Down Expand Up @@ -925,9 +924,12 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
log_write_email_headers(rev, head, &pp.subject, &pp.after_subject,
&need_8bit_cte);

for (i = 0; !need_8bit_cte && i < nr; i++)
if (has_non_ascii(list[i]->buffer))
for (i = 0; !need_8bit_cte && i < nr; i++) {
const char *buf = get_commit_buffer(list[i], NULL);
if (has_non_ascii(buf))
need_8bit_cte = 1;
unuse_commit_buffer(list[i], buf);
}

if (!branch_name)
branch_name = find_branch_name(rev);
Expand Down Expand Up @@ -1528,8 +1530,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
reopen_stdout(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
die(_("Failed to create output files"));
shown = log_tree_commit(&rev, commit);
free(commit->buffer);
commit->buffer = NULL;
free_commit_buffer(commit);

/* We put one extra blank line between formatted
* patches and this flag is used by log-tree code
Expand Down
8 changes: 4 additions & 4 deletions builtin/merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -852,8 +852,8 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
parent->next->item = remoteheads->item;
parent->next->next = NULL;
prepare_to_commit(remoteheads);
if (commit_tree(&merge_msg, result_tree, parent, result_commit, NULL,
sign_commit))
if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parent,
result_commit, NULL, sign_commit))
die(_("failed to write commit object"));
finish(head, remoteheads, result_commit, "In-index merge");
drop_save();
Expand All @@ -877,8 +877,8 @@ static int finish_automerge(struct commit *head,
commit_list_insert(head, &parents);
strbuf_addch(&merge_msg, '\n');
prepare_to_commit(remoteheads);
if (commit_tree(&merge_msg, result_tree, parents, result_commit,
NULL, sign_commit))
if (commit_tree(merge_msg.buf, merge_msg.len, result_tree, parents,
result_commit, NULL, sign_commit))
die(_("failed to write commit object"));
strbuf_addf(&buf, "Merge made by the '%s' strategy.", wt_strategy);
finish(head, remoteheads, result_commit, buf.buf);
Expand Down
4 changes: 2 additions & 2 deletions builtin/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ static int reset_index(const unsigned char *sha1, int reset_type, int quiet)
static void print_new_head_line(struct commit *commit)
{
const char *hex, *body;
char *msg;
const char *msg;

hex = find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV);
printf(_("HEAD is now at %s"), hex);
Expand All @@ -109,7 +109,7 @@ static void print_new_head_line(struct commit *commit)
}
else
printf("\n");
logmsg_free(msg, commit);
unuse_commit_buffer(commit, msg);
}

static void update_index_from_diff(struct diff_queue_struct *q,
Expand Down
5 changes: 2 additions & 3 deletions builtin/rev-list.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static void show_commit(struct commit *commit, void *data)
else
putchar('\n');

if (revs->verbose_header && commit->buffer) {
if (revs->verbose_header && get_cached_commit_buffer(commit, NULL)) {
struct strbuf buf = STRBUF_INIT;
struct pretty_print_context ctx = {0};
ctx.abbrev = revs->abbrev;
Expand Down Expand Up @@ -173,8 +173,7 @@ static void finish_commit(struct commit *commit, void *data)
free_commit_list(commit->parents);
commit->parents = NULL;
}
free(commit->buffer);
commit->buffer = NULL;
free_commit_buffer(commit);
}

static void finish_object(struct object *obj,
Expand Down
12 changes: 12 additions & 0 deletions commit-slab.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,16 @@ static int stat_ ##slabname## realloc
* catch because GCC silently parses it by default.
*/

/*
* Statically initialize a commit slab named "var". Note that this
* evaluates "stride" multiple times! Example:
*
* struct indegree indegrees = COMMIT_SLAB_INIT(1, indegrees);
*
*/
#define COMMIT_SLAB_INIT(stride, var) { \
COMMIT_SLAB_SIZE / sizeof(**((var).slab)) / (stride), \
(stride), 0, NULL \
}

#endif /* COMMIT_SLAB_H */
Loading

0 comments on commit 8061ae8

Please sign in to comment.