You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2014/04/27 15:45:50 UTC

svn commit: r1590393 - in /subversion/trunk/subversion: include/svn_fs.h libsvn_fs/fs-loader.c libsvn_fs/fs-loader.h libsvn_fs_base/tree.c libsvn_fs_fs/tree.c libsvn_fs_x/tree.c libsvn_repos/log.c libsvn_repos/rev_hunt.c

Author: stefan2
Date: Sun Apr 27 13:45:49 2014
New Revision: 1590393

URL: http://svn.apache.org/r1590393
Log:
Fix excessive memory usage during 'svn log -g' with FSFS / FSX.

The root cause is that in --include-merges mode, we recursively
call do_log() such that outer iteration are suddenly long-lived.
In turn, DAG nodes used temporarily in some sub-function are kept
along with a lock on the DAG node cache.  The inability to garbage
collect that cache results in hundreds of MB dynamic memory usage
for some repos.

This patch revs two history related FS API functions to using the
two-pool paradigm.  It allows all DAG nodes to be released early
because they are all temporaries used inside those functions.

Implement API bump in all backends, update the callers and tighten
pool usage where appropriate.

* subversion/include/svn_fs.h
  (svn_fs_node_history2): New, two-pool version of ...
  (svn_fs_node_history): ... this now deprecated API.
  (svn_fs_history_prev2): New, two-pool version of ...
  (svn_fs_history_prev): ... this now deprecated API.

* subversion/libsvn_fs/fs-loader.h
  (root_vtable_t,
   history_vtable_t): Make the vtable entries match the bumped API.

* subversion/libsvn_fs/fs-loader.c
  (svn_fs_node_history2): Implement new API as vtable call.
  (svn_fs_node_history): Call the bumped vtable entry directly.
  (svn_fs_history_prev2): Implement new API as vtable call.
  (svn_fs_history_prev): Call the bumped vtable entry directly.

* subversion/libsvn_fs_base/tree.c
  (base_node_history): Update implementation and use the SCRATCH_POOL
                       for the one temporary that we have.
  (base_history_prev): Update signature and always use the RESULT_POOL
                       as there are no easy to identify temporaries.

* subversion/libsvn_fs_fs/tree.c
  (fs_node_history): Update implementation and use the SCRATCH_POOL
                     for the one temporary that we have.
  (fs_history_prev): Update implementation and laverage the already
                     existing two-pool capability of history_prev().

* subversion/libsvn_fs_x/tree.c
  (x_node_history,
   fs_history_prev): Do the same in FSX as we did for FSFS.

* subversion/libsvn_repos/log.c
  (detect_changed): Bump API calls with no extra benefit.
  (get_history): Switch to two-pool paradigm and call the bumped API
                 with those separate pools.  Use the SCRATCH_POOL in
                 authentication.
  (check_history): Switch to two-pool paradigm and call the bumped API
                   with those separate pools.
  (get_path_histories): Use the ITERPOOL as scratch pool for called funcs.
  (do_logs): Use a separate iteration pool for the inner loop such that
             we may clean it up right after check_history and before
             going into do_log recursion.

* subversion/libsvn_repos/rev_hunt.c
  (svn_repos_history2,
   check_ancestry_of_peg_path): Bump API calls and use the pool that
                                will be cleaned up next as scratch.
  (find_interesting_revisions): Bump API calls with no extra benefit.
  (get_file_revs_backwards): Bump API calls and use the pool that
                             will be cleaned up next as scratch.

Modified:
    subversion/trunk/subversion/include/svn_fs.h
    subversion/trunk/subversion/libsvn_fs/fs-loader.c
    subversion/trunk/subversion/libsvn_fs/fs-loader.h
    subversion/trunk/subversion/libsvn_fs_base/tree.c
    subversion/trunk/subversion/libsvn_fs_fs/tree.c
    subversion/trunk/subversion/libsvn_fs_x/tree.c
    subversion/trunk/subversion/libsvn_repos/log.c
    subversion/trunk/subversion/libsvn_repos/rev_hunt.c

