Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/libexec/ld.elf_so As seen on tech-userlevel...



details:   https://anonhg.NetBSD.org/src/rev/32fa898f8fdc
branches:  trunk
changeset: 537629:32fa898f8fdc
user:      mycroft <mycroft%NetBSD.org@localhost>
date:      Thu Oct 03 20:35:19 2002 +0000

description:
As seen on tech-userlevel...

There are several optimizations here:

1) Objects on _rtld_list_main do not participate in the DAG structures
   at all.  This is okay because all symbols must be resolvable at
   link/load time, and _rtld_list_main is always searched first, so
   any references from those objects must necessarily be resolved to
   other objects on _rtld_list_main.

   (Making this work completely required setting obj->main a bit
   earlier; hence the RTLD_MAIN hack.)

2) Objects on _rtld_list_main are not put on _rtld_list_global,
   preventing an extra search.

3) A bit is used to keep track of whether an object is on
   _rtld_list_global, so we don't have to do a silly linear search.

4) A small attempt is made to prevent objects being put on the DAG
   lists multiple times (using a silly linear search).

The sum of this appears to be a ~10% (.3s) reduction in Mozilla's
startup time on my 800MHz box.

Also, make sure _rtld_objmain->path is always set, just to make the
debug output nicer.

diffstat:

 libexec/ld.elf_so/load.c   |  15 +++++++++++----
 libexec/ld.elf_so/rtld.c   |  39 +++++++++++++++++++++++----------------
 libexec/ld.elf_so/rtld.h   |   8 +++++---
 libexec/ld.elf_so/symbol.c |  13 ++++++++++---
 4 files changed, 49 insertions(+), 26 deletions(-)

diffs (245 lines):

diff -r 76f11cb97de6 -r 32fa898f8fdc libexec/ld.elf_so/load.c
--- a/libexec/ld.elf_so/load.c  Thu Oct 03 20:14:58 2002 +0000
+++ b/libexec/ld.elf_so/load.c  Thu Oct 03 20:35:19 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: load.c,v 1.19 2002/09/23 23:56:46 mycroft Exp $         */
+/*     $NetBSD: load.c,v 1.20 2002/10/03 20:35:19 mycroft Exp $         */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -153,9 +153,16 @@
                free(filepath);
 
        ++obj->refcount;
-       if ((mode & RTLD_GLOBAL) &&
-           _rtld_objlist_find(&_rtld_list_global, obj) == NULL)
+       if (mode & RTLD_MAIN && !obj->mainref) {
+               obj->mainref = 1;
+               rdbg(("adding %p (%s) to _rtld_list_main", obj, obj->path));
+               _rtld_objlist_add(&_rtld_list_main, obj);
+       }
+       if (mode & RTLD_GLOBAL && !obj->globalref) {
+               obj->globalref = 1;
+               rdbg(("adding %p (%s) to _rtld_list_global", obj, obj->path));
                _rtld_objlist_add(&_rtld_list_global, obj);
+       }
        return obj;
 }
 
