diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-08-17 22:27:38 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-08-17 22:27:38 -0700 |
commit | 56ff4d38c78dd99873017c075861efefe5428bad (patch) | |
tree | dfbf0d7c141b9aa9d34381699c2035bddfb9528c | |
parent | 25a3e10e7aed58c8745fdadc87b3b26e8b51523e (diff) | |
download | txr-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.c | 17 |
1 files changed, 13 insertions, 4 deletions
@@ -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 |