Modified: subversion/trunk/subversion/include/svn_fs.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_fs.h?rev=1590393&r1=1590392&r2=1590393&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_fs.h (original)
+++ subversion/trunk/subversion/include/svn_fs.h Sun Apr 27 13:45:49 2014
@@ -1507,8 +1507,24 @@ typedef struct svn_fs_history_t svn_fs_h
 
 /** Set @a *history_p to an opaque node history object which
  * represents @a path under @a root.  @a root must be a revision root.
- * Use @a pool for all allocations.
+ * Allocate the result in @a result_pool and use @a scratch_pool for
+ * temporary allocations.
+ *
+ * @since New in 1.9.
+ */
+svn_error_t *
+svn_fs_node_history2(svn_fs_history_t **history_p,
+                     svn_fs_root_t *root,
+                     const char *path,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool);
+
+/** Same as svn_fs_node_history2() but using a single @a pool for all
+ * allocations.
+ *
+ * @deprecated Provided for backward compatibility with the 1.8 API.
  */
+SVN_DEPRECATED
 svn_error_t *
 svn_fs_node_history(svn_fs_history_t **history_p,
                     svn_fs_root_t *root,
@@ -1541,7 +1557,25 @@ svn_fs_node_history(svn_fs_history_t **h
  * the same age as the revision of that path in @a root.  That is, if
  * @a root is a revision root based on revision X, and @a path was
  * modified in some revision(s) younger than X, those revisions
- * younger than X will not be included for @a path.  */
+ * younger than X will not be included for @a path.
+ *
+ * Allocate the result in @a result_pool and use @a scratch_pool for
+ * temporary allocations.
+ *
+ * @since New in 1.9. */
+svn_error_t *
+svn_fs_history_prev2(svn_fs_history_t **prev_history_p,
+                     svn_fs_history_t *history,
+                     svn_boolean_t cross_copies,
+                     apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool);
+
+/** Same as svn_fs_history_prev2() but using a single @a pool for all
+ * allocations.
+ *
+ * @deprecated Provided for backward compatibility with the 1.8 API.
+ */
+SVN_DEPRECATED
 svn_error_t *
 svn_fs_history_prev(svn_fs_history_t **prev_history_p,
                     svn_fs_history_t *history,

Modified: subversion/trunk/subversion/libsvn_fs/fs-loader.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/fs-loader.c?rev=1590393&r1=1590392&r2=1590393&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs/fs-loader.c (original)
+++ subversion/trunk/subversion/libsvn_fs/fs-loader.c Sun Apr 27 13:45:49 2014
@@ -1077,11 +1077,21 @@ svn_fs_check_path(svn_node_kind_t *kind_
 }
 
 svn_error_t *
+svn_fs_node_history2(svn_fs_history_t **history_p, svn_fs_root_t *root,
+                     const char *path, apr_pool_t *result_pool,
+                     apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(root->vtable->node_history(history_p, root, path,
+                                                    result_pool,
+                                                    scratch_pool));
+}
+
+svn_error_t *
 svn_fs_node_history(svn_fs_history_t **history_p, svn_fs_root_t *root,
                     const char *path, apr_pool_t *pool)
 {
   return svn_error_trace(root->vtable->node_history(history_p, root, path,
-                                                    pool));
+                                                    pool, pool));
 }
 
 svn_error_t *
@@ -1835,12 +1845,22 @@ svn_fs_get_locks(svn_fs_t *fs, const cha
 /* --- History functions --- */
 
 svn_error_t *
+svn_fs_history_prev2(svn_fs_history_t **prev_history_p,
+                     svn_fs_history_t *history, svn_boolean_t cross_copies,
+                     apr_pool_t *result_pool, apr_pool_t *scratch_pool)
+{
+  return svn_error_trace(history->vtable->prev(prev_history_p, history,
+                                               cross_copies, result_pool,
+                                               scratch_pool));
+}
+
+svn_error_t *
 svn_fs_history_prev(svn_fs_history_t **prev_history_p,
                     svn_fs_history_t *history, svn_boolean_t cross_copies,
                     apr_pool_t *pool)
 {
   return svn_error_trace(history->vtable->prev(prev_history_p, history,
-                                               cross_copies, pool));
+                                               cross_copies, pool, pool));
 }
 
 svn_error_t *