@@ -291,7 +298,7 @@
        if (preload_path != NULL) {
                cp = buf = xstrdup(preload_path);
                while ((path = strsep(&cp, " :")) != NULL && status == 0) {
-                       if (!_rtld_load_object(xstrdup(path), RTLD_GLOBAL))
+                       if (!_rtld_load_object(xstrdup(path), RTLD_MAIN))
                                status = -1;
                        else
                                dbg((" preloaded \"%s\"", path));
diff -r 76f11cb97de6 -r 32fa898f8fdc libexec/ld.elf_so/rtld.c
--- a/libexec/ld.elf_so/rtld.c  Thu Oct 03 20:14:58 2002 +0000
+++ b/libexec/ld.elf_so/rtld.c  Thu Oct 03 20:35:19 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtld.c,v 1.83 2002/10/03 01:09:21 mycroft Exp $         */
+/*     $NetBSD: rtld.c,v 1.84 2002/10/03 20:35:20 mycroft Exp $         */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -221,7 +221,6 @@
        const char     *ld_bind_now;
        const char    **argv;
        long            argc;
-       Obj_Entry       *obj;
        const char **real___progname;
        const Obj_Entry **real___mainprog_obj;
        char ***real_environ;
@@ -344,8 +343,8 @@
        if (pAUX_execfd != NULL) {      /* Load the main program. */
                int             fd = pAUX_execfd->a_v;
                dbg(("loading main program"));
-               _rtld_objmain = _rtld_map_object(argv[0] ? xstrdup(argv[0]) :
-                   xstrdup("main program"), fd, NULL);
+               _rtld_objmain = _rtld_map_object(xstrdup(argv[0] ? argv[0] :
+                   "main program"), fd, NULL);
                close(fd);
                if (_rtld_objmain == NULL)
                        _rtld_die();
@@ -364,6 +363,8 @@
                assert(pAUX_entry != NULL);
                entry = (caddr_t) pAUX_entry->a_v;
                _rtld_objmain = _rtld_digest_phdr(phdr, phnum, entry);
+               _rtld_objmain->path = xstrdup(argv[0] ? argv[0] :
+                   "main program");
        }
 
        _rtld_objmain->mainprog = true;
@@ -381,13 +382,16 @@
        
        _rtld_digest_dynamic(_rtld_objmain);
 
+       /* Link the main program into the list of objects. */
+       *_rtld_objtail = _rtld_objmain;
+       _rtld_objtail = &_rtld_objmain->next;
+
        _rtld_linkmap_add(_rtld_objmain);
        _rtld_linkmap_add(&_rtld_objself);
 
-       /* Link the main program into the list of objects. */
-       *_rtld_objtail = _rtld_objmain;
-       _rtld_objtail = &_rtld_objmain->next;
        ++_rtld_objmain->refcount;
+       _rtld_objmain->mainref = 1;
+       _rtld_objlist_add(&_rtld_list_main, _rtld_objmain);
 
        /* Initialize a fake symbol for resolving undefined weak references. */
        _rtld_sym_zero.st_info = ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE);
@@ -402,14 +406,9 @@
                _rtld_die();
 
        dbg(("loading needed objects"));
-       if (_rtld_load_needed_objects(_rtld_objmain, RTLD_GLOBAL) == -1)
+       if (_rtld_load_needed_objects(_rtld_objmain, RTLD_MAIN) == -1)
                _rtld_die();
 
-       for (obj = _rtld_objlist; obj != NULL; obj = obj->next) {
-               obj->main = 1;
-               _rtld_objlist_add(&_rtld_list_main, obj);
-       }
-
        dbg(("relocating objects"));
        if (_rtld_relocate_objects(_rtld_objmain, bind_now) == -1)
                _rtld_die();
@@ -499,9 +498,14 @@
 {
        const Needed_Entry *needed;
 
-       _rtld_objlist_add(&obj->dldags, root);
-       if (!obj->main)
+       if (!obj->mainref) {
+               if (_rtld_objlist_find(&obj->dldags, root))
+                       return;
+               rdbg(("add %p (%s) to %p (%s) DAG", obj, obj->path, root,
+                   root->path));
+               _rtld_objlist_add(&obj->dldags, root);
                _rtld_objlist_add(&root->dagmembers, obj);
+       }
        for (needed = obj->needed; needed != NULL; needed = needed->next)
                if (needed->obj != NULL)
                        _rtld_init_dag1(root, needed->obj);
@@ -532,7 +536,10 @@
                        _rtld_objlist_remove(&elm->obj->dldags, root);
 
                /* Remove the DAG from the RTLD_GLOBAL list. */
-               _rtld_objlist_remove(&_rtld_list_global, root);
+               if (root->globalref) {
+                       root->globalref = 0;
+                       _rtld_objlist_remove(&_rtld_list_global, root);
+               }
 
                /* Unmap all objects that are no longer referenced. */
                linkp = &_rtld_objlist->next;
diff -r 76f11cb97de6 -r 32fa898f8fdc libexec/ld.elf_so/rtld.h
--- a/libexec/ld.elf_so/rtld.h  Thu Oct 03 20:14:58 2002 +0000
+++ b/libexec/ld.elf_so/rtld.h  Thu Oct 03 20:35:19 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtld.h,v 1.61 2002/10/03 01:09:21 mycroft Exp $         */
+/*     $NetBSD: rtld.h,v 1.62 2002/10/03 20:35:20 mycroft Exp $         */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -115,6 +115,7 @@
 
 #define RTLD_MAGIC     0xd550b87a
 #define RTLD_VERSION   1
+#define        RTLD_MAIN       0x800
 
 typedef struct Struct_Obj_Entry {
        Elf32_Word      magic;          /* Magic number (sanity check) */
@@ -183,7 +184,8 @@
                                         * "-Bsymbolic" */
                        printed:1,      /* True if ldd has printed it */
                        isdynamic:1,    /* True if this is a pure PIC object */
-                       main:1;         /* True if on _rtld_list_main */
+                       mainref:1,      /* True if on _rtld_list_main */
+                       globalref:1;    /* True if on _rtld_list_global */
 
        struct link_map linkmap;        /* for GDB */
 
@@ -258,7 +260,7 @@
 const Elf_Sym *_rtld_find_symdef __P((unsigned long, const Obj_Entry *,
     const Obj_Entry **, bool));
 const Elf_Sym *_rtld_symlook_list(const char *, unsigned long,
-  Objlist *, const Obj_Entry **, bool);
+    const Objlist *, const Obj_Entry **, bool);
 
 /* map_object.c */
 Obj_Entry *_rtld_map_object __P((char *, int, const struct stat *));
diff -r 76f11cb97de6 -r 32fa898f8fdc libexec/ld.elf_so/symbol.c
--- a/libexec/ld.elf_so/symbol.c        Thu Oct 03 20:14:58 2002 +0000
+++ b/libexec/ld.elf_so/symbol.c        Thu Oct 03 20:35:19 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: symbol.c,v 1.22 2002/09/24 20:27:07 mycroft Exp $       */
+/*     $NetBSD: symbol.c,v 1.23 2002/10/03 20:35:20 mycroft Exp $       */
 
 /*
  * Copyright 1996 John D. Polstra.
@@ -74,7 +74,7 @@
 }
 
 const Elf_Sym *
-_rtld_symlook_list(const char *name, unsigned long hash, Objlist *objlist,
+_rtld_symlook_list(const char *name, unsigned long hash, const Objlist *objlist,
   const Obj_Entry **defobj_out, bool in_plt)
 {
        const Elf_Sym *symp;
@@ -85,6 +85,7 @@
        def = NULL;
        defobj = NULL;
        SIMPLEQ_FOREACH(elm, objlist, link) {
+               rdbg(("search object %p (%s)", elm->obj, elm->obj->path));
                if ((symp = _rtld_symlook_obj(name, hash, elm->obj, in_plt))
                    != NULL) {
                        if ((def == NULL) ||
@@ -127,6 +128,7 @@
                assert(symnum < obj->nchains);
                symp = obj->symtab + symnum;
                strp = obj->strtab + symp->st_name;
+               rdbg(("check %s vs %s in %p", name, strp, obj));
                if (name[1] == strp[1] && !strcmp(name, strp)) {
                        if (symp->st_shndx != SHN_UNDEF)
                                return symp;
@@ -192,6 +194,7 @@
        
        /* Search all objects loaded at program start up. */
        if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
+               rdbg(("search _rtld_list_main"));
                symp = _rtld_symlook_list(name, hash, &_rtld_list_main, &obj, in_plt);
                if (symp != NULL &&
                    (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
@@ -204,6 +207,7 @@
        SIMPLEQ_FOREACH(elm, &refobj->dldags, link) {
                if (def != NULL && ELF_ST_BIND(def->st_info) != STB_WEAK)
                        break;
+               rdbg(("search DAG with root %p (%s)", elm->obj, elm->obj->path));
                symp = _rtld_symlook_list(name, hash, &elm->obj->dagmembers, &obj, in_plt);
                if (symp != NULL &&
                    (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
@@ -214,6 +218,7 @@
        
        /* Search all RTLD_GLOBAL objects. */
        if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
+               rdbg(("search _rtld_list_global"));
                symp = _rtld_symlook_list(name, hash, &_rtld_list_global, &obj, in_plt);
                if (symp != NULL &&
                    (def == NULL || ELF_ST_BIND(symp->st_info) != STB_WEAK)) {
@@ -234,8 +239,10 @@
        
        if (def != NULL)
                *defobj_out = defobj;
-       else
+       else {
+               rdbg(("lookup failed"));
                _rtld_error("%s: Undefined %ssymbol \"%s\" (symnum = %ld)",
                    refobj->path, in_plt ? "PLT " : "", name, symnum);
+       }
        return def;
 }



Home | Main Index | Thread Index | Old Index