summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-08-17 22:27:38 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-08-17 22:27:38 -0700
commit56ff4d38c78dd99873017c075861efefe5428bad (patch)
treedfbf0d7c141b9aa9d34381699c2035bddfb9528c
parent25a3e10e7aed58c8745fdadc87b3b26e8b51523e (diff)
downloadtxr-56ff4d38c78dd99873017c075861efefe5428bad.tar.gz
txr-56ff4d38c78dd99873017c075861efefe5428bad.tar.bz2
txr-56ff4d38c78dd99873017c075861efefe5428bad.zip
vec-set-length maintenance.
* lib.c (vec_set_length): Check new length against INT_PTR_MAX rather than size_t limit. We want to keep the length a fixnum. If the allocation needs to increase, grow it by 25%, not by doubling it.
-rw-r--r--lib.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/lib.c b/lib.c
index f76c08bd..3ea7b4e2 100644
--- a/lib.c
+++ b/lib.c
@@ -6892,14 +6892,23 @@ val vec_set_length(val vec, val length)
uw_throwf(error_s, lit("vec-set-length: negative length ~s specified"),
length, nao);
- if (new_length > convert(cnum, (convert(size_t, -1)/sizeof (val) - 2)))
+ if (new_length > INT_PTR_MAX - 2)
+ {
uw_throwf(error_s, lit("vec-set-length: cannot extend to length ~s"),
length, nao);
+ }
if (new_length > old_alloc) {
- cnum new_alloc = max(new_length, 2*old_alloc);
- val *newvec = coerce(val *, chk_realloc(coerce(mem_t *, vec->v.vec - 2),
- (new_alloc + 2) * sizeof *newvec));
+ cnum new_alloc;
+ val *newvec;
+
+ if (old_alloc > (INT_PTR_MAX - 2) - (INT_PTR_MAX - 2) / 5)
+ new_alloc = INT_PTR_MAX - 2;
+ else
+ new_alloc = max(new_length, old_alloc + old_alloc / 4);
+
+ newvec = coerce(val *, chk_realloc(coerce(mem_t *, vec->v.vec - 2),
+ (new_alloc + 2) * sizeof *newvec));
vec->v.vec = newvec + 2;
set(mkloc(vec->v.vec[vec_alloc], vec), num(new_alloc));
#if HAVE_VALGRIND