From 5a8d27b767ebf8432620cf3ba1297e8b9327a97f Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Mon, 17 Apr 2017 23:22:54 +0000 Subject: introduce new str_new_dd_freeze internal function This seems like it will be a common pattern to create and immediately dedupe a string. In the future, we may be able to save some memory by eliding temporary object creation or releasing heap memory via rb_str_resize(..., 0) --- ext/kcar/extconf.rb | 15 ++++++++++----- ext/kcar/kcar.rl | 9 +++++++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ext/kcar/extconf.rb b/ext/kcar/extconf.rb index 89ac586..b65846a 100644 --- a/ext/kcar/extconf.rb +++ b/ext/kcar/extconf.rb @@ -6,15 +6,20 @@ dir_config("kcar") have_macro("SIZEOF_OFF_T", "ruby.h") or check_sizeof("off_t", "sys/types.h") have_macro("SIZEOF_LONG", "ruby.h") or check_sizeof("long", "sys/types.h") -uminus_dedupe = false +message('checking if String#-@ (str_uminus) dedupes... ') begin - # oddly, opt_str_freeze is not always effective: - # https://bugs.ruby-lang.org/issues/13282 a = -(%w(t e s t).join) b = -(%w(t e s t).join) - uminus_dedupe = a.object_id == b.object_id + if a.equal?(b) + $CPPFLAGS += " -DSTR_UMINUS_DEDUPE=1 " + message("yes\n") + else + $CPPFLAGS += " -DSTR_UMINUS_DEDUPE=0 " + message("no, needs Ruby 2.5+\n") + end rescue NoMethodError + $CPPFLAGS += " -DSTR_UMINUS_DEDUPE=0 " + message("no, String#-@ not available\n") end -$CFLAGS += " -DSTR_UMINUS_DEDUPE=#{uminus_dedupe ? 1 : 0}" create_makefile("kcar_ext") diff --git a/ext/kcar/kcar.rl b/ext/kcar/kcar.rl index cbcfa97..79f65db 100644 --- a/ext/kcar/kcar.rl +++ b/ext/kcar/kcar.rl @@ -106,6 +106,11 @@ static VALUE str_dd_freeze(VALUE str) return str; } +static VALUE str_new_dd_freeze(const char *ptr, long len) +{ + return str_dd_freeze(rb_str_new(ptr, len)); +} + static VALUE stripped_str_new(const char *str, long len) { long end; @@ -161,7 +166,7 @@ status_phrase(struct http_parser *hp, VALUE hdr, const char *ptr, size_t len) { long nr; - hp->status = str_dd_freeze(rb_str_new(ptr, len)); + hp->status = str_new_dd_freeze(ptr, len); /* RSTRING_PTR is null terminated, ptr is not */ nr = strtol(RSTRING_PTR(hp->status), NULL, 10); @@ -238,7 +243,7 @@ static void write_value(VALUE hdr, struct http_parser *hp, vlen = LEN(mark, p); VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE); VALIDATE_MAX_LENGTH(flen, FIELD_NAME); - f = str_dd_freeze(rb_str_new(fptr, (long)flen)); + f = str_new_dd_freeze(fptr, (long)flen); v = stripped_str_new(vptr, (long)vlen); /* needs more tests for error-checking here */ -- cgit v1.2.3-24-ge0c7