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.
This file is part of Guile.
@ -394,40 +394,25 @@ SCM_DEFINE (scm_bytevector_slice, "bytevector-slice", 2, 1, 0,
SCM
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)))
/* This would be an internal Guile programming error */
abort ();
c_len = SCM_BYTEVECTOR_LENGTH (bv);
size_t c_len = SCM_BYTEVECTOR_LENGTH (bv);
if (SCM_UNLIKELY (c_new_len > c_len))
abort ();
if (SCM_BYTEVECTOR_CONTIGUOUS_P (bv) && c_new_len > c_len / 2)
{
SCM_BYTEVECTOR_SET_LENGTH (bv, c_new_len);
if (SCM_BYTEVECTOR_CONTIGUOUS_P (bv))
{
signed char *c_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);
return bv;
}
else
{
signed char *c_bv;
c_bv = scm_gc_realloc (SCM_BYTEVECTOR_CONTENTS (bv),
c_len, c_new_len, SCM_GC_BYTEVECTOR);
SCM_BYTEVECTOR_SET_CONTENTS (bv, c_bv);
SCM new_bv =
scm_i_make_typed_bytevector (c_new_len, SCM_BYTEVECTOR_ELEMENT_TYPE (bv));
new_bv = bv;
}
memcpy (SCM_BYTEVECTOR_CONTENTS (new_bv), SCM_BYTEVECTOR_CONTENTS (bv),
c_new_len);
return new_bv;
}