[email protected] wrote on Sat, Oct 30, 2010 at 12:09:49 -0000:
> Author: stefan2
> Date: Sat Oct 30 12:09:49 2010
> New Revision: 1029038
> 
> URL: http://svn.apache.org/viewvc?rev=1029038&view=rev
> Log:
> Improve on r1028104:
> Move string buffer size alignment logic down the call stack.
> Also, extend the logic to cover string growth as well.
> 
> * subversion/libsvn_subr/svn_string.c
>   (svn_stringbuf_ncreate): remove alignment logic
>   (svn_stringbuf_create_ensure): add it here
>   (svn_stringbuf_ensure): and here
> 
> Suggested by: Daniel Shahaf <d.s_at_daniel.shahaf.name> 
> 

You can say "Suggested by: danielsh" for people in COMMITTERS.

> Modified:
>     subversion/branches/performance/subversion/libsvn_subr/svn_string.c
> 
> Modified: subversion/branches/performance/subversion/libsvn_subr/svn_string.c
> URL: 
> http://svn.apache.org/viewvc/subversion/branches/performance/subversion/libsvn_subr/svn_string.c?rev=1029038&r1=1029037&r2=1029038&view=diff
> ==============================================================================
> --- subversion/branches/performance/subversion/libsvn_subr/svn_string.c 
> (original)
> +++ subversion/branches/performance/subversion/libsvn_subr/svn_string.c Sat 
> Oct 30 12:09:49 2010
> @@ -255,7 +255,13 @@ svn_stringbuf_create_empty(apr_pool_t *p
>  svn_stringbuf_t *
>  svn_stringbuf_create_ensure(apr_size_t blocksize, apr_pool_t *pool)
>  {
> -  char *data = apr_palloc(pool, ++blocksize); /* + space for '\0' */
> +  /* apr_palloc will allocate multiples of 8.
> +   * Thus, we would waste some of that memory if we stuck to the
> +   * smaller size. Note that this is safe even if apr_palloc would
> +   * use some other aligment or none at all. */
> +
> +  blocksize = APR_ALIGN_DEFAULT(++blocksize); /* + space for '\0' */
> +  char *data = apr_palloc(pool, blocksize);
>  

Two issues:

* Declaration ('char *data') after statement ('blocksize = ...').
  We can't do this because we promise (and one buildbot enforces) C89
  compatibility.  Please avoid this.

* The blocksize line.  It assigns to 'blocksize' and uses ++blocksize on
  the same line... and on top of that, it uses ++blocksize as an
  argument to a macro (and I don't know that that macro promises not to
  multiply-evaluate its argument).  All in all, it touches 'blocksize'
  too many times for my poor brain.  Could you change it to:
 
     blocksize = APR_ALIGN_DEFAULT(blocksize+1);

  please?

Assuming these two changes, +1 to merge to trunk.  (Feel free to just
make the changes and merge them without waiting for another +1; if
further review is necessary, it can be done on trunk.)

>    data[0] = '\0';
>  
> @@ -266,21 +272,7 @@ svn_stringbuf_create_ensure(apr_size_t b
>  svn_stringbuf_t *
>  svn_stringbuf_ncreate(const char *bytes, apr_size_t size, apr_pool_t *pool)
>  {
> -  char *data;
> -
> -  /* apr_palloc will allocate multiples of 8.
> -   * Thus, we would waste some of that memory if we stuck to the
> -   * smaller size. Note that this is safe even if apr_palloc would
> -   * use some other aligment or none at all. */
> -  apr_size_t aligned_size = APR_ALIGN_DEFAULT(size + 1) - 1;
> -
> -  /* Ensure string buffer of aligned_size + 1.
> -   * This should allocate the same amount of memory as "size" would. */
> -  svn_stringbuf_t *strbuf = svn_stringbuf_create_ensure(aligned_size, pool);
> -
> -  /* Actually, aligned_size+1 would be faster but we cannot be entirely
> -   * sure that the source string has been aligned properly such that
> -   * all the extra bytes would actually come from addressible memory.*/
> +  svn_stringbuf_t *strbuf = svn_stringbuf_create_ensure(size, pool);
>    memcpy(strbuf->data, bytes, size);
>  
>    /* Null termination is the convention -- even if we suspect the data
> @@ -385,12 +377,18 @@ svn_stringbuf_ensure(svn_stringbuf_t *st
>    if (str->blocksize < minimum_size)
>      {
>        if (str->blocksize == 0)
> -        str->blocksize = minimum_size;
> +        /* APR will increase odd allocation sizes to the next
> +         * multiple for 8, for instance. Take advantage of that
> +         * knowledge and allow for the extra size to be used. */
> +        str->blocksize = APR_ALIGN_DEFAULT(minimum_size);
>        else
>          while (str->blocksize < minimum_size)
>            {
> +            /* str->blocksize is aligned;
> +             * doubling it should keep it aligned */
>              apr_size_t prev_size = str->blocksize;
>              str->blocksize *= 2;
> +
>              /* check for apr_size_t overflow */
>              if (prev_size > str->blocksize)
>                {
> 
> 

Reply via email to