Modified: subversion/trunk/subversion/libsvn_fs/fs-loader.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs/fs-loader.h?rev=1590393&r1=1590392&r2=1590393&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs/fs-loader.h (original)
+++ subversion/trunk/subversion/libsvn_fs/fs-loader.h Sun Apr 27 13:45:49 2014
@@ -305,7 +305,8 @@ typedef struct root_vtable_t
                              const char *path, apr_pool_t *pool);
   svn_error_t *(*node_history)(svn_fs_history_t **history_p,
                                svn_fs_root_t *root, const char *path,
-                               apr_pool_t *pool);
+                               apr_pool_t *result_pool,
+                               apr_pool_t *scratch_pool);
   svn_error_t *(*node_id)(const svn_fs_id_t **id_p, svn_fs_root_t *root,
                           const char *path, apr_pool_t *pool);
   svn_error_t *(*node_relation)(svn_fs_node_relation_t *relation,
@@ -427,7 +428,7 @@ typedef struct history_vtable_t
 {
   svn_error_t *(*prev)(svn_fs_history_t **prev_history_p,
                        svn_fs_history_t *history, svn_boolean_t cross_copies,
-                       apr_pool_t *pool);
+                       apr_pool_t *result_pool, apr_pool_t *scratch_pool);
   svn_error_t *(*location)(const char **path, svn_revnum_t *revision,
                            svn_fs_history_t *history, apr_pool_t *pool);
 } history_vtable_t;

Modified: subversion/trunk/subversion/libsvn_fs_base/tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_base/tree.c?rev=1590393&r1=1590392&r2=1590393&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_base/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_base/tree.c Sun Apr 27 13:45:49 2014
@@ -4224,7 +4224,8 @@ static svn_error_t *
 base_node_history(svn_fs_history_t **history_p,
                   svn_fs_root_t *root,
                   const char *path,
-                  apr_pool_t *pool)
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   svn_node_kind_t kind;
 
@@ -4233,15 +4234,16 @@ base_node_history(svn_fs_history_t **his
     return svn_error_create(SVN_ERR_FS_NOT_REVISION_ROOT, NULL, NULL);
 
   /* And we require that the path exist in the root. */
-  SVN_ERR(base_check_path(&kind, root, path, pool));
+  SVN_ERR(base_check_path(&kind, root, path, scratch_pool));
   if (kind == svn_node_none)
     return SVN_FS__NOT_FOUND(root, path);
 
   /* Okay, all seems well.  Build our history object and return it. */
   *history_p = assemble_history(root->fs,
-                                svn_fs__canonicalize_abspath(path, pool),
+                                svn_fs__canonicalize_abspath(path,
+                                                             result_pool),
                                 root->rev, FALSE, NULL,
-                                SVN_INVALID_REVNUM, pool);
+                                SVN_INVALID_REVNUM, result_pool);
   return SVN_NO_ERROR;
 }
 
@@ -4491,7 +4493,8 @@ static svn_error_t *
 base_history_prev(svn_fs_history_t **prev_history_p,
                   svn_fs_history_t *history,
                   svn_boolean_t cross_copies,
-                  apr_pool_t *pool)
+                  apr_pool_t *result_pool,
+                  apr_pool_t *scratch_pool)
 {
   svn_fs_history_t *prev_history = NULL;
   base_history_data_t *bhd = history->fsap_data;
@@ -4505,10 +4508,12 @@ base_history_prev(svn_fs_history_t **pre
     {
       if (! bhd->is_interesting)
         prev_history = assemble_history(fs, "/", bhd->revision,
-                                        1, NULL, SVN_INVALID_REVNUM, pool);
+                                        1, NULL, SVN_INVALID_REVNUM,
+                                        result_pool);
       else if (bhd->revision > 0)
         prev_history = assemble_history(fs, "/", bhd->revision - 1,
-                                        1, NULL, SVN_INVALID_REVNUM, pool);
+                                        1, NULL, SVN_INVALID_REVNUM,
+                                        result_pool);
     }
   else
     {
@@ -4522,9 +4527,9 @@ base_history_prev(svn_fs_history_t **pre
           args.prev_history_p = &prev_history;
           args.history = prev_history;
           args.cross_copies = cross_copies;
-          args.pool = pool;
+          args.pool = result_pool;
           SVN_ERR(svn_fs_base__retry_txn(fs, txn_body_history_prev, &args,
-                                         FALSE, pool));
+                                         FALSE, result_pool));
           if (! prev_history)
             break;
           bhd = prev_history->fsap_data;

