diff --git a/libguile/bytevectors.c b/libguile/bytevectors.c index 6b14c7246..2ec26730b 100644 --- a/libguile/bytevectors.c +++ b/libguile/bytevectors.c @@ -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 (); - SCM_BYTEVECTOR_SET_LENGTH (bv, c_new_len); - - if (SCM_BYTEVECTOR_CONTIGUOUS_P (bv)) + if (SCM_BYTEVECTOR_CONTIGUOUS_P (bv) && c_new_len > c_len / 2) { - 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); + SCM_BYTEVECTOR_SET_LENGTH (bv, c_new_len); + 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; }