summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@gmail.com>2011-12-04 17:44:33 -0500
committerUlrich Drepper <drepper@gmail.com>2011-12-04 17:44:33 -0500
commit52ad36a21973c0b4fbc16b7104bbffec765e5a23 (patch)
tree8d71d471da30fa6b86311eef449d5b4ed521ac16
parent52ff5dd0e4ad6436def42b58bc8abe5b534cf739 (diff)
downloadglibc-52ad36a21973c0b4fbc16b7104bbffec765e5a23.tar.gz
glibc-52ad36a21973c0b4fbc16b7104bbffec765e5a23.tar.xz
glibc-52ad36a21973c0b4fbc16b7104bbffec765e5a23.zip
Small optimization of generic ELF hash function
-rw-r--r--ChangeLog1
-rw-r--r--sysdeps/generic/dl-hash.h47
2 files changed, 23 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index 0dfff5cfb5..f4b3460a83 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 2011-12-04  Ulrich Drepper  <drepper@gmail.com>
 
 	* sysdeps/generic/dl-hash.h (_dl_elf_hash): Fix attribute.
+	Minor optimizations.
 
 	* sunrpc/clnt_unix.c (clntunix_control): Fix aliasing issues.
 	* sunrpc/clnt_tcp.c (clnttcp_control): Likewise.
diff --git a/sysdeps/generic/dl-hash.h b/sysdeps/generic/dl-hash.h
index e35bd25a33..28312ca1c4 100644
--- a/sysdeps/generic/dl-hash.h
+++ b/sysdeps/generic/dl-hash.h
@@ -29,42 +29,39 @@ __attribute__ ((unused))
 _dl_elf_hash (const char *name_arg)
 {
   const unsigned char *name = (const unsigned char *) name_arg;
-  unsigned long int hash = 0;
-  if (*name != '\0')
+  unsigned long int hash = *name;
+  if (hash != 0 && name[1] != '\0')
     {
-      hash = *name++;
-      if (*name != '\0')
+      hash = (hash << 4) + name[1];
+      if (name[2] != '\0')
 	{
-	  hash = (hash << 4) + *name++;
-	  if (*name != '\0')
+	  hash = (hash << 4) + name[2];
+	  if (name[3] != '\0')
 	    {
-	      hash = (hash << 4) + *name++;
-	      if (*name != '\0')
+	      hash = (hash << 4) + name[3];
+	      if (name[4] != '\0')
 		{
-		  hash = (hash << 4) + *name++;
-		  if (*name != '\0')
+		  hash = (hash << 4) + name[4];
+		  name += 5;
+		  while (*name != '\0')
 		    {
+		      unsigned long int hi;
 		      hash = (hash << 4) + *name++;
-		      while (*name != '\0')
-			{
-			  unsigned long int hi;
-			  hash = (hash << 4) + *name++;
-			  hi = hash & 0xf0000000;
+		      hi = hash & 0xf0000000;
 
-			  /* The algorithm specified in the ELF ABI is as
-			     follows:
+		      /* The algorithm specified in the ELF ABI is as
+			 follows:
 
-			     if (hi != 0)
-			       hash ^= hi >> 24;
+			 if (hi != 0)
+			   hash ^= hi >> 24;
 
-			     hash &= ~hi;
+			 hash &= ~hi;
 
-			     But the following is equivalent and a lot
-			     faster, especially on modern processors.  */
+			 But the following is equivalent and a lot
+			 faster, especially on modern processors.  */
 
-			  hash ^= hi;
-			  hash ^= hi >> 24;
-			}
+		      hash ^= hi;
+		      hash ^= hi >> 24;
 		    }
 		}
 	    }