Modified: subversion/trunk/subversion/libsvn_fs_fs/tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_fs/tree.c?rev=1590393&r1=1590392&r2=1590393&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_fs/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_fs/tree.c Sun Apr 27 13:45:49 2014
@@ -3474,7 +3474,8 @@ static svn_error_t *
 fs_node_history(svn_fs_history_t **history_p,
                 svn_fs_root_t *root,
                 const char *path,
-                apr_pool_t *pool)
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
 {
   svn_node_kind_t kind;
 
@@ -3483,13 +3484,13 @@ fs_node_history(svn_fs_history_t **histo
     return svn_error_create(SVN_ERR_FS_NOT_REVISION_ROOT, NULL, NULL);
 
   /* And we require that the path exist in the root. */
-  SVN_ERR(svn_fs_fs__check_path(&kind, root, path, pool));
+  SVN_ERR(svn_fs_fs__check_path(&kind, root, path, scratch_pool));
   if (kind == svn_node_none)
     return SVN_FS__NOT_FOUND(root, path);
 
   /* Okay, all seems well.  Build our history object and return it. */
   *history_p = assemble_history(root->fs, path, root->rev, FALSE, NULL,
-                                SVN_INVALID_REVNUM, pool);
+                                SVN_INVALID_REVNUM, result_pool);
   return SVN_NO_ERROR;
 }
 
@@ -3932,7 +3933,8 @@ static svn_error_t *
 fs_history_prev(svn_fs_history_t **prev_history_p,
                 svn_fs_history_t *history,
                 svn_boolean_t cross_copies,
-                apr_pool_t *pool)
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
 {
   svn_fs_history_t *prev_history = NULL;
   fs_history_data_t *fhd = history->fsap_data;
@@ -3946,10 +3948,12 @@ fs_history_prev(svn_fs_history_t **prev_
     {
       if (! fhd->is_interesting)
         prev_history = assemble_history(fs, "/", fhd->revision,
-                                        1, NULL, SVN_INVALID_REVNUM, pool);
+                                        1, NULL, SVN_INVALID_REVNUM,
+                                        result_pool);
       else if (fhd->revision > 0)
         prev_history = assemble_history(fs, "/", fhd->revision - 1,
-                                        1, NULL, SVN_INVALID_REVNUM, pool);
+                                        1, NULL, SVN_INVALID_REVNUM,
+                                        result_pool);
     }
   else
     {
@@ -3958,7 +3962,7 @@ fs_history_prev(svn_fs_history_t **prev_
       while (1)
         {
           SVN_ERR(history_prev(&prev_history, prev_history, cross_copies,
-                               pool, pool));
+                               result_pool, scratch_pool));
 
           if (! prev_history)
             break;

Modified: subversion/trunk/subversion/libsvn_fs_x/tree.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_fs_x/tree.c?rev=1590393&r1=1590392&r2=1590393&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_fs_x/tree.c (original)
+++ subversion/trunk/subversion/libsvn_fs_x/tree.c Sun Apr 27 13:45:49 2014
@@ -3383,7 +3383,8 @@ static svn_error_t *
 x_node_history(svn_fs_history_t **history_p,
                svn_fs_root_t *root,
                const char *path,
-               apr_pool_t *pool)
+               apr_pool_t *result_pool,
+               apr_pool_t *scratch_pool)
 {
   svn_node_kind_t kind;
 
@@ -3392,15 +3393,16 @@ x_node_history(svn_fs_history_t **histor
     return svn_error_create(SVN_ERR_FS_NOT_REVISION_ROOT, NULL, NULL);
 
   /* And we require that the path exist in the root. */
-  SVN_ERR(svn_fs_x__check_path(&kind, root, path, pool));
+  SVN_ERR(svn_fs_x__check_path(&kind, root, path, scratch_pool));
   if (kind == svn_node_none)
     return SVN_FS__NOT_FOUND(root, path);
 
   /* Okay, all seems well.  Build our history object and return it. */
   *history_p = assemble_history(root->fs,
-                                svn_fs__canonicalize_abspath(path, pool),
+                                svn_fs__canonicalize_abspath(path,
+                                                             result_pool),
                                 root->rev, FALSE, NULL,
-                                SVN_INVALID_REVNUM, pool);
+                                SVN_INVALID_REVNUM, result_pool);
   return SVN_NO_ERROR;
 }
 
