aboutsummaryrefslogtreecommitdiffstats
path: root/bignum.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-09-04 21:23:21 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-09-04 21:23:21 +0000
commit3b1ab2a6b76059b65dd6d3f124e40e3226c57c6d (patch)
treed84b33cc46f76e418dd86a3dc58d7e6317b61f29 /bignum.c
parent8db313151d46b0c296c99968cdc3d5619d215a9c (diff)
downloadruby-3b1ab2a6b76059b65dd6d3f124e40e3226c57c6d.tar.gz
* bignum.c (bary_divmod_normal): Reduce temporary array allocations.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42839 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'bignum.c')
-rw-r--r--bignum.c29
1 files changed, 14 insertions, 15 deletions
diff --git a/bignum.c b/bignum.c
index b09080d4ee..308af6b2f3 100644
--- a/bignum.c
+++ b/bignum.c
@@ -2641,8 +2641,7 @@ bary_divmod_normal(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT
int shift;
BDIGIT *zds, *yyds;
size_t zn;
- VALUE tmpz = 0;
- VALUE tmpyy = 0;
+ VALUE tmpyz = 0;
assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1]));
assert(qds ? (xn - yn + 1) <= qn : 1);
@@ -2652,14 +2651,16 @@ bary_divmod_normal(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT
shift = nlz(yds[yn-1]);
if (shift) {
- if (qds && zn <= qn)
- zds = qds;
- else
- zds = ALLOCV_N(BDIGIT, tmpz, zn);
- if (rds)
- yyds = rds;
- else
- yyds = ALLOCV_N(BDIGIT, tmpyy, yn);
+ int alloc_y = !rds;
+ int alloc_z = !qds || qn < zn;
+ if (alloc_y && alloc_z) {
+ yyds = ALLOCV_N(BDIGIT, tmpyz, yn+zn);
+ zds = yyds + yn;
+ }
+ else {
+ yyds = alloc_y ? ALLOCV_N(BDIGIT, tmpyz, yn) : rds;
+ zds = alloc_z ? ALLOCV_N(BDIGIT, tmpyz, zn) : qds;
+ }
zds[xn] = bary_small_lshift(zds, xds, xn, shift);
bary_small_lshift(yyds, yds, yn, shift);
}
@@ -2667,7 +2668,7 @@ bary_divmod_normal(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT
if (qds && zn <= qn)
zds = qds;
else
- zds = ALLOCV_N(BDIGIT, tmpz, zn);
+ zds = ALLOCV_N(BDIGIT, tmpyz, zn);
MEMCPY(zds, xds, BDIGIT, xn);
zds[xn] = 0;
/* bigdivrem_restoring will not modify y.
@@ -2691,10 +2692,8 @@ bary_divmod_normal(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT
BDIGITS_ZERO(qds+j, qn-j);
}
- if (tmpyy)
- ALLOCV_END(tmpyy);
- if (tmpz)
- ALLOCV_END(tmpz);
+ if (tmpyz)
+ ALLOCV_END(tmpyz);
}
VALUE