1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-28 22:10:29 +02:00

Move scm_c_shrink_bytevector off realloc

* libguile/bytevectors.c (scm_c_shrink_bytevector): Return buf as is if
length is more than half of previous.  Otherwise make a fresh buffer and
copy.
This commit is contained in:
Andy Wingo 2025-04-30 11:01:14 +02:00
parent 337eaec77d
commit f3649d7d1b

View file

@ -1,4 +1,4 @@
/* Copyright 2009-2015,2018-2019,2023 /* Copyright 2009-2015,2018-2019,2023,2025
Free Software Foundation, Inc. Free Software Foundation, Inc.
This file is part of Guile. This file is part of Guile.
@ -394,40 +394,25 @@ SCM_DEFINE (scm_bytevector_slice, "bytevector-slice", 2, 1, 0,
SCM SCM
scm_c_shrink_bytevector (SCM bv, size_t c_new_len) scm_c_shrink_bytevector (SCM bv, size_t c_new_len)
{ {
SCM new_bv;
size_t c_len;
if (SCM_UNLIKELY (c_new_len % SCM_BYTEVECTOR_TYPE_SIZE (bv))) if (SCM_UNLIKELY (c_new_len % SCM_BYTEVECTOR_TYPE_SIZE (bv)))
/* This would be an internal Guile programming error */ /* This would be an internal Guile programming error */
abort (); abort ();
c_len = SCM_BYTEVECTOR_LENGTH (bv); size_t c_len = SCM_BYTEVECTOR_LENGTH (bv);
if (SCM_UNLIKELY (c_new_len > c_len)) if (SCM_UNLIKELY (c_new_len > c_len))
abort (); abort ();
SCM_BYTEVECTOR_SET_LENGTH (bv, c_new_len); if (SCM_BYTEVECTOR_CONTIGUOUS_P (bv) && c_new_len > c_len / 2)
if (SCM_BYTEVECTOR_CONTIGUOUS_P (bv))
{ {
signed char *c_bv; SCM_BYTEVECTOR_SET_LENGTH (bv, c_new_len);
return bv;
c_bv = scm_gc_realloc (SCM2PTR (bv),
c_len + SCM_BYTEVECTOR_HEADER_BYTES,
c_new_len + SCM_BYTEVECTOR_HEADER_BYTES,
SCM_GC_BYTEVECTOR);
new_bv = PTR2SCM (c_bv);
SCM_BYTEVECTOR_SET_CONTENTS (new_bv, c_bv + SCM_BYTEVECTOR_HEADER_BYTES);
} }
else
{
signed char *c_bv;
c_bv = scm_gc_realloc (SCM_BYTEVECTOR_CONTENTS (bv), SCM new_bv =
c_len, c_new_len, SCM_GC_BYTEVECTOR); scm_i_make_typed_bytevector (c_new_len, SCM_BYTEVECTOR_ELEMENT_TYPE (bv));
SCM_BYTEVECTOR_SET_CONTENTS (bv, c_bv);
new_bv = bv; memcpy (SCM_BYTEVECTOR_CONTENTS (new_bv), SCM_BYTEVECTOR_CONTENTS (bv),
} c_new_len);
return new_bv; return new_bv;
} }