@@ -3702,7 +3704,8 @@ static svn_error_t *
 fs_history_prev(svn_fs_history_t **prev_history_p,
                 svn_fs_history_t *history,
                 svn_boolean_t cross_copies,
-                apr_pool_t *pool)
+                apr_pool_t *result_pool,
+                apr_pool_t *scratch_pool)
 {
   svn_fs_history_t *prev_history = NULL;
   fs_history_data_t *fhd = history->fsap_data;
@@ -3716,10 +3719,12 @@ fs_history_prev(svn_fs_history_t **prev_
     {
       if (! fhd->is_interesting)
         prev_history = assemble_history(fs, "/", fhd->revision,
-                                        1, NULL, SVN_INVALID_REVNUM, pool);
+                                        1, NULL, SVN_INVALID_REVNUM,
+                                        result_pool);
       else if (fhd->revision > 0)
         prev_history = assemble_history(fs, "/", fhd->revision - 1,
-                                        1, NULL, SVN_INVALID_REVNUM, pool);
+                                        1, NULL, SVN_INVALID_REVNUM,
+                                        result_pool);
     }
   else
     {
@@ -3728,7 +3733,7 @@ fs_history_prev(svn_fs_history_t **prev_
       while (1)
         {
           SVN_ERR(history_prev(&prev_history, prev_history, cross_copies,
-                               pool, pool));
+                               result_pool, scratch_pool));
 
           if (! prev_history)
             break;

Modified: subversion/trunk/subversion/libsvn_repos/log.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/log.c?rev=1590393&r1=1590392&r2=1590393&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/log.c (original)
+++ subversion/trunk/subversion/libsvn_repos/log.c Sun Apr 27 13:45:49 2014
@@ -425,13 +425,15 @@ detect_changed(apr_hash_t **changed,
 
               svn_fspath__split(&parent_path, &name, path, subpool);
 
-              SVN_ERR(svn_fs_node_history(&history, root, parent_path,
-                                          subpool));
+              SVN_ERR(svn_fs_node_history2(&history, root, parent_path,
+                                           subpool, subpool));
 
               /* Two calls because the first call returns the original
                  revision as the deleted child means it is 'interesting' */
-              SVN_ERR(svn_fs_history_prev(&history, history, TRUE, subpool));
-              SVN_ERR(svn_fs_history_prev(&history, history, TRUE, subpool));
+              SVN_ERR(svn_fs_history_prev2(&history, history, TRUE, subpool,
+                                           subpool));
+              SVN_ERR(svn_fs_history_prev2(&history, history, TRUE, subpool,
+                                           subpool));
 
               SVN_ERR(svn_fs_history_location(&parent_path, &prev_rev, history,
                                               subpool));
@@ -567,7 +569,8 @@ get_history(struct path_info *info,
             svn_repos_authz_func_t authz_read_func,
             void *authz_read_baton,
             svn_revnum_t start,
-            apr_pool_t *pool)
+            apr_pool_t *result_pool,
+            apr_pool_t *scratch_pool)
 {
   svn_fs_root_t *history_root = NULL;
   svn_fs_history_t *hist;
@@ -578,27 +581,30 @@ get_history(struct path_info *info,
     {
       subpool = info->newpool;
 
-      SVN_ERR(svn_fs_history_prev(&info->hist, info->hist, ! strict, subpool));
+      SVN_ERR(svn_fs_history_prev2(&info->hist, info->hist, ! strict,
+                                   subpool, scratch_pool));
 
       hist = info->hist;
     }
   else
     {
-      subpool = svn_pool_create(pool);
+      subpool = svn_pool_create(result_pool);
 
       /* Open the history located at the last rev we were at. */
       SVN_ERR(svn_fs_revision_root(&history_root, fs, info->history_rev,
                                    subpool));
 
-      SVN_ERR(svn_fs_node_history(&hist, history_root, info->path->data,
-                                  subpool));
+      SVN_ERR(svn_fs_node_history2(&hist, history_root, info->path->data,
+                                   subpool, scratch_pool));
 
-      SVN_ERR(svn_fs_history_prev(&hist, hist, ! strict, subpool));
+      SVN_ERR(svn_fs_history_prev2(&hist, hist, ! strict, subpool,
+                                   scratch_pool));
 
       if (info->first_time)
         info->first_time = FALSE;
       else
-        SVN_ERR(svn_fs_history_prev(&hist, hist, ! strict, subpool));
+        SVN_ERR(svn_fs_history_prev2(&hist, hist, ! strict, subpool,
+                                     scratch_pool));
     }
 
   if (! hist)
@@ -633,11 +639,11 @@ get_history(struct path_info *info,
       svn_boolean_t readable;
       SVN_ERR(svn_fs_revision_root(&history_root, fs,
                                    info->history_rev,
-                                   subpool));
+                                   scratch_pool));
       SVN_ERR(authz_read_func(&readable, history_root,
                               info->path->data,
                               authz_read_baton,
-                              subpool));
+                              scratch_pool));
       if (! readable)
         info->done = TRUE;
     }
