From 3fc63c15b4ca913b9151cdff9365190d69f2ccd3 Mon Sep 17 00:00:00 2001 From: Jerry Quinn Date: Tue, 16 Dec 2003 01:57:03 +0000 Subject: [PATCH] ctype_noninline.h, [...] (ctype): Initialize _M_narrow, _M_widen. 2003-12-15 Jerry Quinn * config/os/aix/ctype_noninline.h, config/os/bsd/freebsd/ctype_noninline.h, config/os/bsd/netbsd/ctype_noninline.h, config/os/djgpp/ctype_noninline.h, config/os/generic/ctype_noninline.h, config/os/gnu-linux/ctype_noninline.h, config/os/hpux/ctype_noninline.h, config/os/irix/irix5.2/ctype_noninline.h, config/os/irix/irix6.5/ctype_noninline.h, config/os/mingw32/ctype_noninline.h, config/os/newlib/ctype_noninline.h, config/os/qnx/qnx6.1/ctype_noninline.h, config/os/solaris/solaris2.5/ctype_noninline.h, config/os/solaris/solaris2.6/ctype_noninline.h, config/os/solaris/solaris2.7/ctype_noninline.h, config/os/vxworks/ctype_noninline.h, config/os/windiss/ctype_noninline.h (ctype): Initialize _M_narrow, _M_widen. * include/bits/locale_facets.h (_M_widen, _M_widen_ok, _M_narrow, _M_narrow_ok): New. (widen, narrow): Use tables to bypass virtual functions. (_M_widen_init, _M_narrow_init): New. From-SVN: r74662 --- libstdc++-v3/ChangeLog | 25 ++++++ libstdc++-v3/config/os/aix/ctype_noninline.h | 14 ++- .../config/os/bsd/freebsd/ctype_noninline.h | 14 ++- .../config/os/bsd/netbsd/ctype_noninline.h | 14 ++- .../config/os/djgpp/ctype_noninline.h | 14 ++- .../config/os/generic/ctype_noninline.h | 14 ++- .../config/os/gnu-linux/ctype_noninline.h | 16 ++++ libstdc++-v3/config/os/hpux/ctype_noninline.h | 14 ++- .../config/os/irix/irix5.2/ctype_noninline.h | 14 ++- .../config/os/irix/irix6.5/ctype_noninline.h | 14 ++- .../config/os/mingw32/ctype_noninline.h | 14 ++- .../config/os/newlib/ctype_noninline.h | 14 ++- .../config/os/qnx/qnx6.1/ctype_noninline.h | 14 ++- .../os/solaris/solaris2.5/ctype_noninline.h | 14 ++- .../os/solaris/solaris2.6/ctype_noninline.h | 14 ++- .../os/solaris/solaris2.7/ctype_noninline.h | 14 ++- .../config/os/vxworks/ctype_noninline.h | 14 ++- .../config/os/windiss/ctype_noninline.h | 14 ++- libstdc++-v3/include/bits/locale_facets.h | 87 ++++++++++++++++++- .../performance/narrow_widen_char.cc | 76 ++++++++++++++++ 20 files changed, 392 insertions(+), 36 deletions(-) create mode 100644 libstdc++-v3/testsuite/performance/narrow_widen_char.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 5e560e0bc98..853f86afca5 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,28 @@ +2003-12-15 Jerry Quinn + + * config/os/aix/ctype_noninline.h, + config/os/bsd/freebsd/ctype_noninline.h, + config/os/bsd/netbsd/ctype_noninline.h, + config/os/djgpp/ctype_noninline.h, + config/os/generic/ctype_noninline.h, + config/os/gnu-linux/ctype_noninline.h, + config/os/hpux/ctype_noninline.h, + config/os/irix/irix5.2/ctype_noninline.h, + config/os/irix/irix6.5/ctype_noninline.h, + config/os/mingw32/ctype_noninline.h, + config/os/newlib/ctype_noninline.h, + config/os/qnx/qnx6.1/ctype_noninline.h, + config/os/solaris/solaris2.5/ctype_noninline.h, + config/os/solaris/solaris2.6/ctype_noninline.h, + config/os/solaris/solaris2.7/ctype_noninline.h, + config/os/vxworks/ctype_noninline.h, + config/os/windiss/ctype_noninline.h (ctype): Initialize + _M_narrow, _M_widen. + * include/bits/locale_facets.h (_M_widen, _M_widen_ok, + _M_narrow, _M_narrow_ok): New. + (widen, narrow): Use tables to bypass virtual functions. + (_M_widen_init, _M_narrow_init): New. + 2003-12-15 Carlo Wood * include/bits/ios_base.h (Init::_S_initialized): Change into diff --git a/libstdc++-v3/config/os/aix/ctype_noninline.h b/libstdc++-v3/config/os/aix/ctype_noninline.h index 78fce2ef176..edd8d82f3f6 100644 --- a/libstdc++-v3/config/os/aix/ctype_noninline.h +++ b/libstdc++-v3/config/os/aix/ctype_noninline.h @@ -42,13 +42,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/bsd/freebsd/ctype_noninline.h b/libstdc++-v3/config/os/bsd/freebsd/ctype_noninline.h index 27cd28c082e..ec5b5753547 100644 --- a/libstdc++-v3/config/os/bsd/freebsd/ctype_noninline.h +++ b/libstdc++-v3/config/os/bsd/freebsd/ctype_noninline.h @@ -42,13 +42,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/bsd/netbsd/ctype_noninline.h b/libstdc++-v3/config/os/bsd/netbsd/ctype_noninline.h index 0cc08aef248..70bf41c22e1 100644 --- a/libstdc++-v3/config/os/bsd/netbsd/ctype_noninline.h +++ b/libstdc++-v3/config/os/bsd/netbsd/ctype_noninline.h @@ -44,13 +44,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/djgpp/ctype_noninline.h b/libstdc++-v3/config/os/djgpp/ctype_noninline.h index 848f5e2bde7..eda2679ed3c 100644 --- a/libstdc++-v3/config/os/djgpp/ctype_noninline.h +++ b/libstdc++-v3/config/os/djgpp/ctype_noninline.h @@ -42,13 +42,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(__dj_ctype_toupper), _M_tolower(__dj_ctype_tolower), _M_table(__table ? __table : __dj_ctype_flags) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(__dj_ctype_toupper), _M_tolower(__dj_ctype_tolower), _M_table(__table ? __table : __dj_ctype_flags) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/generic/ctype_noninline.h b/libstdc++-v3/config/os/generic/ctype_noninline.h index 92e1173ed67..e30348e6058 100644 --- a/libstdc++-v3/config/os/generic/ctype_noninline.h +++ b/libstdc++-v3/config/os/generic/ctype_noninline.h @@ -43,13 +43,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/gnu-linux/ctype_noninline.h b/libstdc++-v3/config/os/gnu-linux/ctype_noninline.h index 8d38627f7bd..ae4c14d5d58 100644 --- a/libstdc++-v3/config/os/gnu-linux/ctype_noninline.h +++ b/libstdc++-v3/config/os/gnu-linux/ctype_noninline.h @@ -65,6 +65,10 @@ _M_toupper = _M_c_locale_ctype->__ctype_toupper; _M_tolower = _M_c_locale_ctype->__ctype_tolower; _M_table = __table ? __table : _M_c_locale_ctype->__ctype_b; + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; } #else ctype::ctype(__c_locale, const mask* __table, bool __del, @@ -85,6 +89,10 @@ setlocale(LC_CTYPE, __old); free(__old); _M_c_locale_ctype = _S_get_c_locale(); + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; } #endif @@ -96,6 +104,10 @@ _M_toupper = _M_c_locale_ctype->__ctype_toupper; _M_tolower = _M_c_locale_ctype->__ctype_tolower; _M_table = __table ? __table : _M_c_locale_ctype->__ctype_b; + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; } #else ctype::ctype(const mask* __table, bool __del, size_t __refs) @@ -115,6 +127,10 @@ setlocale(LC_CTYPE, __old); free(__old); _M_c_locale_ctype = _S_get_c_locale(); + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; } #endif diff --git a/libstdc++-v3/config/os/hpux/ctype_noninline.h b/libstdc++-v3/config/os/hpux/ctype_noninline.h index c42fd8a49ee..00e338b6e06 100644 --- a/libstdc++-v3/config/os/hpux/ctype_noninline.h +++ b/libstdc++-v3/config/os/hpux/ctype_noninline.h @@ -43,13 +43,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : (const mask *) __SB_masks) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : (const mask *) __SB_masks) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/irix/irix5.2/ctype_noninline.h b/libstdc++-v3/config/os/irix/irix5.2/ctype_noninline.h index 2268a9b9e2c..2aeb50c658b 100644 --- a/libstdc++-v3/config/os/irix/irix5.2/ctype_noninline.h +++ b/libstdc++-v3/config/os/irix/irix5.2/ctype_noninline.h @@ -43,13 +43,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(!__table ? classic_table() : __table) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(!__table ? classic_table() : __table) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/irix/irix6.5/ctype_noninline.h b/libstdc++-v3/config/os/irix/irix6.5/ctype_noninline.h index c0e6e56d515..8fdf95ef7a9 100644 --- a/libstdc++-v3/config/os/irix/irix6.5/ctype_noninline.h +++ b/libstdc++-v3/config/os/irix/irix6.5/ctype_noninline.h @@ -43,14 +43,24 @@ _M_toupper(NULL), _M_tolower(NULL), _M_table(!__table ? (const mask*) (__libc_attr._ctype_tbl->_class + 1) : __table) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(!__table ? (const mask*) (__libc_attr._ctype_tbl->_class + 1) : __table) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/mingw32/ctype_noninline.h b/libstdc++-v3/config/os/mingw32/ctype_noninline.h index 4ea7b892cca..e493d403030 100644 --- a/libstdc++-v3/config/os/mingw32/ctype_noninline.h +++ b/libstdc++-v3/config/os/mingw32/ctype_noninline.h @@ -46,13 +46,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/newlib/ctype_noninline.h b/libstdc++-v3/config/os/newlib/ctype_noninline.h index 7c5f053528a..d0cce941b4c 100644 --- a/libstdc++-v3/config/os/newlib/ctype_noninline.h +++ b/libstdc++-v3/config/os/newlib/ctype_noninline.h @@ -42,13 +42,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/qnx/qnx6.1/ctype_noninline.h b/libstdc++-v3/config/os/qnx/qnx6.1/ctype_noninline.h index f4e2ca5f6c6..2eef13a7e65 100644 --- a/libstdc++-v3/config/os/qnx/qnx6.1/ctype_noninline.h +++ b/libstdc++-v3/config/os/qnx/qnx6.1/ctype_noninline.h @@ -41,12 +41,22 @@ size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : _Ctype) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : _Ctype) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/solaris/solaris2.5/ctype_noninline.h b/libstdc++-v3/config/os/solaris/solaris2.5/ctype_noninline.h index 25eec3418b0..a80863653ff 100644 --- a/libstdc++-v3/config/os/solaris/solaris2.5/ctype_noninline.h +++ b/libstdc++-v3/config/os/solaris/solaris2.5/ctype_noninline.h @@ -42,13 +42,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/solaris/solaris2.6/ctype_noninline.h b/libstdc++-v3/config/os/solaris/solaris2.6/ctype_noninline.h index 659c81a3ffe..694901a5dc7 100644 --- a/libstdc++-v3/config/os/solaris/solaris2.6/ctype_noninline.h +++ b/libstdc++-v3/config/os/solaris/solaris2.6/ctype_noninline.h @@ -42,13 +42,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(__trans_upper), _M_tolower(__trans_lower), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(__trans_upper), _M_tolower(__trans_lower), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/solaris/solaris2.7/ctype_noninline.h b/libstdc++-v3/config/os/solaris/solaris2.7/ctype_noninline.h index 81536b5fc87..d4917f069cb 100644 --- a/libstdc++-v3/config/os/solaris/solaris2.7/ctype_noninline.h +++ b/libstdc++-v3/config/os/solaris/solaris2.7/ctype_noninline.h @@ -43,13 +43,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(__trans_upper), _M_tolower(__trans_lower), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(__trans_upper), _M_tolower(__trans_lower), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/vxworks/ctype_noninline.h b/libstdc++-v3/config/os/vxworks/ctype_noninline.h index 4f4e92b1693..acf91a4aa55 100644 --- a/libstdc++-v3/config/os/vxworks/ctype_noninline.h +++ b/libstdc++-v3/config/os/vxworks/ctype_noninline.h @@ -42,13 +42,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table ? __table : classic_table()) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/config/os/windiss/ctype_noninline.h b/libstdc++-v3/config/os/windiss/ctype_noninline.h index a22b65d46d0..cf75ddfd96c 100644 --- a/libstdc++-v3/config/os/windiss/ctype_noninline.h +++ b/libstdc++-v3/config/os/windiss/ctype_noninline.h @@ -43,13 +43,23 @@ : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table == 0 ? classic_table() : __table) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } ctype::ctype(const mask* __table, bool __del, size_t __refs) : facet(__refs), _M_del(__table != 0 && __del), _M_toupper(NULL), _M_tolower(NULL), _M_table(__table == 0 ? classic_table() : __table) - { } + { + memset(_M_widen, 0, sizeof(_M_widen)); + _M_widen_ok = 0; + memset(_M_narrow, 0, sizeof(_M_narrow)); + _M_narrow_ok = 0; + } char ctype::do_toupper(char __c) const diff --git a/libstdc++-v3/include/bits/locale_facets.h b/libstdc++-v3/include/bits/locale_facets.h index 83d77c81119..08cd2960e18 100644 --- a/libstdc++-v3/include/bits/locale_facets.h +++ b/libstdc++-v3/include/bits/locale_facets.h @@ -325,6 +325,11 @@ namespace std __to_type _M_toupper; __to_type _M_tolower; const mask* _M_table; + mutable char _M_widen_ok; + mutable char _M_widen[1 + static_cast(-1)]; + mutable char _M_narrow[1 + static_cast(-1)]; + mutable char _M_narrow_ok; // 0 uninitialized, 1 init, + // 2 non-consecutive public: static locale::id id; @@ -367,20 +372,46 @@ namespace std char_type widen(char __c) const - { return this->do_widen(__c); } + { +// if (_M_widen_ok) return _M_widen[__c]; +// this->_M_widen_init(); + return this->do_widen(__c); + } const char* widen(const char* __lo, const char* __hi, char_type* __to) const - { return this->do_widen(__lo, __hi, __to); } + { +// if (_M_widen_ok == 1) +// { +// memcpy(__to, __lo, __hi - __lo); +// return __hi; +// } +// if (!_M_widen_ok) _M_widen_init(); + return this->do_widen(__lo, __hi, __to); + } char narrow(char_type __c, char __dfault) const - { return this->do_narrow(__c, __dfault); } + { +// if (_M_narrow[__c]) return _M_narrow[__c]; + char __t = do_narrow(__c, __dfault); +// if (__t != __dfault) _M_narrow[__c] = __t; + return __t; + } const char_type* narrow(const char_type* __lo, const char_type* __hi, char __dfault, char *__to) const - { return this->do_narrow(__lo, __hi, __dfault, __to); } + { +// if (__builtin_expect(_M_narrow_ok==1,true)) +// { +// memcpy(__to, __lo, __hi - __lo); +// return __hi; +// } +// if (!_M_narrow_ok) +// _M_narrow_init(); + return this->do_narrow(__lo, __hi, __dfault, __to); + } protected: const mask* @@ -427,6 +458,54 @@ namespace std memcpy(__dest, __lo, __hi - __lo); return __hi; } + + private: + + void _M_widen_init() const + { + char __tmp[sizeof(_M_widen)]; + for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i) + __tmp[__i] = __i; + do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen); + + _M_widen_ok = 1; + // Set _M_widen_ok to 2 if memcpy can't be used. + for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i) + if (__tmp[__i] != _M_widen[__i]) + { + _M_widen_ok = 2; + break; + } + } + + // Fill in the narrowing cache and flag whether all values are + // valid or not. _M_narrow_ok is set to 1 if the whole table is + // narrowed, 2 if only some values could be narrowed. + void _M_narrow_init() const + { + char __tmp[sizeof(_M_narrow)]; + for (unsigned i = 0; i < sizeof(_M_narrow); ++i) + __tmp[i] = i; + do_narrow(__tmp, __tmp + sizeof(__tmp), 0, _M_narrow); + + // Check if any default values were created. Do this by + // renarrowing with a different default value and comparing. + bool __consecutive = true; + for (unsigned __i = 0; __i < sizeof(_M_narrow); ++__i) + { + char __c[1]; + if (!_M_narrow[__i]) + { + do_narrow(__tmp + __i, __tmp + __i + 1, 1, __c); + if (__c[0] == 1) + { + __consecutive = false; + break; + } + } + } + _M_narrow_ok = __consecutive ? 1 : 2; + } }; template<> diff --git a/libstdc++-v3/testsuite/performance/narrow_widen_char.cc b/libstdc++-v3/testsuite/performance/narrow_widen_char.cc new file mode 100644 index 00000000000..d4dd658df59 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/narrow_widen_char.cc @@ -0,0 +1,76 @@ +// Copyright (C) 2003 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING. If not, write to the Free +// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, +// USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +#include +#include + +int main() +{ + using namespace std; + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + const long iters = 200000000; + char bufin[] = "This was an attempt to bypass string construction just for test."; + char bufout[sizeof(bufin) + 1]; + + locale loc; + const ctype& ct = use_facet >(loc); + + // narrow + start_counters(time, resource); + for (long i = 0; i < 1000000000; ++i) + ct.narrow(i % 128, '*'); + stop_counters(time, resource); + report_performance(__FILE__, "narrow", time, resource); + clear_counters(time, resource); + + // narrow array + start_counters(time, resource); + for (long i = 0; i < 100000000; ++i) + ct.narrow(bufin, bufin+sizeof(bufin), '*', bufout); + stop_counters(time, resource); + report_performance(__FILE__, "narrow_array", time, resource); + clear_counters(time, resource); + + // widen + start_counters(time, resource); + for (long i = 0; i < iters; ++i) + ct.widen(i % 128); + stop_counters(time, resource); + report_performance(__FILE__, "widen", time, resource); + + // widen array + start_counters(time, resource); + for (long i = 0; i < iters; ++i) + ct.widen(bufin, bufin+sizeof(bufin), bufout); + stop_counters(time, resource); + report_performance(__FILE__, "widen_array", time, resource); + + return 0; +} -- 2.30.2