On Wed, May 11, 2011 at 3:25 AM, Greg Stein <gstein_at_gmail.com> wrote:
> On Tue, May 10, 2011 at 14:14, Â <pburba_at_apache.org> wrote:
>>...
>> +++ subversion/trunk/subversion/libsvn_client/merge.c Tue May 10 18:14:22 2011
>>...
>> @@ -2989,14 +2997,15 @@ fix_deleted_subtree_ranges(const char *u
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_ra_session_t *ra_session,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â notification_receiver_baton_t *notify_b,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_cmd_baton_t *merge_b,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â apr_pool_t *pool)
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â apr_pool_t *result_pool,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â apr_pool_t *scratch_pool)
>> Â {
>> Â int i;
>> Â const char *source_root_url;
>> - Â apr_pool_t *iterpool = svn_pool_create(pool);
>> + Â apr_pool_t *iterpool = svn_pool_create(scratch_pool);
>> Â svn_boolean_t is_rollback = revision2 < revision1;
>>
>> - Â SVN_ERR(svn_ra_get_repos_root2(ra_session, &source_root_url, pool));
>> + Â SVN_ERR(svn_ra_get_repos_root2(ra_session, &source_root_url, scratch_pool));
>>
>> Â /* NOTIFY_B->CHILDREN_WITH_MERGEINFO is sorted in depth-first order, so
>> Â Â Â start at index 1 to examine only subtrees. */
>> @@ -3090,7 +3099,8 @@ fix_deleted_subtree_ranges(const char *u
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â revision1, revision2,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â child_primary_source_url,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ra_session,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->ctx, pool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->ctx, result_pool,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â iterpool));
>> Â Â Â Â }
>> Â Â }
>>
>
> iterpool is constructured and used, but never cleared or destroyed.
Hi Greg,
Which iterpool are you referring to above? The one in
fix_deleted_subtree_ranges I assume? That is cleared on line 3025 and
destroyed right before the function returns on line 3107.
>>...
>> @@ -4086,7 +4108,7 @@ populate_remaining_ranges(apr_array_head
>> Â svn_client__merge_path_t *parent;
>> Â int parent_index;
>>
>> - Â iterpool = svn_pool_create(pool);
>> + Â iterpool = svn_pool_create(scratch_pool);
>>
>> Â /* If we aren't honoring mergeinfo or this is a --record-only merge,
>> Â Â Â we'll make quick work of this by simply adding dummy REVISION1:REVISION2
>> @@ -4115,7 +4137,8 @@ populate_remaining_ranges(apr_array_head
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â child->abspath,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â MAX(revision1, revision2),
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â MIN(revision1, revision2),
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->ctx, pool, iterpool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->ctx, result_pool,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â iterpool));
>> Â Â Â Â Â Â }
>> Â Â Â Â Â else
>> Â Â Â Â Â Â {
>> @@ -4135,12 +4158,13 @@ populate_remaining_ranges(apr_array_head
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â child_inherits_implicit,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â revision1, revision2,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ra_session, merge_b->ctx,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool, iterpool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â result_pool, iterpool));
>> Â Â Â Â Â Â }
>>
>> Â Â Â Â Â child->remaining_ranges = svn_rangelist__initialize(revision1,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â revision2,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â TRUE, pool);
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â TRUE,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â result_pool);
>> Â Â Â Â }
>> Â Â Â return SVN_NO_ERROR;
>> Â Â }
>> @@ -4168,7 +4192,7 @@ populate_remaining_ranges(apr_array_head
>> Â Â Â recording mergeinfo describing this merge. */
>> Â if (SVN_IS_VALID_REVNUM(gap_start) && SVN_IS_VALID_REVNUM(gap_end))
>> Â Â merge_b->implicit_src_gap = svn_rangelist__initialize(gap_start, gap_end,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â TRUE, pool);
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â TRUE, result_pool);
>>
>> Â for (i = 0; i < children_with_mergeinfo->nelts; i++)
>> Â Â {
>> @@ -4209,7 +4233,7 @@ populate_remaining_ranges(apr_array_head
>> Â Â Â Â child->abspath,
>> Â Â Â Â MAX(revision1, revision2),
>> Â Â Â Â 0, /* Get all implicit mergeinfo */
>> - Â Â Â Â merge_b->ctx, pool, pool));
>> + Â Â Â Â merge_b->ctx, result_pool, scratch_pool));
>>
>> Â Â Â /* If CHILD isn't the merge target find its parent. */
>> Â Â Â if (i > 0)
>> @@ -4239,7 +4263,8 @@ populate_remaining_ranges(apr_array_head
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->implicit_src_gap,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â child_inherits_implicit,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ra_session,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->ctx, pool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->ctx, result_pool,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â iterpool));
>>
>> Â Â Â /* Deal with any gap in URL1_at_REVISION1:URL2_at_REVISION2's natural history.
>>
>> @@ -4297,12 +4322,12 @@ populate_remaining_ranges(apr_array_head
>> Â Â Â Â Â Â Â if (overlaps_or_adjoins)
>> Â Â Â Â Â Â Â Â SVN_ERR(svn_rangelist_merge(&(child->remaining_ranges),
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->implicit_src_gap,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â result_pool));
>> Â Â Â Â Â Â Â else /* equals == TRUE */
>> Â Â Â Â Â Â Â Â SVN_ERR(svn_rangelist_remove(&(child->remaining_ranges),
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->implicit_src_gap,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â child->remaining_ranges, FALSE,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â result_pool));
>> Â Â Â Â Â Â }
>>
>> Â Â Â Â Â if (revision1 > revision2) /* Reverse merge */
>
> iterpool is constructed and used, but never cleared or destroyed.
Hmmm, something is up. The iterpool in populate_remaining_ranges *is*
cleared: First on line 4128 for the iteration when not honoring
mergeinfo doing a --record-only merge. It is also cleared on line
4215 for the "normal" merge-tracking iteration. The pool is destroyed
at the end of the function on line 4342. There is a long-standing
leak in the first case, where we return early without destroying the
iterpool. I'll fix that, but I don't suspect that was what you were
talking about.
> Also
> note that if you defer its destruction (and maybe an earlier creation,
> too),
The iterpool is actually created at the start of the function. The
patch is a bit misleading because iterpool is needlessly declared and
then constructed on separate lines, I'll fix that.
> then you can use it as a scratch_pool. (of course, being wary
> not to use it for things that need to survive the loop, like a hash
> iter).
I do use it as a scratch pool. The only exception is the call to
get_full_mergeinfo on line 4231, which can use the iterpool as a
scratch pool (I'll change that too).
>>...
>> @@ -6242,7 +6268,8 @@ normalize_merge_sources(apr_array_header
>> Â Â Â Â Â Â Â Â Â Â Â Â const apr_array_header_t *ranges_to_merge,
>> Â Â Â Â Â Â Â Â Â Â Â Â svn_ra_session_t *ra_session,
>> Â Â Â Â Â Â Â Â Â Â Â Â svn_client_ctx_t *ctx,
>> - Â Â Â Â Â Â Â Â Â Â Â Â apr_pool_t *pool)
>> + Â Â Â Â Â Â Â Â Â Â Â Â apr_pool_t *result_pool,
>> + Â Â Â Â Â Â Â Â Â Â Â Â apr_pool_t *scratch_pool)
>> Â {
>> Â svn_revnum_t youngest_rev = SVN_INVALID_REVNUM;
>> Â svn_revnum_t peg_revnum;
>> @@ -6251,30 +6278,32 @@ normalize_merge_sources(apr_array_header
>> Â svn_revnum_t trim_revision = SVN_INVALID_REVNUM;
>> Â apr_array_header_t *merge_range_ts, *segments;
>> Â const char *source_abspath_or_url;
>> - Â apr_pool_t *subpool;
>> Â int i;
>> + Â apr_pool_t *iterpool;
>>
>> Â if(!svn_path_is_url(source))
>> - Â Â SVN_ERR(svn_dirent_get_absolute(&source_abspath_or_url, source, pool));
>> + Â Â SVN_ERR(svn_dirent_get_absolute(&source_abspath_or_url, source,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â result_pool));
>> Â else
>> Â Â source_abspath_or_url = source;
>>
>> Â /* Initialize our return variable. */
>> - Â *merge_sources_p = apr_array_make(pool, 1, sizeof(merge_source_t *));
>> + Â *merge_sources_p = apr_array_make(result_pool, 1, sizeof(merge_source_t *));
>>
>> Â /* Resolve our PEG_REVISION to a real number. */
>> Â SVN_ERR(svn_client__get_revision_number(&peg_revnum, &youngest_rev,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ctx->wc_ctx,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â source_abspath_or_url,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ra_session, peg_revision, pool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ra_session, peg_revision,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool));
>> Â if (! SVN_IS_VALID_REVNUM(peg_revnum))
>> Â Â return svn_error_create(SVN_ERR_CLIENT_BAD_REVISION, NULL, NULL);
>>
>> Â /* Create a list to hold svn_merge_range_t's. */
>> - Â merge_range_ts = apr_array_make(pool, ranges_to_merge->nelts,
>> + Â merge_range_ts = apr_array_make(scratch_pool, ranges_to_merge->nelts,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â sizeof(svn_merge_range_t *));
>>
>> - Â subpool = svn_pool_create(pool);
>> + Â iterpool = svn_pool_create(scratch_pool);
>
> If you created the iterpool earlier, then you could use it as a
> scratch_pool for many of the above calls.
Well only svn_client__get_revision_number can benefit in that way, but
it's something, done r1101957
> The memory will get free'd
> on the first iteration of the loop, rather than be returned in the
> caller's scratch_pool (again: minimize the high-water mark).
>
>>...
>> @@ -6318,6 +6348,8 @@ normalize_merge_sources(apr_array_header
>> Â Â Â Â }
>> Â Â }
>>
>> + Â svn_pool_destroy(iterpool);
>> +
>> Â /* No ranges to merge? Â No problem. */
>> Â if (merge_range_ts->nelts == 0)
>> Â Â return SVN_NO_ERROR;
>
> Again, you may be able to defer the destruction of the iterpool for
> some benefit. (tho it complicates the early-exit a bit)
Done r1101957
>>...
>> @@ -6661,12 +6695,11 @@ do_file_merge(svn_mergeinfo_catalog_t re
>> Â Â Â APR_ARRAY_PUSH(remaining_ranges, svn_merge_range_t *) = ⦥
>> Â Â }
>>
>> - Â subpool = svn_pool_create(scratch_pool);
>> -
>> Â if (!merge_b->record_only)
>> Â Â {
>> Â Â Â apr_array_header_t *ranges_to_merge = remaining_ranges;
>> Â Â Â int i;
>> + Â Â Â apr_pool_t *iterpool;
>>
>> Â Â Â /* If we have ancestrally related sources and more than one
>> Â Â Â Â Â range to merge, eliminate no-op ranges before going through
>> @@ -6677,16 +6710,18 @@ do_file_merge(svn_mergeinfo_catalog_t re
>> Â Â Â Â Â const char *old_sess_url = NULL;
>> Â Â Â Â Â SVN_ERR(svn_client__ensure_ra_session_url(&old_sess_url,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->ra_session1,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â primary_url, subpool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â primary_url,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool));
>> Â Â Â Â Â SVN_ERR(remove_noop_merge_ranges(&ranges_to_merge,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_b->ra_session1,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â remaining_ranges, subpool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â remaining_ranges, scratch_pool));
>> Â Â Â Â Â if (old_sess_url)
>> Â Â Â Â Â Â SVN_ERR(svn_ra_reparent(merge_b->ra_session1, old_sess_url,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â subpool));
>> - Â Â Â Â Â svn_pool_clear(subpool);
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool));
>> Â Â Â Â }
>>
>> + Â Â Â iterpool = svn_pool_create(scratch_pool);
>
> Again: earlier construction of the pool could have some benefit for
> several of the calls above. It looks like you already had a clear()
> for the old subpool... by using iterpool, you'll still get that
> clear() on the first iteration.
Ok, there is a lot of opportunity to do as you suggest in this
function. Done r1101957
>>...
>> @@ -8090,7 +8127,7 @@ do_directory_merge(svn_mergeinfo_catalog
>> Â if (honor_mergeinfo && !merge_b->reintegrate_merge)
>> Â Â {
>> Â Â Â svn_revnum_t new_range_start, start_rev, end_rev;
>> - Â Â Â apr_pool_t *iterpool = svn_pool_create(pool);
>> + Â Â Â apr_pool_t *iterpool = svn_pool_create(scratch_pool);
>>
>> Â Â Â /* The merge target TARGET_ABSPATH and/or its subtrees may not need all
>> Â Â Â Â Â of REVISION1:REVISION2 applied. Â So examine
>> @@ -8112,11 +8149,12 @@ do_directory_merge(svn_mergeinfo_catalog
>> Â Â Â Â SVN_ERR(remove_noop_subtree_ranges(url1, revision1, url2, revision2,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ra_session,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â notify_b, merge_b,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool, iterpool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool, iterpool));
>>
>> Â Â Â /* Adjust subtrees' remaining_ranges to deal with issue #3067 */
>> Â Â Â SVN_ERR(fix_deleted_subtree_ranges(url1, revision1, url2, revision2,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ra_session, notify_b, merge_b, pool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ra_session, notify_b, merge_b,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool, iterpool));
>>
>> Â Â Â /* remove_noop_subtree_ranges() and/or fix_deleted_subtree_range()
>> Â Â Â Â Â may have further refined the starting revision for our editor
>
> I see iterpool being created and used, but not cleared or destroyed.
And once again it is cleared on line 8248 and destroyed on line 8345.
I feel like we are looking at different code!
>>...
>> @@ -8465,6 +8505,7 @@ do_merge(apr_hash_t **modified_subtrees,
>> Â svn_boolean_t checked_mergeinfo_capability = FALSE;
>> Â svn_ra_session_t *ra_session1 = NULL, *ra_session2 = NULL;
>> Â svn_node_kind_t target_kind;
>> + Â apr_pool_t *iterpool;
>>
>> Â SVN_ERR_ASSERT(svn_dirent_is_absolute(target_abspath));
>>
>> @@ -8491,7 +8532,7 @@ do_merge(apr_hash_t **modified_subtrees,
>> Â Â }
>>
>> Â SVN_ERR(svn_wc_read_kind(&target_kind, ctx->wc_ctx, target_abspath, FALSE,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â pool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool));
>>
>> Â if (target_kind != svn_node_dir && target_kind != svn_node_file)
>> Â Â return svn_error_createf(SVN_ERR_ILLEGAL_TARGET, NULL,
>> @@ -8509,7 +8550,7 @@ do_merge(apr_hash_t **modified_subtrees,
>> Â Â Â Â Â Â Â Â Â SVN_CONFIG_OPTION_DIFF3_CMD, NULL);
>>
>> Â if (diff3_cmd != NULL)
>> - Â Â SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, pool));
>> + Â Â SVN_ERR(svn_path_cstring_to_utf8(&diff3_cmd, diff3_cmd, scratch_pool));
>>
>> Â /* Build the merge context baton (or at least the parts of it that
>> Â Â Â don't need to be reset for each merge source). Â */
>> @@ -8527,8 +8568,10 @@ do_merge(apr_hash_t **modified_subtrees,
>> Â SVN_ERR(svn_wc__node_get_repos_info(&merge_cmd_baton.repos_root_url, NULL,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ctx->wc_ctx,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â merge_cmd_baton.target_abspath,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â pool, subpool));
>> - Â merge_cmd_baton.pool = subpool;
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â result_pool,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool));
>> + Â iterpool = svn_pool_create(scratch_pool);
>
> Again, you may see some benefit from creating iterpool sooner, and
> destroying it later.
Done r1101957
>>...
>> @@ -8702,7 +8749,7 @@ merge_cousins_and_supplement_mergeinfo(c
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â const apr_array_header_t *merge_options,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_boolean_t *use_sleep,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â svn_client_ctx_t *ctx,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â apr_pool_t *pool)
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â apr_pool_t *scratch_pool)
>> Â {
>> Â svn_opt_revision_range_t *range;
>> Â apr_array_header_t *remove_sources, *add_sources, *ranges;
>> @@ -8710,6 +8757,12 @@ merge_cousins_and_supplement_mergeinfo(c
>> Â svn_boolean_t same_repos;
>> Â apr_hash_t *modified_subtrees = NULL;
>>
>> + Â /* Sure we could use SCRATCH_POOL througout this function, but since this
>> + Â Â is a wrapper around three separate merges we'll create a subpool we can
>> + Â Â clear between each of the three. Â If the merge target has a lot of
>> + Â Â subtree mergeinfo, then this will help keep memory use in check. */
>> + Â apr_pool_t *subpool = svn_pool_create(scratch_pool);
>> +
>> Â SVN_ERR_ASSERT(svn_dirent_is_absolute(target_abspath));
>>
>> Â if (strcmp(wc_repos_root, source_repos_root) != 0)
>> @@ -8717,9 +8770,10 @@ merge_cousins_and_supplement_mergeinfo(c
>> Â Â Â const char *source_repos_uuid;
>> Â Â Â const char *wc_repos_uuid;
>>
>> - Â Â Â SVN_ERR(svn_ra_get_uuid2(URL1_ra_session, &source_repos_uuid, pool));
>> + Â Â Â SVN_ERR(svn_ra_get_uuid2(URL1_ra_session, &source_repos_uuid,
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â scratch_pool));
>> Â Â Â SVN_ERR(svn_client_uuid_from_path2(&wc_repos_uuid, target_abspath,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ctx, pool, pool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ctx, scratch_pool, scratch_pool));
>> Â Â Â same_repos = (strcmp(wc_repos_uuid, source_repos_uuid) == 0);
>> Â Â }
>
> Looks like these UUIDs have a very short lifetime. Could they use the subpool?
They can, done r1101957
>>...
>> @@ -10052,26 +10131,28 @@ calculate_left_hand_side(const char **ur
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â path_rel_to_session,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â target_rev, target_rev,
>> Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â SVN_INVALID_REVNUM,
>> - Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ctx, subpool));
>> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â ctx, scratch_pool));
>> Â Â Â apr_hash_set(segments_hash,
>> - Â Â Â Â Â Â Â Â Â apr_pstrdup(subpool, path_rel_to_root),
>> + Â Â Â Â Â Â Â Â Â apr_pstrdup(scratch_pool, path_rel_to_root),
>> Â Â Â Â Â Â Â Â Â Â APR_HASH_KEY_STRING, segments);
>> Â Â }
>>
>> + Â svn_pool_destroy(iterpool);
>
> You'd probably get benefit from delaying this destruction.
Done, r1101957
Paul
>>...
>>
>> [... 36 lines stripped ...]
>>
>
> I guess that's the end of the review :-P
>
> Cheers,
> -g
>
Received on 2011-05-11 18:34:00 CEST