@@ -675,7 +681,8 @@ check_history(svn_boolean_t *changed,
               svn_repos_authz_func_t authz_read_func,
               void *authz_read_baton,
               svn_revnum_t start,
-              apr_pool_t *pool)
+              apr_pool_t *result_pool,
+              apr_pool_t *scratch_pool)
 {
   /* If we're already done with histories for this path,
      don't try to fetch any more. */
@@ -694,7 +701,7 @@ check_history(svn_boolean_t *changed,
      rev where this path was changed. */
   *changed = TRUE;
   return get_history(info, fs, strict, authz_read_func,
-                     authz_read_baton, start, pool);
+                     authz_read_baton, start, result_pool, scratch_pool);
 }
 
 /* Return the next interesting revision in our list of HISTORIES. */
@@ -1539,13 +1546,11 @@ get_path_histories(apr_array_header_t **
       const char *this_path = APR_ARRAY_IDX(paths, i, const char *);
       struct path_info *info = apr_palloc(pool,
                                           sizeof(struct path_info));
+      svn_pool_clear(iterpool);
 
       if (authz_read_func)
         {
           svn_boolean_t readable;
-
-          svn_pool_clear(iterpool);
-
           SVN_ERR(authz_read_func(&readable, root, this_path,
                                   authz_read_baton, iterpool));
           if (! readable)
@@ -1559,7 +1564,8 @@ get_path_histories(apr_array_header_t **
 
       if (i < MAX_OPEN_HISTORIES)
         {
-          err = svn_fs_node_history(&info->hist, root, this_path, pool);
+          err = svn_fs_node_history2(&info->hist, root, this_path, pool,
+                                     iterpool);
           if (err
               && ignore_missing_locations
               && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
@@ -1583,7 +1589,7 @@ get_path_histories(apr_array_header_t **
       err = get_history(info, fs,
                         strict_node_history,
                         authz_read_func, authz_read_baton,
-                        hist_start, pool);
+                        hist_start, pool, iterpool);
       if (err
           && ignore_missing_locations
           && (err->apr_err == SVN_ERR_FS_NOT_FOUND ||
@@ -2117,7 +2123,7 @@ do_logs(svn_fs_t *fs,
         void *authz_read_baton,
         apr_pool_t *pool)
 {
-  apr_pool_t *iterpool;
+  apr_pool_t *iterpool, *iterpool2;
   apr_pool_t *subpool = NULL;
   apr_array_header_t *revs = NULL;
   apr_hash_t *rev_mergeinfo = NULL;
@@ -2153,6 +2159,7 @@ do_logs(svn_fs_t *fs,
      where a path was changed to the array, or if they wanted
      history in reverse order just send it to them right away. */
   iterpool = svn_pool_create(pool);
+  iterpool2 = svn_pool_create(pool);
   for (current = hist_end;
        any_histories_left;
        current = next_history_rev(histories))
@@ -2166,14 +2173,19 @@ do_logs(svn_fs_t *fs,
           struct path_info *info = APR_ARRAY_IDX(histories, i,
                                                  struct path_info *);
 
+          svn_pool_clear(iterpool2);
+
           /* Check history for this path in current rev. */
           SVN_ERR(check_history(&changed, info, fs, current,
                                 strict_node_history, authz_read_func,
-                                authz_read_baton, hist_start, pool));
+                                authz_read_baton, hist_start, pool,
+                                iterpool2));
           if (! info->done)
             any_histories_left = TRUE;
         }
 
+      svn_pool_clear(iterpool2);
+
       /* If any of the paths changed in this rev then add or send it. */
       if (changed)
         {
@@ -2283,6 +2295,7 @@ do_logs(svn_fs_t *fs,
             }
         }
     }
+  svn_pool_destroy(iterpool2);
   svn_pool_destroy(iterpool);
 
   if (subpool)

Modified: subversion/trunk/subversion/libsvn_repos/rev_hunt.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/rev_hunt.c?rev=1590393&r1=1590392&r2=1590393&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/rev_hunt.c (original)
+++ subversion/trunk/subversion/libsvn_repos/rev_hunt.c Sun Apr 27 13:45:49 2014
@@ -231,7 +231,7 @@ svn_repos_history2(svn_fs_t *fs,
         return svn_error_create(SVN_ERR_AUTHZ_UNREADABLE, NULL, NULL);
     }
 
-  SVN_ERR(svn_fs_node_history(&history, root, path, oldpool));
+  SVN_ERR(svn_fs_node_history2(&history, root, path, oldpool, oldpool));
 
   /* Now, we loop over the history items, calling svn_fs_history_prev(). */
   do
@@ -242,7 +242,8 @@ svn_repos_history2(svn_fs_t *fs,
       apr_pool_t *tmppool;
       svn_error_t *err;
 
-      SVN_ERR(svn_fs_history_prev(&history, history, cross_copies, newpool));
+      SVN_ERR(svn_fs_history_prev2(&history, history, cross_copies, newpool,
+                                   oldpool));
 
       /* Only continue if there is further history to deal with. */
       if (! history)
@@ -523,7 +524,7 @@ check_ancestry_of_peg_path(svn_boolean_t
 
   SVN_ERR(svn_fs_revision_root(&root, fs, future_revision, pool));
 
-  SVN_ERR(svn_fs_node_history(&history, root, fs_path, lastpool));
+  SVN_ERR(svn_fs_node_history2(&history, root, fs_path, lastpool, lastpool));
 
   /* Since paths that are different according to strcmp may still be
      equivalent (due to number of consecutive slashes and the fact that
@@ -536,7 +537,8 @@ check_ancestry_of_peg_path(svn_boolean_t
     {
       apr_pool_t *tmppool;
 
-      SVN_ERR(svn_fs_history_prev(&history, history, TRUE, currpool));
+      SVN_ERR(svn_fs_history_prev2(&history, history, TRUE, currpool,
+                                   lastpool));
 
       if (!history)
         break;
@@ -1116,7 +1118,8 @@ find_interesting_revisions(apr_array_hea
        path, end);
 
   /* Open a history object. */
-  SVN_ERR(svn_fs_node_history(&history, root, path, scratch_pool));
+  SVN_ERR(svn_fs_node_history2(&history, root, path, scratch_pool,
+                               scratch_pool));
   while (1)
     {
       struct path_revision *path_rev;
@@ -1127,7 +1130,8 @@ find_interesting_revisions(apr_array_hea
       svn_pool_clear(iterpool);
 
       /* Fetch the history object to walk through. */
-      SVN_ERR(svn_fs_history_prev(&history, history, TRUE, iterpool));
+      SVN_ERR(svn_fs_history_prev2(&history, history, TRUE, iterpool,
+                                   iterpool));
       if (!history)
         break;
       SVN_ERR(svn_fs_history_location(&tmp_path, &tmp_revnum,
@@ -1453,7 +1457,7 @@ get_file_revs_backwards(svn_repos_t *rep
                              path, end);
 
   /* Open a history object. */
-  SVN_ERR(svn_fs_node_history(&history, root, path, scratch_pool));
+  SVN_ERR(svn_fs_node_history2(&history, root, path, scratch_pool, iterpool));
   while (1)
     {
       struct path_revision *path_rev;
@@ -1463,7 +1467,8 @@ get_file_revs_backwards(svn_repos_t *rep
       svn_pool_clear(iterpool);
 
       /* Fetch the history object to walk through. */
-      SVN_ERR(svn_fs_history_prev(&history, history, TRUE, iterpool));
+      SVN_ERR(svn_fs_history_prev2(&history, history, TRUE, iterpool,
+                                   iterpool));
       if (!history)
         break;
       SVN_ERR(svn_fs_history_location(&tmp_path, &tmp_revnum,