1
0
Эх сурвалжийг харах

Optimize rfc functions for common case of using them.

Mainly this allows inlining them where used rather than requiring
the function pointer lookup and then a function call for something
trivial like rfc_toupper().

Also add some const attributes since these don't read/write modifiable
global memory.  rfc_touppertab is const so this should be fine.
Bryan Drewery 7 жил өмнө
parent
commit
4be3e05bc4

+ 7 - 10
src/RfcString.cc

@@ -4,16 +4,11 @@
 #include <stdlib.h>
 #include "RfcString.h"
 
-bool
-RfcString::rfc_equal(const char c1, const char c2) noexcept {
-  if (c1 == c2)
-    return true;
-  return (rfc_toupper(c1) == rfc_toupper(c2));
-}
-
 int
 RfcString::compare(const RfcString& str, size_t n) const noexcept
 {
+  if (rfc_casecmp != _rfc_casecmp)
+    return String::compare(str, n);
   /* Same string? */
   if (cbegin() == str.cbegin() && length() == str.length())
     return 0;
@@ -24,7 +19,7 @@ RfcString::compare(const RfcString& str, size_t n) const noexcept
   /* XXX: std::lexicographical_compare_3way would be nice ... */
   int cmp = 0;
   while (n > 0 && s1 != cend() && s2 != str.cend()) {
-    if ((cmp = rfc_toupper(*s1) - rfc_toupper(*s2)) != 0)
+    if ((cmp = _rfc_toupper(*s1) - _rfc_toupper(*s2)) != 0)
       return cmp;
     ++s1;
     ++s2;
@@ -38,16 +33,18 @@ RfcString::compare(const RfcString& str, size_t n) const noexcept
     return -1;
   else
     return 0;
-  return rfc_toupper(*s1) - rfc_toupper(*s2);
+  return _rfc_toupper(*s1) - _rfc_toupper(*s2);
 }
 
 size_t
 RfcString::hash() const noexcept {
   if (my_hash != 0) return my_hash;
+  if (rfc_casecmp != _rfc_casecmp)
+    return String::hash();
   std::hash<value_type> hasher;
   size_t _hash = 5381;
 
   for(size_t i = 0; i < this->length(); ++i)
-    _hash = ((_hash << 5) + _hash) + hasher(rfc_toupper(this->data()[i]));
+    _hash = ((_hash << 5) + _hash) + hasher(_rfc_toupper(this->data()[i]));
   return (my_hash = (_hash & 0x7FFFFFFF));
 }

+ 0 - 2
src/RfcString.h

@@ -9,8 +9,6 @@ namespace bd {
 
 class RfcString : public bd::String {
   private:
-    static bool rfc_equal(const char c1, const char c2) noexcept
-      __attribute__((pure));
 
   protected:
 

+ 2 - 2
src/match.cc

@@ -130,7 +130,7 @@ int _wild_match_per(unsigned char *m, unsigned char *n)
       case QUOTE:
         m++;                    /* Handle quoting */
       }
-      if (rfc_toupper(*m) == rfc_toupper(*n)) { /* If matching */
+      if (rfc_char_equal(*m, *n)) { /* If matching */
         m++;
         n++;
         sofar++;
@@ -210,7 +210,7 @@ int _wild_match(unsigned char *m, unsigned char *n)
       n--;
       continue;                 /* '?' always matches */
     }
-    if (rfc_toupper(*m) == rfc_toupper(*n)) {   /* If matching char */
+    if (rfc_char_equal(*m, *n)) {   /* If matching char */
       m--;
       n--;
       sofar++;                  /* Tally the match */

+ 1 - 1
src/mod/server.mod/servmsg.cc

@@ -455,7 +455,7 @@ got005(char *from, char *msg)
       if (strcasecmp(p, "rfc1459")) {
         rfc_casecmp = strcasecmp;
         rfc_ncasecmp = strncasecmp;
-        rfc_toupper = toupper;
+        rfc_char_equal = char_equal;
       }
     }
   }

+ 7 - 47
src/rfc1459.cc

@@ -27,18 +27,18 @@
 #include "common.h"
 #include "rfc1459.h"
 
-int (*rfc_casecmp) (const char *, const char *) = _rfc_casecmp;
-int (*rfc_ncasecmp) (const char *, const char *, size_t) = _rfc_ncasecmp;
-int (*rfc_toupper) (int) = _rfc_toupper;
+int (*rfc_casecmp) (const char *, const char *) __attribute__((const)) = _rfc_casecmp;
+int (*rfc_ncasecmp) (const char *, const char *, size_t) __attribute__((const)) = _rfc_ncasecmp;
+bool (*rfc_char_equal) (const char, const char) __attribute__((const)) = _rfc_char_equal;
 
 int
 _rfc_casecmp(const char *s1, const char *s2)
 {
-  while ((*s1) && (*s2) && (rfc_toupper(*s1) == rfc_toupper(*s2))) {
+  while ((*s1) && (*s2) && _rfc_char_equal(*s1, *s2)) {
     ++s1;
     ++s2;
   }
-  return rfc_toupper(*s1) - rfc_toupper(*s2);
+  return _rfc_toupper(*s1) - _rfc_toupper(*s2);
 }
 
 int
@@ -46,51 +46,11 @@ _rfc_ncasecmp(const char *s1, const char *s2, size_t n)
 {
   if (!n)
     return 0;
-  while (--n && (*s1) && (*s2) && (rfc_toupper(*s1) == rfc_toupper(*s2))) {
+  while (--n && (*s1) && (*s2) && _rfc_char_equal(*s1, *s2)) {
     ++s1;
     ++s2;
   }
-  return rfc_toupper(*s1) - rfc_toupper(*s2);
-}
-
-unsigned char rfc_touppertab[] = { 0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
-  0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
-  0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
-  0x1e, 0x1f,
-  ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
-  '*', '+', ',', '-', '.', '/',
-  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
-  ':', ';', '<', '=', '>', '?',
-  '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
-  'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
-  'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
-  0x5f,
-  '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
-  'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
-  'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
-  0x7f,
-  0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
-  0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
-  0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
-  0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
-  0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
-  0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
-  0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
-  0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
-  0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
-  0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
-  0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
-  0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
-  0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
-  0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
-  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
-  0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
-};
-
-int
-_rfc_toupper(int c)
-{
-  return rfc_touppertab[(unsigned char) (c)];
+  return _rfc_toupper(*s1) - _rfc_toupper(*s2);
 }
 
 /* vim: set sts=2 sw=2 ts=8 et: */

+ 58 - 6
src/rfc1459.h

@@ -1,12 +1,64 @@
 #ifndef _RFC1459_H
 #define _RFC1459_H
 
-int _rfc_casecmp(const char *, const char *);
-int _rfc_ncasecmp(const char *, const char *, size_t);
-int _rfc_toupper(int);
+int _rfc_casecmp(const char *, const char *) __attribute__((const));
+int _rfc_ncasecmp(const char *, const char *, size_t) __attribute__((const));
 
-extern int (*rfc_casecmp) (const char *, const char *);
-extern int (*rfc_ncasecmp) (const char *, const char *, size_t);
-extern int (*rfc_toupper) (int);
+static const unsigned char rfc_touppertab[] = {
+  0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa,
+  0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11, 0x12, 0x13, 0x14,
+  0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
+  0x1e, 0x1f,
+  ' ', '!', '"', '#', '$', '%', '&', 0x27, '(', ')',
+  '*', '+', ',', '-', '.', '/',
+  '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+  ':', ';', '<', '=', '>', '?',
+  '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
+  'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+  'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
+  0x5f,
+  '`', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
+  'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
+  'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\', ']', '^',
+  0x7f,
+  0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+  0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+  0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
+  0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+  0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
+  0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+  0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
+  0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+  0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
+  0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+  0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9,
+  0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+  0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
+  0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+  0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
+  0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+static inline int __attribute__((const))
+_rfc_toupper(const int c)
+{
+  return rfc_touppertab[(unsigned char) (c)];
+}
+
+static inline bool __attribute__((const))
+char_equal(const char c1, const char c2)
+{
+  return c1 == c2;
+}
+
+static inline bool __attribute__((const))
+_rfc_char_equal(const char c1, const char c2)
+{
+  return _rfc_toupper(c1) == _rfc_toupper(c2);
+}
+
+extern bool (*rfc_char_equal) (const char, const char) __attribute__((const));
+extern int (*rfc_casecmp) (const char *, const char *) __attribute__((const));
+extern int (*rfc_ncasecmp) (const char *, const char *, size_t) __attribute__((const));
 
 #endif /* !_RFC1459_H */