summaryrefslogtreecommitdiff
path: root/libguile/strings.c
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2022-02-05 23:27:48 +0100
committerLudovic Courtès <ludo@gnu.org>2022-02-07 12:23:35 +0100
commit032acdeac9dfe6b407a1fcbd9f00c3e1a0dd27aa (patch)
treec1d6a755728448d1413d576c742a6a6ee165c446 /libguile/strings.c
parent2f9bc7fe61d39658a24a15526b7b88bbd184961b (diff)
downloadguile-032acdeac9dfe6b407a1fcbd9f00c3e1a0dd27aa.tar.gz
'string->symbol' avoids copying the underlying string.
* libguile/strings.c (scm_i_make_symbol): Reuse NAME's stringbuf unless it's mutable or NAME starts at a non-zero offset or has a different length.
Diffstat (limited to 'libguile/strings.c')
-rw-r--r--libguile/strings.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/libguile/strings.c b/libguile/strings.c
index a5b4b0386..5eebb3300 100644
--- a/libguile/strings.c
+++ b/libguile/strings.c
@@ -763,10 +763,16 @@ SCM
scm_i_make_symbol (SCM name, scm_t_bits flags, unsigned long hash)
{
SCM buf, symbol;
- size_t length = STRING_LENGTH (name);
+ size_t start, length = STRING_LENGTH (name);
- name = scm_i_substring_copy (name, 0, length);
- buf = STRING_STRINGBUF (name);
+ get_str_buf_start (&name, &buf, &start);
+ if (SCM_UNLIKELY (STRINGBUF_MUTABLE (buf)
+ || start != 0
+ || STRINGBUF_LENGTH (buf) != length))
+ {
+ name = scm_i_substring_copy (name, 0, length);
+ buf = STRING_STRINGBUF (name);
+ }
symbol = scm_words (scm_tc7_symbol | flags, 3);
SCM_SET_CELL_WORD_1 (symbol, SCM_UNPACK (buf));