Module Name:    src
Committed By:   joerg
Date:           Mon Apr  5 14:01:26 UTC 2010

Modified Files:
        src/libexec/ld.elf_so: headers.c reloc.c rtld.h symbol.c

Log Message:
Use fast_remainder32 for the ELF hash. For the hot cache case, this
speeds up Firefox startup by over 2% on AMD64.
Limit hash table buckets to 32bit.


To generate a diff of this commit:
cvs rdiff -u -r1.28 -r1.29 src/libexec/ld.elf_so/headers.c
cvs rdiff -u -r1.101 -r1.102 src/libexec/ld.elf_so/reloc.c
cvs rdiff -u -r1.90 -r1.91 src/libexec/ld.elf_so/rtld.h
cvs rdiff -u -r1.52 -r1.53 src/libexec/ld.elf_so/symbol.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/libexec/ld.elf_so/headers.c
diff -u src/libexec/ld.elf_so/headers.c:1.28 src/libexec/ld.elf_so/headers.c:1.29
--- src/libexec/ld.elf_so/headers.c:1.28	Sun Apr 12 13:29:29 2009
+++ src/libexec/ld.elf_so/headers.c	Mon Apr  5 14:01:26 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: headers.c,v 1.28 2009/04/12 13:29:29 lukem Exp $	 */
+/*	$NetBSD: headers.c,v 1.29 2010/04/05 14:01:26 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: headers.c,v 1.28 2009/04/12 13:29:29 lukem Exp $");
+__RCSID("$NetBSD: headers.c,v 1.29 2010/04/05 14:01:26 joerg Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -53,6 +53,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/bitops.h>
 #include <dirent.h>
 
 #include "debug.h"
@@ -138,10 +139,23 @@
 				const Elf_Word *hashtab = (const Elf_Word *)
 				(obj->relocbase + dynp->d_un.d_ptr);
 
-				obj->nbuckets = hashtab[0];
+				if (hashtab[0] > UINT32_MAX)
+					obj->nbuckets = UINT32_MAX;
+				else
+					obj->nbuckets = hashtab[0];
 				obj->nchains = hashtab[1];
 				obj->buckets = hashtab + 2;
 				obj->chains = obj->buckets + obj->nbuckets;
+				/*
+				 * Should really be in _rtld_relocate_objects,
+				 * but _rtld_symlook_obj might be used before.
+				 */
+				if (obj->nbuckets) {
+					fast_divide32_prepare(obj->nbuckets,
+					    &obj->nbuckets_m,
+					    &obj->nbuckets_s1,
+					    &obj->nbuckets_s2);
+				}
 			}
 			break;
 

Index: src/libexec/ld.elf_so/reloc.c
diff -u src/libexec/ld.elf_so/reloc.c:1.101 src/libexec/ld.elf_so/reloc.c:1.102
--- src/libexec/ld.elf_so/reloc.c:1.101	Sat Jan 16 10:37:51 2010
+++ src/libexec/ld.elf_so/reloc.c	Mon Apr  5 14:01:26 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: reloc.c,v 1.101 2010/01/16 10:37:51 skrll Exp $	 */
+/*	$NetBSD: reloc.c,v 1.102 2010/04/05 14:01:26 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: reloc.c,v 1.101 2010/01/16 10:37:51 skrll Exp $");
+__RCSID("$NetBSD: reloc.c,v 1.102 2010/04/05 14:01:26 joerg Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -52,6 +52,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/bitops.h>
 #include <dirent.h>
 
 #include "debug.h"
@@ -154,6 +155,10 @@
 			    " symbol table", obj->path);
 			return -1;
 		}
+		if (obj->nbuckets == UINT32_MAX) {
+			_rtld_error("%s: Symbol table too large", obj->path);
+			return -1;
+		}
 		rdbg((" relocating %s (%ld/%ld rel/rela, %ld/%ld plt rel/rela)",
 		    obj->path,
 		    (long)(obj->rellim - obj->rel),

Index: src/libexec/ld.elf_so/rtld.h
diff -u src/libexec/ld.elf_so/rtld.h:1.90 src/libexec/ld.elf_so/rtld.h:1.91
--- src/libexec/ld.elf_so/rtld.h:1.90	Thu Mar 18 22:17:55 2010
+++ src/libexec/ld.elf_so/rtld.h	Mon Apr  5 14:01:26 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtld.h,v 1.90 2010/03/18 22:17:55 roy Exp $	 */
+/*	$NetBSD: rtld.h,v 1.91 2010/04/05 14:01:26 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -162,7 +162,10 @@
 #endif
 
 	const Elf_Word *buckets;	/* Hash table buckets array */
-	unsigned long   nbuckets;	/* Number of buckets */
+	uint32_t        nbuckets;	/* Number of buckets */
+	uint32_t        nbuckets_m;	/* Precomputed for fast remainder */
+	uint8_t         nbuckets_s1;
+	uint8_t         nbuckets_s2;
 	const Elf_Word *chains;		/* Hash table chain array */
 	unsigned long   nchains;	/* Number of chains */
 

Index: src/libexec/ld.elf_so/symbol.c
diff -u src/libexec/ld.elf_so/symbol.c:1.52 src/libexec/ld.elf_so/symbol.c:1.53
--- src/libexec/ld.elf_so/symbol.c:1.52	Thu Mar 18 22:17:55 2010
+++ src/libexec/ld.elf_so/symbol.c	Mon Apr  5 14:01:26 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: symbol.c,v 1.52 2010/03/18 22:17:55 roy Exp $	 */
+/*	$NetBSD: symbol.c,v 1.53 2010/04/05 14:01:26 joerg Exp $	 */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: symbol.c,v 1.52 2010/03/18 22:17:55 roy Exp $");
+__RCSID("$NetBSD: symbol.c,v 1.53 2010/04/05 14:01:26 joerg Exp $");
 #endif /* not lint */
 
 #include <err.h>
@@ -53,6 +53,7 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/bitops.h>
 #include <dirent.h>
 
 #include "debug.h"
@@ -229,7 +230,8 @@
 {
 	unsigned long symnum;
 
-	for (symnum = obj->buckets[hash % obj->nbuckets];
+	for (symnum = obj->buckets[fast_remainder32(hash, obj->nbuckets,
+	     obj->nbuckets_m, obj->nbuckets_s1, obj->nbuckets_s2)];
 	     symnum != ELF_SYM_UNDEFINED;
 	     symnum = obj->chains[symnum]) {
 		const Elf_Sym  *symp;

Reply via email to