{"thread":{"id":"55075","subject":"[PATCH] alloc.h|c: migrate alloc_states to mem-pool","startedAt":"2021-01-30T13:00:16Z","lastAt":"2021-02-04T10:35:32Z","messageCount":8,"participants":["阿德烈 via GitGitGadget","René Scharfe","Junio C Hamano","胡哲宁","René Scharfe."],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"415654","messageId":"pull.857.git.1612011569489.gitgitgadget@gmail.com","threadId":"55075","inReplyTo":null,"subject":"[PATCH] alloc.h|c: migrate alloc_states to mem-pool","fromName":"阿德烈 via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-01-30T12:59:28Z","receivedAt":"2021-01-30T13:00:16Z","isPatch":true,"sender":{"key":"name:阿德烈","avatar":null},"body":"From: ZheNing Hu <adlternative@gmail.com>\n\n\"alloc_state\" may have similar effects with \"mem_pool\".\nUsing the new memory pool API may be more beneficial\nto our memory management in the future.\n\nSo I change them in the \"struct parsed_object_pool\",and\nThe corresponding interface has also been changed.\nfunctions \"alloc_*_node\" now change to \"mem_pool_alloc_*_node\".\n\nAt the same time ,I add the member `alloc_count` of\nstruct mem_pool ,so that we can effective track\nnode alloc count,and adapt to the original interface `alloc_report`.\n\nSigned-off-by: ZheNing Hu <adlternative@gmail.com>\n---\n    alloc.h|c: migrate alloc_states to mem-pool\n    \n    Notice that \"mem-pool\" api may have similar effort with alloc_state,\n    \"parsed_object_pool\" have five member with alloc_state type, and \"TODO\"\n    usage in \"object.h\":\"migrate alloc_states to mem-pool?\", so let us\n    change it to mem-pool version.\n    \n    After I learned the role of the memory pool,I think in the future git\n    may be more inclined to use the memory pool instead of the old interface\n    \"alloc_state\".\n    \n    Thanks.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-857%2Fadlternative%2Falloc_states_to_mem_pool-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-857/adlternative/alloc_states_to_mem_pool-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/857\n\n alloc.c           | 24 ++++++++++++------------\n alloc.h           | 10 +++++-----\n blame.c           |  2 +-\n blob.c            |  2 +-\n commit-graph.c    |  2 +-\n commit.c          |  2 +-\n mem-pool.c        |  6 ++++++\n mem-pool.h        |  8 ++++++++\n merge-recursive.c |  2 +-\n object.c          | 37 +++++++++++++++++++++----------------\n object.h          | 10 +++++-----\n tag.c             |  2 +-\n tree.c            |  2 +-\n 13 files changed, 64 insertions(+), 45 deletions(-)\n\ndiff --git a/alloc.c b/alloc.c\nindex 957a0af3626..951ef3e4ed7 100644\n--- a/alloc.c\n+++ b/alloc.c\n@@ -71,30 +71,30 @@ static inline void *alloc_node(struct alloc_state *s, size_t node_size)\n \treturn ret;\n }\n \n-void *alloc_blob_node(struct repository *r)\n+void *mem_pool_alloc_blob_node(struct repository *r)\n {\n-\tstruct blob *b = alloc_node(r->parsed_objects->blob_state, sizeof(struct blob));\n+\tstruct blob *b = mem_pool_calloc(r->parsed_objects->blob_pool, 1, sizeof(struct blob));\n \tb->object.type = OBJ_BLOB;\n \treturn b;\n }\n \n-void *alloc_tree_node(struct repository *r)\n+void *mem_pool_alloc_tree_node(struct repository *r)\n {\n-\tstruct tree *t = alloc_node(r->parsed_objects->tree_state, sizeof(struct tree));\n+\tstruct tree *t = mem_pool_calloc(r->parsed_objects->tree_pool, 1, sizeof(struct tree));\n \tt->object.type = OBJ_TREE;\n \treturn t;\n }\n \n-void *alloc_tag_node(struct repository *r)\n+void *mem_pool_alloc_tag_node(struct repository *r)\n {\n-\tstruct tag *t = alloc_node(r->parsed_objects->tag_state, sizeof(struct tag));\n+\tstruct tag *t = mem_pool_calloc(r->parsed_objects->tag_pool, 1, sizeof(struct tag));\n \tt->object.type = OBJ_TAG;\n \treturn t;\n }\n \n-void *alloc_object_node(struct repository *r)\n+void *mem_pool_alloc_object_node(struct repository *r)\n {\n-\tstruct object *obj = alloc_node(r->parsed_objects->object_state, sizeof(union any_object));\n+\tstruct object *obj = mem_pool_calloc(r->parsed_objects->object_pool, 1, sizeof(union any_object));\n \tobj->type = OBJ_NONE;\n \treturn obj;\n }\n@@ -116,9 +116,9 @@ void init_commit_node(struct commit *c)\n \tc->index = alloc_commit_index();\n }\n \n-void *alloc_commit_node(struct repository *r)\n+void *mem_pool_alloc_commit_node(struct repository *r)\n {\n-\tstruct commit *c = alloc_node(r->parsed_objects->commit_state, sizeof(struct commit));\n+\tstruct commit *c = mem_pool_calloc(r->parsed_objects->commit_pool, 1, sizeof(struct commit));\n \tinit_commit_node(c);\n \treturn c;\n }\n@@ -130,8 +130,8 @@ static void report(const char *name, unsigned int count, size_t size)\n }\n \n #define REPORT(name, type)\t\\\n-    report(#name, r->parsed_objects->name##_state->count, \\\n-\t\t  r->parsed_objects->name##_state->count * sizeof(type) >> 10)\n+    report(#name, r->parsed_objects->name##_pool->alloc_count, \\\n+\t\t  r->parsed_objects->name##_pool->alloc_count * sizeof(type) >> 10)\n \n void alloc_report(struct repository *r)\n {\ndiff --git a/alloc.h b/alloc.h\nindex 371d388b552..707b28b464e 100644\n--- a/alloc.h\n+++ b/alloc.h\n@@ -7,12 +7,12 @@ struct commit;\n struct tag;\n struct repository;\n \n-void *alloc_blob_node(struct repository *r);\n-void *alloc_tree_node(struct repository *r);\n+void *mem_pool_alloc_blob_node(struct repository *r);\n+void *mem_pool_alloc_tree_node(struct repository *r);\n void init_commit_node(struct commit *c);\n-void *alloc_commit_node(struct repository *r);\n-void *alloc_tag_node(struct repository *r);\n-void *alloc_object_node(struct repository *r);\n+void *mem_pool_alloc_commit_node(struct repository *r);\n+void *mem_pool_alloc_tag_node(struct repository *r);\n+void *mem_pool_alloc_object_node(struct repository *r);\n void alloc_report(struct repository *r);\n \n struct alloc_state *allocate_alloc_state(void);\ndiff --git a/blame.c b/blame.c\nindex a5044fcfaa6..cbb9d8316c1 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -192,7 +192,7 @@ static struct commit *fake_working_tree_commit(struct repository *r,\n \n \trepo_read_index(r);\n \ttime(&now);\n-\tcommit = alloc_commit_node(r);\n+\tcommit = mem_pool_alloc_commit_node(r);\n \tcommit->object.parsed = 1;\n \tcommit->date = now;\n \tparent_tail = &commit->parents;\ndiff --git a/blob.c b/blob.c\nindex 182718aba9f..787c7b2b016 100644\n--- a/blob.c\n+++ b/blob.c\n@@ -9,7 +9,7 @@ struct blob *lookup_blob(struct repository *r, const struct object_id *oid)\n {\n \tstruct object *obj = lookup_object(r, oid);\n \tif (!obj)\n-\t\treturn create_object(r, oid, alloc_blob_node(r));\n+\t\treturn create_object(r, oid, mem_pool_alloc_blob_node(r));\n \treturn object_as_type(obj, OBJ_BLOB, 0);\n }\n \ndiff --git a/commit-graph.c b/commit-graph.c\nindex 06f8dc1d896..edbcfd8a01e 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -2362,7 +2362,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)\n \t\thashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i);\n \n \t\tgraph_commit = lookup_commit(r, &cur_oid);\n-\t\todb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r));\n+\t\todb_commit = (struct commit *)create_object(r, &cur_oid, mem_pool_alloc_commit_node(r));\n \t\tif (parse_commit_internal(odb_commit, 0, 0)) {\n \t\t\tgraph_report(_(\"failed to parse commit %s from object database for commit-graph\"),\n \t\t\t\t     oid_to_hex(&cur_oid));\ndiff --git a/commit.c b/commit.c\nindex fe1fa3dc41f..96d06737409 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -61,7 +61,7 @@ struct commit *lookup_commit(struct repository *r, const struct object_id *oid)\n {\n \tstruct object *obj = lookup_object(r, oid);\n \tif (!obj)\n-\t\treturn create_object(r, oid, alloc_commit_node(r));\n+\t\treturn create_object(r, oid, mem_pool_alloc_commit_node(r));\n \treturn object_as_type(obj, OBJ_COMMIT, 0);\n }\n \ndiff --git a/mem-pool.c b/mem-pool.c\nindex 8401761dda0..d7bae84a982 100644\n--- a/mem-pool.c\n+++ b/mem-pool.c\n@@ -35,6 +35,11 @@ static struct mp_block *mem_pool_alloc_block(struct mem_pool *pool,\n \treturn p;\n }\n \n+struct mem_pool *mem_pool_new(void)\n+{\n+\treturn xmalloc(sizeof(struct mem_pool));\n+}\n+\n void mem_pool_init(struct mem_pool *pool, size_t initial_size)\n {\n \tmemset(pool, 0, sizeof(*pool));\n@@ -69,6 +74,7 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len)\n \tstruct mp_block *p = NULL;\n \tvoid *r;\n \n+\tpool->alloc_count++;\n \t/* round up to a 'uintmax_t' alignment */\n \tif (len & (sizeof(uintmax_t) - 1))\n \t\tlen += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));\ndiff --git a/mem-pool.h b/mem-pool.h\nindex fe7507f022b..64529e136cf 100644\n--- a/mem-pool.h\n+++ b/mem-pool.h\n@@ -19,8 +19,16 @@ struct mem_pool {\n \n \t/* The total amount of memory allocated by the pool. */\n \tsize_t pool_alloc;\n+\n+\t/* The count of calling mem_pool_alloc .*/\n+\tsize_t alloc_count;\n };\n \n+/*\n+ * Create a new mem_pool.\n+ */\n+struct mem_pool *mem_pool_new(void);\n+\n /*\n  * Initialize mem_pool with specified initial size.\n  */\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex f736a0f6323..62ef4e7b688 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -216,7 +216,7 @@ static struct commit *make_virtual_commit(struct repository *repo,\n \t\t\t\t\t  struct tree *tree,\n \t\t\t\t\t  const char *comment)\n {\n-\tstruct commit *commit = alloc_commit_node(repo);\n+\tstruct commit *commit = mem_pool_alloc_commit_node(repo);\n \n \tset_merge_remote_desc(commit, comment, (struct object *)commit);\n \tset_commit_tree(commit, tree);\ndiff --git a/object.c b/object.c\nindex 68f80b0b3d8..241933f6c88 100644\n--- a/object.c\n+++ b/object.c\n@@ -182,7 +182,7 @@ struct object *lookup_unknown_object(const struct object_id *oid)\n \tstruct object *obj = lookup_object(the_repository, oid);\n \tif (!obj)\n \t\tobj = create_object(the_repository, oid,\n-\t\t\t\t    alloc_object_node(the_repository));\n+\t\t\t\tmem_pool_alloc_object_node(the_repository));\n \treturn obj;\n }\n \n@@ -469,11 +469,16 @@ struct parsed_object_pool *parsed_object_pool_new(void)\n \tstruct parsed_object_pool *o = xmalloc(sizeof(*o));\n \tmemset(o, 0, sizeof(*o));\n \n-\to->blob_state = allocate_alloc_state();\n-\to->tree_state = allocate_alloc_state();\n-\to->commit_state = allocate_alloc_state();\n-\to->tag_state = allocate_alloc_state();\n-\to->object_state = allocate_alloc_state();\n+\to->blob_pool = mem_pool_new();\n+\to->tree_pool = mem_pool_new();\n+\to->commit_pool = mem_pool_new();\n+\to->tag_pool = mem_pool_new();\n+\to->object_pool = mem_pool_new();\n+\tmem_pool_init(o->blob_pool,0);\n+\tmem_pool_init(o->tree_pool,0);\n+\tmem_pool_init(o->commit_pool,0);\n+\tmem_pool_init(o->tag_pool,0);\n+\tmem_pool_init(o->object_pool,0);\n \n \to->is_shallow = -1;\n \to->shallow_stat = xcalloc(1, sizeof(*o->shallow_stat));\n@@ -566,16 +571,16 @@ void parsed_object_pool_clear(struct parsed_object_pool *o)\n \tfree_commit_buffer_slab(o->buffer_slab);\n \to->buffer_slab = NULL;\n \n-\tclear_alloc_state(o->blob_state);\n-\tclear_alloc_state(o->tree_state);\n-\tclear_alloc_state(o->commit_state);\n-\tclear_alloc_state(o->tag_state);\n-\tclear_alloc_state(o->object_state);\n+\tmem_pool_discard(o->blob_pool,1);\n+\tmem_pool_discard(o->tree_pool,1);\n+\tmem_pool_discard(o->tag_pool,1);\n+\tmem_pool_discard(o->object_pool,1);\n+\tmem_pool_discard(o->commit_pool,1);\n \tstat_validity_clear(o->shallow_stat);\n-\tFREE_AND_NULL(o->blob_state);\n-\tFREE_AND_NULL(o->tree_state);\n-\tFREE_AND_NULL(o->commit_state);\n-\tFREE_AND_NULL(o->tag_state);\n-\tFREE_AND_NULL(o->object_state);\n+\tFREE_AND_NULL(o->blob_pool);\n+\tFREE_AND_NULL(o->tree_pool);\n+\tFREE_AND_NULL(o->commit_pool);\n+\tFREE_AND_NULL(o->tag_pool);\n+\tFREE_AND_NULL(o->object_pool);\n \tFREE_AND_NULL(o->shallow_stat);\n }\ndiff --git a/object.h b/object.h\nindex 59daadce214..43031d8dc04 100644\n--- a/object.h\n+++ b/object.h\n@@ -10,11 +10,11 @@ struct parsed_object_pool {\n \tint nr_objs, obj_hash_size;\n \n \t/* TODO: migrate alloc_states to mem-pool? */\n-\tstruct alloc_state *blob_state;\n-\tstruct alloc_state *tree_state;\n-\tstruct alloc_state *commit_state;\n-\tstruct alloc_state *tag_state;\n-\tstruct alloc_state *object_state;\n+\tstruct mem_pool *blob_pool;\n+\tstruct mem_pool *tree_pool;\n+\tstruct mem_pool *commit_pool;\n+\tstruct mem_pool *tag_pool;\n+\tstruct mem_pool *object_pool;\n \n \t/* parent substitutions from .git/info/grafts and .git/shallow */\n \tstruct commit_graft **grafts;\ndiff --git a/tag.c b/tag.c\nindex 1ed2684e45b..de24b6308b4 100644\n--- a/tag.c\n+++ b/tag.c\n@@ -102,7 +102,7 @@ struct tag *lookup_tag(struct repository *r, const struct object_id *oid)\n {\n \tstruct object *obj = lookup_object(r, oid);\n \tif (!obj)\n-\t\treturn create_object(r, oid, alloc_tag_node(r));\n+\t\treturn create_object(r, oid, mem_pool_alloc_tag_node(r));\n \treturn object_as_type(obj, OBJ_TAG, 0);\n }\n \ndiff --git a/tree.c b/tree.c\nindex e76517f6b18..7d61ae942e6 100644\n--- a/tree.c\n+++ b/tree.c\n@@ -199,7 +199,7 @@ struct tree *lookup_tree(struct repository *r, const struct object_id *oid)\n {\n \tstruct object *obj = lookup_object(r, oid);\n \tif (!obj)\n-\t\treturn create_object(r, oid, alloc_tree_node(r));\n+\t\treturn create_object(r, oid, mem_pool_alloc_tree_node(r));\n \treturn object_as_type(obj, OBJ_TREE, 0);\n }\n \n\nbase-commit: 6d3ef5b467eccd2769f1aa1c555d317d3c8dc707\n-- \ngitgitgadget\n"},{"id":"415730","messageId":"pull.857.v2.git.1612175966786.gitgitgadget@gmail.com","threadId":"55075","inReplyTo":"pull.857.git.1612011569489.gitgitgadget@gmail.com","subject":"[PATCH v2] alloc.h|c: migrate alloc_states to mem-pool","fromName":"阿德烈 via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-02-01T10:39:26Z","receivedAt":"2021-02-01T10:45:05Z","isPatch":true,"sender":{"key":"name:阿德烈","avatar":null},"body":"From: ZheNing Hu <adlternative@gmail.com>\n\n\"alloc_state\" may have similar effects with \"mem_pool\".\nUsing the new memory pool API may be more beneficial\nto our memory management in the future.\n\nSo I change them in the \"struct parsed_object_pool\",and\nThe corresponding interface has also been changed.\nfunctions \"alloc_*_node\" now change to \"mem_pool_alloc_*_node\".\n\nAt the same time ,I add the member `alloc_count` of\nstruct mem_pool ,so that we can effective track\nnode alloc count,and adapt to the original interface `alloc_report`.\n\nSigned-off-by: ZheNing Hu <adlternative@gmail.com>\n---\n    object.h: migrate alloc_states to mem-pool\n    \n    Notice that \"mem-pool\" api may have similar effort with alloc_state,\n    \"parsed_object_pool\" have five member with alloc_state type, and \"TODO\"\n    usage in \"object.h\":\"migrate alloc_states to mem-pool?\", so let us\n    change it to mem-pool version.\n    \n    After I learned the role of the memory pool,I think in the future git\n    may be more inclined to use the memory pool instead of the old interface\n    \"alloc_state\".\n    \n    Thanks.\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-857%2Fadlternative%2Falloc_states_to_mem_pool-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-857/adlternative/alloc_states_to_mem_pool-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/857\n\nRange-diff vs v1:\n\n 1:  3adcd229be7 ! 1:  e9c1f9eef42 alloc.h|c: migrate alloc_states to mem-pool\n     @@ mem-pool.h: struct mem_pool {\n        * Initialize mem_pool with specified initial size.\n        */\n      \n     + ## merge-ort.c ##\n     +@@ merge-ort.c: static struct commit *make_virtual_commit(struct repository *repo,\n     + \t\t\t\t\t  struct tree *tree,\n     + \t\t\t\t\t  const char *comment)\n     + {\n     +-\tstruct commit *commit = alloc_commit_node(repo);\n     ++\tstruct commit *commit = mem_pool_alloc_commit_node(repo);\n     + \n     + \tset_merge_remote_desc(commit, comment, (struct object *)commit);\n     + \tset_commit_tree(commit, tree);\n     +\n       ## merge-recursive.c ##\n      @@ merge-recursive.c: static struct commit *make_virtual_commit(struct repository *repo,\n       \t\t\t\t\t  struct tree *tree,\n\n\n alloc.c           | 24 ++++++++++++------------\n alloc.h           | 10 +++++-----\n blame.c           |  2 +-\n blob.c            |  2 +-\n commit-graph.c    |  2 +-\n commit.c          |  2 +-\n mem-pool.c        |  6 ++++++\n mem-pool.h        |  8 ++++++++\n merge-ort.c       |  2 +-\n merge-recursive.c |  2 +-\n object.c          | 37 +++++++++++++++++++++----------------\n object.h          | 10 +++++-----\n tag.c             |  2 +-\n tree.c            |  2 +-\n 14 files changed, 65 insertions(+), 46 deletions(-)\n\ndiff --git a/alloc.c b/alloc.c\nindex 957a0af3626..951ef3e4ed7 100644\n--- a/alloc.c\n+++ b/alloc.c\n@@ -71,30 +71,30 @@ static inline void *alloc_node(struct alloc_state *s, size_t node_size)\n \treturn ret;\n }\n \n-void *alloc_blob_node(struct repository *r)\n+void *mem_pool_alloc_blob_node(struct repository *r)\n {\n-\tstruct blob *b = alloc_node(r->parsed_objects->blob_state, sizeof(struct blob));\n+\tstruct blob *b = mem_pool_calloc(r->parsed_objects->blob_pool, 1, sizeof(struct blob));\n \tb->object.type = OBJ_BLOB;\n \treturn b;\n }\n \n-void *alloc_tree_node(struct repository *r)\n+void *mem_pool_alloc_tree_node(struct repository *r)\n {\n-\tstruct tree *t = alloc_node(r->parsed_objects->tree_state, sizeof(struct tree));\n+\tstruct tree *t = mem_pool_calloc(r->parsed_objects->tree_pool, 1, sizeof(struct tree));\n \tt->object.type = OBJ_TREE;\n \treturn t;\n }\n \n-void *alloc_tag_node(struct repository *r)\n+void *mem_pool_alloc_tag_node(struct repository *r)\n {\n-\tstruct tag *t = alloc_node(r->parsed_objects->tag_state, sizeof(struct tag));\n+\tstruct tag *t = mem_pool_calloc(r->parsed_objects->tag_pool, 1, sizeof(struct tag));\n \tt->object.type = OBJ_TAG;\n \treturn t;\n }\n \n-void *alloc_object_node(struct repository *r)\n+void *mem_pool_alloc_object_node(struct repository *r)\n {\n-\tstruct object *obj = alloc_node(r->parsed_objects->object_state, sizeof(union any_object));\n+\tstruct object *obj = mem_pool_calloc(r->parsed_objects->object_pool, 1, sizeof(union any_object));\n \tobj->type = OBJ_NONE;\n \treturn obj;\n }\n@@ -116,9 +116,9 @@ void init_commit_node(struct commit *c)\n \tc->index = alloc_commit_index();\n }\n \n-void *alloc_commit_node(struct repository *r)\n+void *mem_pool_alloc_commit_node(struct repository *r)\n {\n-\tstruct commit *c = alloc_node(r->parsed_objects->commit_state, sizeof(struct commit));\n+\tstruct commit *c = mem_pool_calloc(r->parsed_objects->commit_pool, 1, sizeof(struct commit));\n \tinit_commit_node(c);\n \treturn c;\n }\n@@ -130,8 +130,8 @@ static void report(const char *name, unsigned int count, size_t size)\n }\n \n #define REPORT(name, type)\t\\\n-    report(#name, r->parsed_objects->name##_state->count, \\\n-\t\t  r->parsed_objects->name##_state->count * sizeof(type) >> 10)\n+    report(#name, r->parsed_objects->name##_pool->alloc_count, \\\n+\t\t  r->parsed_objects->name##_pool->alloc_count * sizeof(type) >> 10)\n \n void alloc_report(struct repository *r)\n {\ndiff --git a/alloc.h b/alloc.h\nindex 371d388b552..707b28b464e 100644\n--- a/alloc.h\n+++ b/alloc.h\n@@ -7,12 +7,12 @@ struct commit;\n struct tag;\n struct repository;\n \n-void *alloc_blob_node(struct repository *r);\n-void *alloc_tree_node(struct repository *r);\n+void *mem_pool_alloc_blob_node(struct repository *r);\n+void *mem_pool_alloc_tree_node(struct repository *r);\n void init_commit_node(struct commit *c);\n-void *alloc_commit_node(struct repository *r);\n-void *alloc_tag_node(struct repository *r);\n-void *alloc_object_node(struct repository *r);\n+void *mem_pool_alloc_commit_node(struct repository *r);\n+void *mem_pool_alloc_tag_node(struct repository *r);\n+void *mem_pool_alloc_object_node(struct repository *r);\n void alloc_report(struct repository *r);\n \n struct alloc_state *allocate_alloc_state(void);\ndiff --git a/blame.c b/blame.c\nindex a5044fcfaa6..cbb9d8316c1 100644\n--- a/blame.c\n+++ b/blame.c\n@@ -192,7 +192,7 @@ static struct commit *fake_working_tree_commit(struct repository *r,\n \n \trepo_read_index(r);\n \ttime(&now);\n-\tcommit = alloc_commit_node(r);\n+\tcommit = mem_pool_alloc_commit_node(r);\n \tcommit->object.parsed = 1;\n \tcommit->date = now;\n \tparent_tail = &commit->parents;\ndiff --git a/blob.c b/blob.c\nindex 182718aba9f..787c7b2b016 100644\n--- a/blob.c\n+++ b/blob.c\n@@ -9,7 +9,7 @@ struct blob *lookup_blob(struct repository *r, const struct object_id *oid)\n {\n \tstruct object *obj = lookup_object(r, oid);\n \tif (!obj)\n-\t\treturn create_object(r, oid, alloc_blob_node(r));\n+\t\treturn create_object(r, oid, mem_pool_alloc_blob_node(r));\n \treturn object_as_type(obj, OBJ_BLOB, 0);\n }\n \ndiff --git a/commit-graph.c b/commit-graph.c\nindex f3486ec18f1..216d770eeb9 100644\n--- a/commit-graph.c\n+++ b/commit-graph.c\n@@ -2362,7 +2362,7 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)\n \t\thashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i);\n \n \t\tgraph_commit = lookup_commit(r, &cur_oid);\n-\t\todb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r));\n+\t\todb_commit = (struct commit *)create_object(r, &cur_oid, mem_pool_alloc_commit_node(r));\n \t\tif (parse_commit_internal(odb_commit, 0, 0)) {\n \t\t\tgraph_report(_(\"failed to parse commit %s from object database for commit-graph\"),\n \t\t\t\t     oid_to_hex(&cur_oid));\ndiff --git a/commit.c b/commit.c\nindex bab8d5ab07c..cd9cd8f94f9 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -61,7 +61,7 @@ struct commit *lookup_commit(struct repository *r, const struct object_id *oid)\n {\n \tstruct object *obj = lookup_object(r, oid);\n \tif (!obj)\n-\t\treturn create_object(r, oid, alloc_commit_node(r));\n+\t\treturn create_object(r, oid, mem_pool_alloc_commit_node(r));\n \treturn object_as_type(obj, OBJ_COMMIT, 0);\n }\n \ndiff --git a/mem-pool.c b/mem-pool.c\nindex 8401761dda0..d7bae84a982 100644\n--- a/mem-pool.c\n+++ b/mem-pool.c\n@@ -35,6 +35,11 @@ static struct mp_block *mem_pool_alloc_block(struct mem_pool *pool,\n \treturn p;\n }\n \n+struct mem_pool *mem_pool_new(void)\n+{\n+\treturn xmalloc(sizeof(struct mem_pool));\n+}\n+\n void mem_pool_init(struct mem_pool *pool, size_t initial_size)\n {\n \tmemset(pool, 0, sizeof(*pool));\n@@ -69,6 +74,7 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len)\n \tstruct mp_block *p = NULL;\n \tvoid *r;\n \n+\tpool->alloc_count++;\n \t/* round up to a 'uintmax_t' alignment */\n \tif (len & (sizeof(uintmax_t) - 1))\n \t\tlen += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));\ndiff --git a/mem-pool.h b/mem-pool.h\nindex fe7507f022b..64529e136cf 100644\n--- a/mem-pool.h\n+++ b/mem-pool.h\n@@ -19,8 +19,16 @@ struct mem_pool {\n \n \t/* The total amount of memory allocated by the pool. */\n \tsize_t pool_alloc;\n+\n+\t/* The count of calling mem_pool_alloc .*/\n+\tsize_t alloc_count;\n };\n \n+/*\n+ * Create a new mem_pool.\n+ */\n+struct mem_pool *mem_pool_new(void);\n+\n /*\n  * Initialize mem_pool with specified initial size.\n  */\ndiff --git a/merge-ort.c b/merge-ort.c\nindex d36a92b59b7..880a300c35c 100644\n--- a/merge-ort.c\n+++ b/merge-ort.c\n@@ -1774,7 +1774,7 @@ static struct commit *make_virtual_commit(struct repository *repo,\n \t\t\t\t\t  struct tree *tree,\n \t\t\t\t\t  const char *comment)\n {\n-\tstruct commit *commit = alloc_commit_node(repo);\n+\tstruct commit *commit = mem_pool_alloc_commit_node(repo);\n \n \tset_merge_remote_desc(commit, comment, (struct object *)commit);\n \tset_commit_tree(commit, tree);\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex b052974f191..49ca817d727 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -216,7 +216,7 @@ static struct commit *make_virtual_commit(struct repository *repo,\n \t\t\t\t\t  struct tree *tree,\n \t\t\t\t\t  const char *comment)\n {\n-\tstruct commit *commit = alloc_commit_node(repo);\n+\tstruct commit *commit = mem_pool_alloc_commit_node(repo);\n \n \tset_merge_remote_desc(commit, comment, (struct object *)commit);\n \tset_commit_tree(commit, tree);\ndiff --git a/object.c b/object.c\nindex 98017bed8ef..ec3b656188b 100644\n--- a/object.c\n+++ b/object.c\n@@ -182,7 +182,7 @@ struct object *lookup_unknown_object(const struct object_id *oid)\n \tstruct object *obj = lookup_object(the_repository, oid);\n \tif (!obj)\n \t\tobj = create_object(the_repository, oid,\n-\t\t\t\t    alloc_object_node(the_repository));\n+\t\t\t\tmem_pool_alloc_object_node(the_repository));\n \treturn obj;\n }\n \n@@ -471,11 +471,16 @@ struct parsed_object_pool *parsed_object_pool_new(void)\n \tstruct parsed_object_pool *o = xmalloc(sizeof(*o));\n \tmemset(o, 0, sizeof(*o));\n \n-\to->blob_state = allocate_alloc_state();\n-\to->tree_state = allocate_alloc_state();\n-\to->commit_state = allocate_alloc_state();\n-\to->tag_state = allocate_alloc_state();\n-\to->object_state = allocate_alloc_state();\n+\to->blob_pool = mem_pool_new();\n+\to->tree_pool = mem_pool_new();\n+\to->commit_pool = mem_pool_new();\n+\to->tag_pool = mem_pool_new();\n+\to->object_pool = mem_pool_new();\n+\tmem_pool_init(o->blob_pool,0);\n+\tmem_pool_init(o->tree_pool,0);\n+\tmem_pool_init(o->commit_pool,0);\n+\tmem_pool_init(o->tag_pool,0);\n+\tmem_pool_init(o->object_pool,0);\n \n \to->is_shallow = -1;\n \to->shallow_stat = xcalloc(1, sizeof(*o->shallow_stat));\n@@ -568,16 +573,16 @@ void parsed_object_pool_clear(struct parsed_object_pool *o)\n \tfree_commit_buffer_slab(o->buffer_slab);\n \to->buffer_slab = NULL;\n \n-\tclear_alloc_state(o->blob_state);\n-\tclear_alloc_state(o->tree_state);\n-\tclear_alloc_state(o->commit_state);\n-\tclear_alloc_state(o->tag_state);\n-\tclear_alloc_state(o->object_state);\n+\tmem_pool_discard(o->blob_pool,1);\n+\tmem_pool_discard(o->tree_pool,1);\n+\tmem_pool_discard(o->tag_pool,1);\n+\tmem_pool_discard(o->object_pool,1);\n+\tmem_pool_discard(o->commit_pool,1);\n \tstat_validity_clear(o->shallow_stat);\n-\tFREE_AND_NULL(o->blob_state);\n-\tFREE_AND_NULL(o->tree_state);\n-\tFREE_AND_NULL(o->commit_state);\n-\tFREE_AND_NULL(o->tag_state);\n-\tFREE_AND_NULL(o->object_state);\n+\tFREE_AND_NULL(o->blob_pool);\n+\tFREE_AND_NULL(o->tree_pool);\n+\tFREE_AND_NULL(o->commit_pool);\n+\tFREE_AND_NULL(o->tag_pool);\n+\tFREE_AND_NULL(o->object_pool);\n \tFREE_AND_NULL(o->shallow_stat);\n }\ndiff --git a/object.h b/object.h\nindex 59daadce214..43031d8dc04 100644\n--- a/object.h\n+++ b/object.h\n@@ -10,11 +10,11 @@ struct parsed_object_pool {\n \tint nr_objs, obj_hash_size;\n \n \t/* TODO: migrate alloc_states to mem-pool? */\n-\tstruct alloc_state *blob_state;\n-\tstruct alloc_state *tree_state;\n-\tstruct alloc_state *commit_state;\n-\tstruct alloc_state *tag_state;\n-\tstruct alloc_state *object_state;\n+\tstruct mem_pool *blob_pool;\n+\tstruct mem_pool *tree_pool;\n+\tstruct mem_pool *commit_pool;\n+\tstruct mem_pool *tag_pool;\n+\tstruct mem_pool *object_pool;\n \n \t/* parent substitutions from .git/info/grafts and .git/shallow */\n \tstruct commit_graft **grafts;\ndiff --git a/tag.c b/tag.c\nindex 1ed2684e45b..de24b6308b4 100644\n--- a/tag.c\n+++ b/tag.c\n@@ -102,7 +102,7 @@ struct tag *lookup_tag(struct repository *r, const struct object_id *oid)\n {\n \tstruct object *obj = lookup_object(r, oid);\n \tif (!obj)\n-\t\treturn create_object(r, oid, alloc_tag_node(r));\n+\t\treturn create_object(r, oid, mem_pool_alloc_tag_node(r));\n \treturn object_as_type(obj, OBJ_TAG, 0);\n }\n \ndiff --git a/tree.c b/tree.c\nindex a52479812ce..a4b081a42b7 100644\n--- a/tree.c\n+++ b/tree.c\n@@ -199,7 +199,7 @@ struct tree *lookup_tree(struct repository *r, const struct object_id *oid)\n {\n \tstruct object *obj = lookup_object(r, oid);\n \tif (!obj)\n-\t\treturn create_object(r, oid, alloc_tree_node(r));\n+\t\treturn create_object(r, oid, mem_pool_alloc_tree_node(r));\n \treturn object_as_type(obj, OBJ_TREE, 0);\n }\n \n\nbase-commit: e6362826a0409539642a5738db61827e5978e2e4\n-- \ngitgitgadget\n"},{"id":"415777","messageId":"7a9e78d0-732d-a990-0cb5-6bd8cf940a88@web.de","threadId":"55075","inReplyTo":"pull.857.v2.git.1612175966786.gitgitgadget@gmail.com","subject":"Re: [PATCH v2] alloc.h|c: migrate alloc_states to mem-pool","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2021-02-01T17:55:03Z","receivedAt":"2021-02-01T17:57:32Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 01.02.21 um 11:39 schrieb 阿德烈 via GitGitGadget:\n> From: ZheNing Hu <adlternative@gmail.com>\n>\n> \"alloc_state\" may have similar effects with \"mem_pool\".\n> Using the new memory pool API may be more beneficial\n> to our memory management in the future.\n\nReplacing the custom object allocator with mem-pool would allow reducing\nthe code size.  What other effects might it have?  Do you expect changes\nin memory use and/or performance with the current code and your patch?\n\n> functions \"alloc_*_node\" now change to \"mem_pool_alloc_*_node\".\n\nWhy rename these functions?  Do callers need to care about the\nunderlying allocator?  The function signatures stay the same.  In any\ncase, this renaming would be easier to review if it was moved to a\nseparate patch.\n\n> At the same time ,I add the member `alloc_count` of\n> struct mem_pool ,so that we can effective track\n> node alloc count,and adapt to the original interface `alloc_report`.\n\nThis function has no callers.  Why not remove it (in a separate patch)?\n\n> diff --git a/alloc.c b/alloc.c\n> index 957a0af3626..951ef3e4ed7 100644\n> --- a/alloc.c\n> +++ b/alloc.c\n> @@ -71,30 +71,30 @@ static inline void *alloc_node(struct alloc_state *s, size_t node_size)\n>  \treturn ret;\n>  }\n\nThis keeps the now unused function alloc_node(), which breaks the build\nwith -Werror.\n\nallocate_alloc_state() and clear_alloc_state() become unused as well,\nbut the compiler doesn't complain because those functions are\nexported.  Nevertheless this patch should remove them, no?\n\n> diff --git a/object.h b/object.h\n> index 59daadce214..43031d8dc04 100644\n> --- a/object.h\n> +++ b/object.h\n> @@ -10,11 +10,11 @@ struct parsed_object_pool {\n>  \tint nr_objs, obj_hash_size;\n>\n>  \t/* TODO: migrate alloc_states to mem-pool? */\n\nThis comment becomes stale with this patch and should be removed at\nthe same time.\n\n> -\tstruct alloc_state *blob_state;\n> -\tstruct alloc_state *tree_state;\n> -\tstruct alloc_state *commit_state;\n> -\tstruct alloc_state *tag_state;\n> -\tstruct alloc_state *object_state;\n> +\tstruct mem_pool *blob_pool;\n> +\tstruct mem_pool *tree_pool;\n> +\tstruct mem_pool *commit_pool;\n> +\tstruct mem_pool *tag_pool;\n> +\tstruct mem_pool *object_pool;\n\nWhy have pointers here instead of the structs themselves?  It's not like\na struct parsed_object_pool is of much use without them, right?\n\nThe same question applies to the original code as well, of course.\n\nRené\n"},{"id":"415778","messageId":"xmqqpn1jn033.fsf@gitster.c.googlers.com","threadId":"55075","inReplyTo":"pull.857.v2.git.1612175966786.gitgitgadget@gmail.com","subject":"Re: [PATCH v2] alloc.h|c: migrate alloc_states to mem-pool","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-02-01T17:56:32Z","receivedAt":"2021-02-01T17:57:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"阿德烈 via GitGitGadget\"  <gitgitgadget@gmail.com> writes:\n\n> From: ZheNing Hu <adlternative@gmail.com>\n>\n> \"alloc_state\" may have similar effects with \"mem_pool\".\n\nWhat \"similar effects\" do you have in mind?  \"mem_pool\" may have\nmore than one \"effects\" to multiple things that are affected, but it\nis unclear which effect that \"mem_pool\" exerts on what you are\nreferring to.\n\n> Using the new memory pool API may be more beneficial\n> to our memory management in the future.\n\nMany things may or may not be \"beneficial\" in the future.  We do not\nbuild things on a vague \"hunch\".\n\nAre you seeking performance (e.g.  number of objects that can be\nallocated per minute)?  Are you seeking better memory locality\n(e.g. related objects are likely to be stored in the same page,\nreducing number of page faults)?  Are you seeking reduced wasted\nmemory (e.g. custom allocator packs objects better than bog-standard\nmalloc(3))?  Are you seeking functionality (e.g. you have this and\nthat specific codepaths and usecase where you wish to be able to\nrelease all the objects instantiated for a particular repository,\nwithout having to go through the list of all objects, and use of\nmempool is one way to allow us do so)?\n\nIt is not even clear in your problem description what kind of\nbenefit you are seeking, let alone how much quantitative improvement\nyou are getting with this change.\n\n"},{"id":"415917","messageId":"CAOLTT8ShJzJangqkk8KQVdptFB5K0TiB1ETQcXb=HwinbkL9Hw@mail.gmail.com","threadId":"55075","inReplyTo":"xmqqpn1jn033.fsf@gitster.c.googlers.com","subject":"Re: [PATCH v2] alloc.h|c: migrate alloc_states to mem-pool","fromName":"胡哲宁","fromEmail":"adlternative@gmail.com","sentAt":"2021-02-02T13:06:17Z","receivedAt":"2021-02-02T13:04:57Z","isPatch":true,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"To Junio:\nThanks for checking.forget my unprofessional\ndescription.Macroscopically speaking,\nboth alloc_state and mem_pool are doing one thing:Apply for a\nlarge block of memory in advance,and when needed a dynamically\nallocated memory ,we call the interface function to apply for memory,\nThis can reduce the overhead of calling malloc multiple times.And the\nmem-pool or alloc_state will Automatic Expand capacity.\n\nSo that ,my this patch may have something not considered,\n>     mem_pool_init(o->blob_pool,0);\nmay be a wrong way to init this mem-pool\nbecause:\n>void mem_pool_init(...)\n>       ...\n>       if (initial_size > 0)\n>              mem_pool_alloc_block(pool, initial_size, NULL);\nthe first time calloc malloc may  decay to we first call \"mem_pool_alloc_block\",\nI think this may not be great.\n\nA little ashamed,I did not consider the optimization point of this\nat the beginning,\n\n\nJunio C Hamano <gitster@pobox.com> 于2021年2月2日周二 上午1:56写道：\n>\n> \"阿德烈 via GitGitGadget\"  <gitgitgadget@gmail.com> writes:\n>\n> > From: ZheNing Hu <adlternative@gmail.com>\n> >\n> > \"alloc_state\" may have similar effects with \"mem_pool\".\n>\n> What \"similar effects\" do you have in mind?  \"mem_pool\" may have\n> more than one \"effects\" to multiple things that are affected, but it\n> is unclear which effect that \"mem_pool\" exerts on what you are\n> referring to.\n>\n> > Using the new memory pool API may be more beneficial\n> > to our memory management in the future.\n>\n> Many things may or may not be \"beneficial\" in the future.  We do not\n> build things on a vague \"hunch\".\n>\nNow,I make a rough comparison.\nSituation : when we just use it to malloc little struct node\nsuch as `object`,`blob` ,`tree`.\n> Are you seeking performance (e.g.  number of objects that can be\n> allocated per minute)?\n\n1.  performance.\n`mem_pool` api will allocate 2^20 byte everytime ,\n`alloc_state` api will allocate 1024*nodesize byte and ALLOC_GROW everytime.\nA repo like git may call malloc fewer times when using `mem_pool`,\nwhile a small repo may not have this amount of objects. The number of\ncalling `malloc`\nmay be similar.\nmay be `mem_pool` win a little...\n>Are you seeking better memory locality\n> (e.g. related objects are likely to be stored in the same page,\n> reducing number of page faults)?\n2. page faults .\nI might think they are similar at first.But now,I start to understand\nwhat you mean:`alloc_state` more like an object pool,so that we could\ngo through the list of all objects.Therefore, mem_pool is not conducive\nto continuous access to all objects.Because There may be fragments\nin the memory And this must be a cross-page operation.\nso `alloc_state` win.\n>Are you seeking reduced wasted\n> memory (e.g. custom allocator packs objects better than bog-standard\n> malloc(3))?\n3.Memory utilization.\n`alloc_state`win.No doubt.\n Are you seeking functionality (e.g. you have this and\n> that specific codepaths and usecase where you wish to be able to\n> release all the objects instantiated for a particular repository,\n> without having to go through the list of all objects, and use of\n> mempool is one way to allow us do so)?\n>\n4.functionality\nyeah,As mentioned above.Object pool will be better.\n`alloc_state`win.\n5.\nIndeed, the object pool `alloc_state` may be better than the\nmemory pool `mem_pool`.\nBut We can assume that the original author’s intention may be to\nThe five alloc_states are merged together.\nBecause the original author said: \"migrate alloc_states to mem-pool\"\nOr another advantage of using the memory pool is that it can dynamically\nallocate a variety of different objects, I now think the original author has\nthis intention.So my patch code also needs some modifications.But at the\nsame time, it may not be good to count them separately if multiple objects\nare allocated using the memory pool at the same time.\nso 'mem_pool' win a little.\n> It is not even clear in your problem description what kind of\n> benefit you are seeking, let alone how much quantitative improvement\n> you are getting with this change.\n>\nI don't know how to quantify them temporarily.\nI may need the opinions of you and the original author before I can move on.\n\nThanks.\n"},{"id":"415918","messageId":"CAOLTT8Rf0vjB1+RuChbVPgf=YDif4B1mnro2MEF6E8+uGXM24Q@mail.gmail.com","threadId":"55075","inReplyTo":"7a9e78d0-732d-a990-0cb5-6bd8cf940a88@web.de","subject":"Re: [PATCH v2] alloc.h|c: migrate alloc_states to mem-pool","fromName":"胡哲宁","fromEmail":"adlternative@gmail.com","sentAt":"2021-02-02T13:12:10Z","receivedAt":"2021-02-02T13:11:19Z","isPatch":true,"sender":{"key":"adlternative@gmail.com","avatar":"https://avatars.githubusercontent.com/u/58138461?v=4"},"body":"To René Scharfe:\nThanks for checking in.\n\nRené Scharfe <l.s.r@web.de> 于2021年2月2日周二 上午1:55写道：\n>\n> Am 01.02.21 um 11:39 schrieb 阿德烈 via GitGitGadget:\n> > From: ZheNing Hu <adlternative@gmail.com>\n> >\n> > \"alloc_state\" may have similar effects with \"mem_pool\".\n> > Using the new memory pool API may be more beneficial\n> > to our memory management in the future.\n>\n> Replacing the custom object allocator with mem-pool would allow reducing\n> the code size.  What other effects might it have?  Do you expect changes\n> in memory use and/or performance with the current code and your patch?\n>\n> > functions \"alloc_*_node\" now change to \"mem_pool_alloc_*_node\".\n>\n> Why rename these functions?  Do callers need to care about the\n> underlying allocator?  The function signatures stay the same.  In any\n> case, this renaming would be easier to review if it was moved to a\n> separate patch.\n>\nTruly,I will change it.\n> > At the same time ,I add the member `alloc_count` of\n> > struct mem_pool ,so that we can effective track\n> > node alloc count,and adapt to the original interface `alloc_report`.\n>\n> This function has no callers.  Why not remove it (in a separate patch)?\n>\nBefore I may have some confuse about choosing `alloc_state`or`mem_pool`,\nso It has not been deleted yet.I remember that now.\n> > diff --git a/alloc.c b/alloc.c\n> > index 957a0af3626..951ef3e4ed7 100644\n> > --- a/alloc.c\n> > +++ b/alloc.c\n> > @@ -71,30 +71,30 @@ static inline void *alloc_node(struct alloc_state *s, size_t node_size)\n> >       return ret;\n> >  }\n>\n> This keeps the now unused function alloc_node(), which breaks the build\n> with -Werror.\n>\n> allocate_alloc_state() and clear_alloc_state() become unused as well,\n> but the compiler doesn't complain because those functions are\n> exported.  Nevertheless this patch should remove them, no?\n>\n> > diff --git a/object.h b/object.h\n> > index 59daadce214..43031d8dc04 100644\n> > --- a/object.h\n> > +++ b/object.h\n> > @@ -10,11 +10,11 @@ struct parsed_object_pool {\n> >       int nr_objs, obj_hash_size;\n> >\n> >       /* TODO: migrate alloc_states to mem-pool? */\n>\n> This comment becomes stale with this patch and should be removed at\n> the same time.\n>\nOK.\n> > -     struct alloc_state *blob_state;\n> > -     struct alloc_state *tree_state;\n> > -     struct alloc_state *commit_state;\n> > -     struct alloc_state *tag_state;\n> > -     struct alloc_state *object_state;\n> > +     struct mem_pool *blob_pool;\n> > +     struct mem_pool *tree_pool;\n> > +     struct mem_pool *commit_pool;\n> > +     struct mem_pool *tag_pool;\n> > +     struct mem_pool *object_pool;\n>\n> Why have pointers here instead of the structs themselves?  It's not like\n> a struct parsed_object_pool is of much use without them, right?\n>\n> The same question applies to the original code as well, of course.\nHere I may have some questions: why use `struct mem_pool` instead of\nusing `struct mem_pool *`?\nI hope you can answer my doubts, thank you!\n>\n> René\n"},{"id":"415935","messageId":"f10273ef-3d71-5220-9985-1a4fa2c84cd3@web.de","threadId":"55075","inReplyTo":"CAOLTT8Rf0vjB1+RuChbVPgf=YDif4B1mnro2MEF6E8+uGXM24Q@mail.gmail.com","subject":"Re: [PATCH v2] alloc.h|c: migrate alloc_states to mem-pool","fromName":"René Scharfe.","fromEmail":"l.s.r@web.de","sentAt":"2021-02-02T16:36:00Z","receivedAt":"2021-02-02T16:41:16Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 02.02.21 um 14:12 schrieb 胡哲宁:\n> To René Scharfe:\n>>> -     struct alloc_state *blob_state;\n>>> -     struct alloc_state *tree_state;\n>>> -     struct alloc_state *commit_state;\n>>> -     struct alloc_state *tag_state;\n>>> -     struct alloc_state *object_state;\n>>> +     struct mem_pool *blob_pool;\n>>> +     struct mem_pool *tree_pool;\n>>> +     struct mem_pool *commit_pool;\n>>> +     struct mem_pool *tag_pool;\n>>> +     struct mem_pool *object_pool;\n>>\n>> Why have pointers here instead of the structs themselves?  It's not like\n>> a struct parsed_object_pool is of much use without them, right?\n>>\n>> The same question applies to the original code as well, of course.\n> Here I may have some questions: why use `struct mem_pool` instead of\n> using `struct mem_pool *`?\n> I hope you can answer my doubts, thank you!\n\nIf struct parsed_object_pool contains pointers to five instances of\nstruct alloc_state or struct mem_pool then you have to allocate and\neventually release those instances explicitly.  Your patch introduced\nmem_pool_new() for the allocation part.\n\nIf the five instances are embedded in struct parsed_object_pool then\nyou don't need to do that.\n\nThe indirection added by allocating explicitly and using pointers\nwould be beneficial if some of five instances were optional, as you\ncould skip their allocation and save some memory -- but you need\nthem all to get a usable struct parsed_object_pool.\n\nRené\n"},{"id":"416146","messageId":"pull.857.v3.git.1612434793195.gitgitgadget@gmail.com","threadId":"55075","inReplyTo":"pull.857.v2.git.1612175966786.gitgitgadget@gmail.com","subject":"[PATCH v3] alloc.h|c: migrate alloc_states to mem-pool","fromName":"阿德烈 via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2021-02-04T10:33:12Z","receivedAt":"2021-02-04T10:35:32Z","isPatch":true,"sender":{"key":"name:阿德烈","avatar":null},"body":"From: ZheNing Hu <adlternative@gmail.com>\n\nIn \"object.h\",I use `mem_pool` to replace the five\n\"alloc_state *\" which used to allocate memory for\ndifferent types of object nodes.Now that one `mem_pool`\nunified management of the allocation and release of\nthe memory of multiple nodes.\nThe advantage of changing to a `mem_pool` is:\n1.we can allocate more memory at a time than the original\n`alloc_state`,thus reducing the number of system calls to malloc.\n2.the user interface is take memory in a memory pool,We no longer\nneed to take from multiple pools as before.\n\nAt the same time, mem_pool may have its disadvantages:\n1. There is memory fragmentation\n2. It is not conducive to counting or traversing\ndifferent types of nodes.\nThis may require some refinement or disregard.\n\nSigned-off-by: ZheNing Hu <adlternative@gmail.com>\n---\n    object.h: migrate alloc_states to mem-pool\n    \n    Notice that \"mem-pool\" api may have similar effort with alloc_state,\n    \"parsed_object_pool\" have five member with alloc_state type, and \"TODO\"\n    usage in \"object.h\":\"migrate alloc_states to mem-pool?\", so let us\n    change it to mem-pool version.\n    \n    After I learned the role of the memory pool,I think in the future git\n    may be more inclined to use the memory pool instead of the old interface\n    \"alloc_state\".\n    \n    Thanks.\n    \n    cc: Junio C Hamano gitster@pobox.com cc: Stefan Beller\n    sbeller@google.com\n\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-857%2Fadlternative%2Falloc_states_to_mem_pool-v3\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-857/adlternative/alloc_states_to_mem_pool-v3\nPull-Request: https://github.com/gitgitgadget/git/pull/857\n\nRange-diff vs v2:\n\n 1:  e9c1f9eef428 ! 1:  4b292c037ed2 alloc.h|c: migrate alloc_states to mem-pool\n     @@ Metadata\n       ## Commit message ##\n          alloc.h|c: migrate alloc_states to mem-pool\n      \n     -    \"alloc_state\" may have similar effects with \"mem_pool\".\n     -    Using the new memory pool API may be more beneficial\n     -    to our memory management in the future.\n     -\n     -    So I change them in the \"struct parsed_object_pool\",and\n     -    The corresponding interface has also been changed.\n     -    functions \"alloc_*_node\" now change to \"mem_pool_alloc_*_node\".\n     -\n     -    At the same time ,I add the member `alloc_count` of\n     -    struct mem_pool ,so that we can effective track\n     -    node alloc count,and adapt to the original interface `alloc_report`.\n     +    In \"object.h\",I use `mem_pool` to replace the five\n     +    \"alloc_state *\" which used to allocate memory for\n     +    different types of object nodes.Now that one `mem_pool`\n     +    unified management of the allocation and release of\n     +    the memory of multiple nodes.\n     +    The advantage of changing to a `mem_pool` is:\n     +    1.we can allocate more memory at a time than the original\n     +    `alloc_state`,thus reducing the number of system calls to malloc.\n     +    2.the user interface is take memory in a memory pool,We no longer\n     +    need to take from multiple pools as before.\n     +\n     +    At the same time, mem_pool may have its disadvantages:\n     +    1. There is memory fragmentation\n     +    2. It is not conducive to counting or traversing\n     +    different types of nodes.\n     +    This may require some refinement or disregard.\n      \n          Signed-off-by: ZheNing Hu <adlternative@gmail.com>\n      \n       ## alloc.c ##\n     -@@ alloc.c: static inline void *alloc_node(struct alloc_state *s, size_t node_size)\n     - \treturn ret;\n     - }\n     +@@ alloc.c: struct alloc_state {\n     + \tint slab_nr, slab_alloc;\n     + };\n       \n     --void *alloc_blob_node(struct repository *r)\n     -+void *mem_pool_alloc_blob_node(struct repository *r)\n     +-struct alloc_state *allocate_alloc_state(void)\n     +-{\n     +-\treturn xcalloc(1, sizeof(struct alloc_state));\n     +-}\n     +-\n     +-void clear_alloc_state(struct alloc_state *s)\n     +-{\n     +-\twhile (s->slab_nr > 0) {\n     +-\t\ts->slab_nr--;\n     +-\t\tfree(s->slabs[s->slab_nr]);\n     +-\t}\n     +-\n     +-\tFREE_AND_NULL(s->slabs);\n     +-}\n     +-\n     +-static inline void *alloc_node(struct alloc_state *s, size_t node_size)\n     +-{\n     +-\tvoid *ret;\n     +-\n     +-\tif (!s->nr) {\n     +-\t\ts->nr = BLOCKING;\n     +-\t\ts->p = xmalloc(BLOCKING * node_size);\n     +-\n     +-\t\tALLOC_GROW(s->slabs, s->slab_nr + 1, s->slab_alloc);\n     +-\t\ts->slabs[s->slab_nr++] = s->p;\n     +-\t}\n     +-\ts->nr--;\n     +-\ts->count++;\n     +-\tret = s->p;\n     +-\ts->p = (char *)s->p + node_size;\n     +-\tmemset(ret, 0, node_size);\n     +-\n     +-\treturn ret;\n     +-}\n     +-\n     + void *alloc_blob_node(struct repository *r)\n       {\n      -\tstruct blob *b = alloc_node(r->parsed_objects->blob_state, sizeof(struct blob));\n     -+\tstruct blob *b = mem_pool_calloc(r->parsed_objects->blob_pool, 1, sizeof(struct blob));\n     ++\tstruct blob *b = mem_pool_calloc(&r->parsed_objects->objects_pool, 1, sizeof(struct blob));\n       \tb->object.type = OBJ_BLOB;\n       \treturn b;\n       }\n       \n     --void *alloc_tree_node(struct repository *r)\n     -+void *mem_pool_alloc_tree_node(struct repository *r)\n     + void *alloc_tree_node(struct repository *r)\n       {\n      -\tstruct tree *t = alloc_node(r->parsed_objects->tree_state, sizeof(struct tree));\n     -+\tstruct tree *t = mem_pool_calloc(r->parsed_objects->tree_pool, 1, sizeof(struct tree));\n     ++\tstruct tree *t = mem_pool_calloc(&r->parsed_objects->objects_pool, 1, sizeof(struct tree));\n       \tt->object.type = OBJ_TREE;\n       \treturn t;\n       }\n       \n     --void *alloc_tag_node(struct repository *r)\n     -+void *mem_pool_alloc_tag_node(struct repository *r)\n     + void *alloc_tag_node(struct repository *r)\n       {\n      -\tstruct tag *t = alloc_node(r->parsed_objects->tag_state, sizeof(struct tag));\n     -+\tstruct tag *t = mem_pool_calloc(r->parsed_objects->tag_pool, 1, sizeof(struct tag));\n     ++\tstruct tag *t = mem_pool_calloc(&r->parsed_objects->objects_pool, 1, sizeof(struct tag));\n       \tt->object.type = OBJ_TAG;\n       \treturn t;\n       }\n       \n     --void *alloc_object_node(struct repository *r)\n     -+void *mem_pool_alloc_object_node(struct repository *r)\n     + void *alloc_object_node(struct repository *r)\n       {\n      -\tstruct object *obj = alloc_node(r->parsed_objects->object_state, sizeof(union any_object));\n     -+\tstruct object *obj = mem_pool_calloc(r->parsed_objects->object_pool, 1, sizeof(union any_object));\n     ++\tstruct object *obj = mem_pool_calloc(&r->parsed_objects->objects_pool, 1, sizeof(union any_object));\n       \tobj->type = OBJ_NONE;\n       \treturn obj;\n       }\n      @@ alloc.c: void init_commit_node(struct commit *c)\n     - \tc->index = alloc_commit_index();\n     - }\n       \n     --void *alloc_commit_node(struct repository *r)\n     -+void *mem_pool_alloc_commit_node(struct repository *r)\n     + void *alloc_commit_node(struct repository *r)\n       {\n      -\tstruct commit *c = alloc_node(r->parsed_objects->commit_state, sizeof(struct commit));\n     -+\tstruct commit *c = mem_pool_calloc(r->parsed_objects->commit_pool, 1, sizeof(struct commit));\n     ++\tstruct commit *c = mem_pool_calloc(&r->parsed_objects->objects_pool, 1, sizeof(struct commit));\n       \tinit_commit_node(c);\n       \treturn c;\n       }\n     -@@ alloc.c: static void report(const char *name, unsigned int count, size_t size)\n     - }\n     - \n     - #define REPORT(name, type)\t\\\n     +-\n     +-static void report(const char *name, unsigned int count, size_t size)\n     +-{\n     +-\tfprintf(stderr, \"%10s: %8u (%\"PRIuMAX\" kB)\\n\",\n     +-\t\t\tname, count, (uintmax_t) size);\n     +-}\n     +-\n     +-#define REPORT(name, type)\t\\\n      -    report(#name, r->parsed_objects->name##_state->count, \\\n      -\t\t  r->parsed_objects->name##_state->count * sizeof(type) >> 10)\n     -+    report(#name, r->parsed_objects->name##_pool->alloc_count, \\\n     -+\t\t  r->parsed_objects->name##_pool->alloc_count * sizeof(type) >> 10)\n     - \n     - void alloc_report(struct repository *r)\n     - {\n     +-\n     +-void alloc_report(struct repository *r)\n     +-{\n     +-\tREPORT(blob, struct blob);\n     +-\tREPORT(tree, struct tree);\n     +-\tREPORT(commit, struct commit);\n     +-\tREPORT(tag, struct tag);\n     +-\tREPORT(object, union any_object);\n     +-}\n      \n       ## alloc.h ##\n     -@@ alloc.h: struct commit;\n     - struct tag;\n     - struct repository;\n     - \n     --void *alloc_blob_node(struct repository *r);\n     --void *alloc_tree_node(struct repository *r);\n     -+void *mem_pool_alloc_blob_node(struct repository *r);\n     -+void *mem_pool_alloc_tree_node(struct repository *r);\n     - void init_commit_node(struct commit *c);\n     --void *alloc_commit_node(struct repository *r);\n     --void *alloc_tag_node(struct repository *r);\n     --void *alloc_object_node(struct repository *r);\n     -+void *mem_pool_alloc_commit_node(struct repository *r);\n     -+void *mem_pool_alloc_tag_node(struct repository *r);\n     -+void *mem_pool_alloc_object_node(struct repository *r);\n     +@@ alloc.h: void *alloc_tag_node(struct repository *r);\n     + void *alloc_object_node(struct repository *r);\n       void alloc_report(struct repository *r);\n       \n     - struct alloc_state *allocate_alloc_state(void);\n     -\n     - ## blame.c ##\n     -@@ blame.c: static struct commit *fake_working_tree_commit(struct repository *r,\n     - \n     - \trepo_read_index(r);\n     - \ttime(&now);\n     --\tcommit = alloc_commit_node(r);\n     -+\tcommit = mem_pool_alloc_commit_node(r);\n     - \tcommit->object.parsed = 1;\n     - \tcommit->date = now;\n     - \tparent_tail = &commit->parents;\n     -\n     - ## blob.c ##\n     -@@ blob.c: struct blob *lookup_blob(struct repository *r, const struct object_id *oid)\n     - {\n     - \tstruct object *obj = lookup_object(r, oid);\n     - \tif (!obj)\n     --\t\treturn create_object(r, oid, alloc_blob_node(r));\n     -+\t\treturn create_object(r, oid, mem_pool_alloc_blob_node(r));\n     - \treturn object_as_type(obj, OBJ_BLOB, 0);\n     - }\n     - \n     -\n     - ## commit-graph.c ##\n     -@@ commit-graph.c: int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags)\n     - \t\thashcpy(cur_oid.hash, g->chunk_oid_lookup + g->hash_len * i);\n     - \n     - \t\tgraph_commit = lookup_commit(r, &cur_oid);\n     --\t\todb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r));\n     -+\t\todb_commit = (struct commit *)create_object(r, &cur_oid, mem_pool_alloc_commit_node(r));\n     - \t\tif (parse_commit_internal(odb_commit, 0, 0)) {\n     - \t\t\tgraph_report(_(\"failed to parse commit %s from object database for commit-graph\"),\n     - \t\t\t\t     oid_to_hex(&cur_oid));\n     -\n     - ## commit.c ##\n     -@@ commit.c: struct commit *lookup_commit(struct repository *r, const struct object_id *oid)\n     - {\n     - \tstruct object *obj = lookup_object(r, oid);\n     - \tif (!obj)\n     --\t\treturn create_object(r, oid, alloc_commit_node(r));\n     -+\t\treturn create_object(r, oid, mem_pool_alloc_commit_node(r));\n     - \treturn object_as_type(obj, OBJ_COMMIT, 0);\n     - }\n     - \n     +-struct alloc_state *allocate_alloc_state(void);\n     +-void clear_alloc_state(struct alloc_state *s);\n     +-\n     + #endif\n      \n       ## mem-pool.c ##\n     -@@ mem-pool.c: static struct mp_block *mem_pool_alloc_block(struct mem_pool *pool,\n     - \treturn p;\n     - }\n     +@@\n     + #include \"cache.h\"\n     + #include \"mem-pool.h\"\n       \n     -+struct mem_pool *mem_pool_new(void)\n     -+{\n     -+\treturn xmalloc(sizeof(struct mem_pool));\n     -+}\n     -+\n     - void mem_pool_init(struct mem_pool *pool, size_t initial_size)\n     - {\n     - \tmemset(pool, 0, sizeof(*pool));\n     +-#define BLOCK_GROWTH_SIZE 1024*1024 - sizeof(struct mp_block);\n     + \n     + /*\n     +  * Allocate a new mp_block and insert it after the block specified in\n      @@ mem-pool.c: void *mem_pool_alloc(struct mem_pool *pool, size_t len)\n       \tstruct mp_block *p = NULL;\n       \tvoid *r;\n     @@ mem-pool.h: struct mem_pool {\n      +\tsize_t alloc_count;\n       };\n       \n     -+/*\n     -+ * Create a new mem_pool.\n     -+ */\n     -+struct mem_pool *mem_pool_new(void);\n     ++#define BLOCK_GROWTH_SIZE 1024*1024 - sizeof(struct mp_block)\n      +\n       /*\n        * Initialize mem_pool with specified initial size.\n        */\n      \n     - ## merge-ort.c ##\n     -@@ merge-ort.c: static struct commit *make_virtual_commit(struct repository *repo,\n     - \t\t\t\t\t  struct tree *tree,\n     - \t\t\t\t\t  const char *comment)\n     - {\n     --\tstruct commit *commit = alloc_commit_node(repo);\n     -+\tstruct commit *commit = mem_pool_alloc_commit_node(repo);\n     - \n     - \tset_merge_remote_desc(commit, comment, (struct object *)commit);\n     - \tset_commit_tree(commit, tree);\n     -\n     - ## merge-recursive.c ##\n     -@@ merge-recursive.c: static struct commit *make_virtual_commit(struct repository *repo,\n     - \t\t\t\t\t  struct tree *tree,\n     - \t\t\t\t\t  const char *comment)\n     - {\n     --\tstruct commit *commit = alloc_commit_node(repo);\n     -+\tstruct commit *commit = mem_pool_alloc_commit_node(repo);\n     - \n     - \tset_merge_remote_desc(commit, comment, (struct object *)commit);\n     - \tset_commit_tree(commit, tree);\n     -\n       ## object.c ##\n      @@ object.c: struct object *lookup_unknown_object(const struct object_id *oid)\n       \tstruct object *obj = lookup_object(the_repository, oid);\n       \tif (!obj)\n       \t\tobj = create_object(the_repository, oid,\n      -\t\t\t\t    alloc_object_node(the_repository));\n     -+\t\t\t\tmem_pool_alloc_object_node(the_repository));\n     ++\t\t\t\talloc_object_node(the_repository));\n       \treturn obj;\n       }\n       \n      @@ object.c: struct parsed_object_pool *parsed_object_pool_new(void)\n     + {\n       \tstruct parsed_object_pool *o = xmalloc(sizeof(*o));\n       \tmemset(o, 0, sizeof(*o));\n     - \n     +-\n      -\to->blob_state = allocate_alloc_state();\n      -\to->tree_state = allocate_alloc_state();\n      -\to->commit_state = allocate_alloc_state();\n      -\to->tag_state = allocate_alloc_state();\n      -\to->object_state = allocate_alloc_state();\n     -+\to->blob_pool = mem_pool_new();\n     -+\to->tree_pool = mem_pool_new();\n     -+\to->commit_pool = mem_pool_new();\n     -+\to->tag_pool = mem_pool_new();\n     -+\to->object_pool = mem_pool_new();\n     -+\tmem_pool_init(o->blob_pool,0);\n     -+\tmem_pool_init(o->tree_pool,0);\n     -+\tmem_pool_init(o->commit_pool,0);\n     -+\tmem_pool_init(o->tag_pool,0);\n     -+\tmem_pool_init(o->object_pool,0);\n     - \n     +-\n     ++\tmem_pool_init(&o->objects_pool, BLOCK_GROWTH_SIZE);\n       \to->is_shallow = -1;\n       \to->shallow_stat = xcalloc(1, sizeof(*o->shallow_stat));\n     + \n      @@ object.c: void parsed_object_pool_clear(struct parsed_object_pool *o)\n       \tfree_commit_buffer_slab(o->buffer_slab);\n       \to->buffer_slab = NULL;\n     @@ object.c: void parsed_object_pool_clear(struct parsed_object_pool *o)\n      -\tclear_alloc_state(o->commit_state);\n      -\tclear_alloc_state(o->tag_state);\n      -\tclear_alloc_state(o->object_state);\n     -+\tmem_pool_discard(o->blob_pool,1);\n     -+\tmem_pool_discard(o->tree_pool,1);\n     -+\tmem_pool_discard(o->tag_pool,1);\n     -+\tmem_pool_discard(o->object_pool,1);\n     -+\tmem_pool_discard(o->commit_pool,1);\n     ++\tmem_pool_discard(&o->objects_pool,0);\n       \tstat_validity_clear(o->shallow_stat);\n      -\tFREE_AND_NULL(o->blob_state);\n      -\tFREE_AND_NULL(o->tree_state);\n      -\tFREE_AND_NULL(o->commit_state);\n      -\tFREE_AND_NULL(o->tag_state);\n      -\tFREE_AND_NULL(o->object_state);\n     -+\tFREE_AND_NULL(o->blob_pool);\n     -+\tFREE_AND_NULL(o->tree_pool);\n     -+\tFREE_AND_NULL(o->commit_pool);\n     -+\tFREE_AND_NULL(o->tag_pool);\n     -+\tFREE_AND_NULL(o->object_pool);\n     - \tFREE_AND_NULL(o->shallow_stat);\n     +-\tFREE_AND_NULL(o->shallow_stat);\n       }\n      \n       ## object.h ##\n      @@ object.h: struct parsed_object_pool {\n     + \tstruct object **obj_hash;\n       \tint nr_objs, obj_hash_size;\n       \n     - \t/* TODO: migrate alloc_states to mem-pool? */\n     +-\t/* TODO: migrate alloc_states to mem-pool? */\n      -\tstruct alloc_state *blob_state;\n      -\tstruct alloc_state *tree_state;\n      -\tstruct alloc_state *commit_state;\n      -\tstruct alloc_state *tag_state;\n      -\tstruct alloc_state *object_state;\n     -+\tstruct mem_pool *blob_pool;\n     -+\tstruct mem_pool *tree_pool;\n     -+\tstruct mem_pool *commit_pool;\n     -+\tstruct mem_pool *tag_pool;\n     -+\tstruct mem_pool *object_pool;\n     ++\tstruct mem_pool objects_pool;\n       \n       \t/* parent substitutions from .git/info/grafts and .git/shallow */\n       \tstruct commit_graft **grafts;\n     -\n     - ## tag.c ##\n     -@@ tag.c: struct tag *lookup_tag(struct repository *r, const struct object_id *oid)\n     - {\n     - \tstruct object *obj = lookup_object(r, oid);\n     - \tif (!obj)\n     --\t\treturn create_object(r, oid, alloc_tag_node(r));\n     -+\t\treturn create_object(r, oid, mem_pool_alloc_tag_node(r));\n     - \treturn object_as_type(obj, OBJ_TAG, 0);\n     - }\n     - \n     -\n     - ## tree.c ##\n     -@@ tree.c: struct tree *lookup_tree(struct repository *r, const struct object_id *oid)\n     - {\n     - \tstruct object *obj = lookup_object(r, oid);\n     - \tif (!obj)\n     --\t\treturn create_object(r, oid, alloc_tree_node(r));\n     -+\t\treturn create_object(r, oid, mem_pool_alloc_tree_node(r));\n     - \treturn object_as_type(obj, OBJ_TREE, 0);\n     - }\n     - \n\n\n alloc.c    | 64 +++++-------------------------------------------------\n alloc.h    |  3 ---\n mem-pool.c |  2 +-\n mem-pool.h |  5 +++++\n object.c   | 22 +++----------------\n object.h   |  7 +-----\n 6 files changed, 15 insertions(+), 88 deletions(-)\n\ndiff --git a/alloc.c b/alloc.c\nindex 957a0af36264..d5e84caa3794 100644\n--- a/alloc.c\n+++ b/alloc.c\n@@ -36,65 +36,30 @@ struct alloc_state {\n \tint slab_nr, slab_alloc;\n };\n \n-struct alloc_state *allocate_alloc_state(void)\n-{\n-\treturn xcalloc(1, sizeof(struct alloc_state));\n-}\n-\n-void clear_alloc_state(struct alloc_state *s)\n-{\n-\twhile (s->slab_nr > 0) {\n-\t\ts->slab_nr--;\n-\t\tfree(s->slabs[s->slab_nr]);\n-\t}\n-\n-\tFREE_AND_NULL(s->slabs);\n-}\n-\n-static inline void *alloc_node(struct alloc_state *s, size_t node_size)\n-{\n-\tvoid *ret;\n-\n-\tif (!s->nr) {\n-\t\ts->nr = BLOCKING;\n-\t\ts->p = xmalloc(BLOCKING * node_size);\n-\n-\t\tALLOC_GROW(s->slabs, s->slab_nr + 1, s->slab_alloc);\n-\t\ts->slabs[s->slab_nr++] = s->p;\n-\t}\n-\ts->nr--;\n-\ts->count++;\n-\tret = s->p;\n-\ts->p = (char *)s->p + node_size;\n-\tmemset(ret, 0, node_size);\n-\n-\treturn ret;\n-}\n-\n void *alloc_blob_node(struct repository *r)\n {\n-\tstruct blob *b = alloc_node(r->parsed_objects->blob_state, sizeof(struct blob));\n+\tstruct blob *b = mem_pool_calloc(&r->parsed_objects->objects_pool, 1, sizeof(struct blob));\n \tb->object.type = OBJ_BLOB;\n \treturn b;\n }\n \n void *alloc_tree_node(struct repository *r)\n {\n-\tstruct tree *t = alloc_node(r->parsed_objects->tree_state, sizeof(struct tree));\n+\tstruct tree *t = mem_pool_calloc(&r->parsed_objects->objects_pool, 1, sizeof(struct tree));\n \tt->object.type = OBJ_TREE;\n \treturn t;\n }\n \n void *alloc_tag_node(struct repository *r)\n {\n-\tstruct tag *t = alloc_node(r->parsed_objects->tag_state, sizeof(struct tag));\n+\tstruct tag *t = mem_pool_calloc(&r->parsed_objects->objects_pool, 1, sizeof(struct tag));\n \tt->object.type = OBJ_TAG;\n \treturn t;\n }\n \n void *alloc_object_node(struct repository *r)\n {\n-\tstruct object *obj = alloc_node(r->parsed_objects->object_state, sizeof(union any_object));\n+\tstruct object *obj = mem_pool_calloc(&r->parsed_objects->objects_pool, 1, sizeof(union any_object));\n \tobj->type = OBJ_NONE;\n \treturn obj;\n }\n@@ -118,26 +83,7 @@ void init_commit_node(struct commit *c)\n \n void *alloc_commit_node(struct repository *r)\n {\n-\tstruct commit *c = alloc_node(r->parsed_objects->commit_state, sizeof(struct commit));\n+\tstruct commit *c = mem_pool_calloc(&r->parsed_objects->objects_pool, 1, sizeof(struct commit));\n \tinit_commit_node(c);\n \treturn c;\n }\n-\n-static void report(const char *name, unsigned int count, size_t size)\n-{\n-\tfprintf(stderr, \"%10s: %8u (%\"PRIuMAX\" kB)\\n\",\n-\t\t\tname, count, (uintmax_t) size);\n-}\n-\n-#define REPORT(name, type)\t\\\n-    report(#name, r->parsed_objects->name##_state->count, \\\n-\t\t  r->parsed_objects->name##_state->count * sizeof(type) >> 10)\n-\n-void alloc_report(struct repository *r)\n-{\n-\tREPORT(blob, struct blob);\n-\tREPORT(tree, struct tree);\n-\tREPORT(commit, struct commit);\n-\tREPORT(tag, struct tag);\n-\tREPORT(object, union any_object);\n-}\ndiff --git a/alloc.h b/alloc.h\nindex 371d388b552f..eab035e3d373 100644\n--- a/alloc.h\n+++ b/alloc.h\n@@ -15,7 +15,4 @@ void *alloc_tag_node(struct repository *r);\n void *alloc_object_node(struct repository *r);\n void alloc_report(struct repository *r);\n \n-struct alloc_state *allocate_alloc_state(void);\n-void clear_alloc_state(struct alloc_state *s);\n-\n #endif\ndiff --git a/mem-pool.c b/mem-pool.c\nindex 8401761dda0a..09edd51cb40b 100644\n--- a/mem-pool.c\n+++ b/mem-pool.c\n@@ -5,7 +5,6 @@\n #include \"cache.h\"\n #include \"mem-pool.h\"\n \n-#define BLOCK_GROWTH_SIZE 1024*1024 - sizeof(struct mp_block);\n \n /*\n  * Allocate a new mp_block and insert it after the block specified in\n@@ -69,6 +68,7 @@ void *mem_pool_alloc(struct mem_pool *pool, size_t len)\n \tstruct mp_block *p = NULL;\n \tvoid *r;\n \n+\tpool->alloc_count++;\n \t/* round up to a 'uintmax_t' alignment */\n \tif (len & (sizeof(uintmax_t) - 1))\n \t\tlen += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));\ndiff --git a/mem-pool.h b/mem-pool.h\nindex fe7507f022bb..131fa1511601 100644\n--- a/mem-pool.h\n+++ b/mem-pool.h\n@@ -19,8 +19,13 @@ struct mem_pool {\n \n \t/* The total amount of memory allocated by the pool. */\n \tsize_t pool_alloc;\n+\n+\t/* The count of calling mem_pool_alloc .*/\n+\tsize_t alloc_count;\n };\n \n+#define BLOCK_GROWTH_SIZE 1024*1024 - sizeof(struct mp_block)\n+\n /*\n  * Initialize mem_pool with specified initial size.\n  */\ndiff --git a/object.c b/object.c\nindex 98017bed8efb..75e2305e7cd2 100644\n--- a/object.c\n+++ b/object.c\n@@ -182,7 +182,7 @@ struct object *lookup_unknown_object(const struct object_id *oid)\n \tstruct object *obj = lookup_object(the_repository, oid);\n \tif (!obj)\n \t\tobj = create_object(the_repository, oid,\n-\t\t\t\t    alloc_object_node(the_repository));\n+\t\t\t\talloc_object_node(the_repository));\n \treturn obj;\n }\n \n@@ -470,13 +470,7 @@ struct parsed_object_pool *parsed_object_pool_new(void)\n {\n \tstruct parsed_object_pool *o = xmalloc(sizeof(*o));\n \tmemset(o, 0, sizeof(*o));\n-\n-\to->blob_state = allocate_alloc_state();\n-\to->tree_state = allocate_alloc_state();\n-\to->commit_state = allocate_alloc_state();\n-\to->tag_state = allocate_alloc_state();\n-\to->object_state = allocate_alloc_state();\n-\n+\tmem_pool_init(&o->objects_pool, BLOCK_GROWTH_SIZE);\n \to->is_shallow = -1;\n \to->shallow_stat = xcalloc(1, sizeof(*o->shallow_stat));\n \n@@ -568,16 +562,6 @@ void parsed_object_pool_clear(struct parsed_object_pool *o)\n \tfree_commit_buffer_slab(o->buffer_slab);\n \to->buffer_slab = NULL;\n \n-\tclear_alloc_state(o->blob_state);\n-\tclear_alloc_state(o->tree_state);\n-\tclear_alloc_state(o->commit_state);\n-\tclear_alloc_state(o->tag_state);\n-\tclear_alloc_state(o->object_state);\n+\tmem_pool_discard(&o->objects_pool,0);\n \tstat_validity_clear(o->shallow_stat);\n-\tFREE_AND_NULL(o->blob_state);\n-\tFREE_AND_NULL(o->tree_state);\n-\tFREE_AND_NULL(o->commit_state);\n-\tFREE_AND_NULL(o->tag_state);\n-\tFREE_AND_NULL(o->object_state);\n-\tFREE_AND_NULL(o->shallow_stat);\n }\ndiff --git a/object.h b/object.h\nindex 59daadce2145..23e2127f5867 100644\n--- a/object.h\n+++ b/object.h\n@@ -9,12 +9,7 @@ struct parsed_object_pool {\n \tstruct object **obj_hash;\n \tint nr_objs, obj_hash_size;\n \n-\t/* TODO: migrate alloc_states to mem-pool? */\n-\tstruct alloc_state *blob_state;\n-\tstruct alloc_state *tree_state;\n-\tstruct alloc_state *commit_state;\n-\tstruct alloc_state *tag_state;\n-\tstruct alloc_state *object_state;\n+\tstruct mem_pool objects_pool;\n \n \t/* parent substitutions from .git/info/grafts and .git/shallow */\n \tstruct commit_graft **grafts;\n\nbase-commit: e6362826a0409539642a5738db61827e5978e2e4\n-- \ngitgitgadget\n"}]}