From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26259 invoked by alias); 1 May 2009 22:17:44 -0000 Received: (qmail 26247 invoked by uid 22791); 1 May 2009 22:17:42 -0000 X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,SPF_PASS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.45.13) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 01 May 2009 22:17:34 +0000 Received: from spaceape13.eur.corp.google.com (spaceape13.eur.corp.google.com [172.28.16.147]) by smtp-out.google.com with ESMTP id n41MGg5P013408; Fri, 1 May 2009 15:16:43 -0700 Received: from localhost (elbrus.mtv.corp.google.com [172.18.118.100]) by spaceape13.eur.corp.google.com with ESMTP id n41MGd3t030639; Fri, 1 May 2009 15:16:40 -0700 Received: by localhost (Postfix, from userid 74925) id 4FF8A19C4E1; Fri, 1 May 2009 15:16:39 -0700 (PDT) To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [patch] Eliminate quadratic slow-down on number of soilibs (part 2). Message-Id: <20090501221639.4FF8A19C4E1@localhost> Date: Fri, 01 May 2009 22:17:00 -0000 From: ppluzhnikov@google.com (Paul Pluzhnikov) X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-05/txt/msg00044.txt.bz2 Greetings, This is the patch to eliminate repeated iteration over the same objfile looking for Objective-C methods, as Tom suggested here: http://sourceware.org/ml/gdb-patches/2009-04/msg00551.html Here is the 'diff -w', which is much easier to read due to changed indentation: Index: objc-lang.c =================================================================== RCS file: /cvs/src/src/gdb/objc-lang.c,v retrieving revision 1.77 diff -u -p -u -w -r1.77 objc-lang.c --- objc-lang.c 20 Mar 2009 23:04:33 -0000 1.77 +++ objc-lang.c 1 May 2009 21:50:18 -0000 @@ -76,6 +76,8 @@ struct objc_method { CORE_ADDR imp; }; +static const struct objfile_data *objc_objfile_data; + /* Lookup a structure type named "struct NAME", visible in lexical block BLOCK. If NOERR is nonzero, return zero if NAME is not suitably defined. */ @@ -1154,7 +1156,18 @@ find_methods (struct symtab *symtab, cha if (symtab) block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); - ALL_MSYMBOLS (objfile, msymbol) + ALL_OBJFILES (objfile) + { + unsigned int *objc_csym; + unsigned int objfile_csym = 0; /* Counts ObjC symbols in this + objfile. */ + + objc_csym = objfile_data (objfile, objc_objfile_data); + if (objc_csym != NULL && *objc_csym == 0) + /* There are no ObjC symbols in this objfile. */ + continue; + + ALL_OBJFILE_MSYMBOLS (objfile, msymbol) { QUIT; @@ -1187,6 +1200,8 @@ find_methods (struct symtab *symtab, cha if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL) continue; + objfile_csym++; + if ((type != '\0') && (ntype != type)) continue; @@ -1237,6 +1252,13 @@ find_methods (struct symtab *symtab, cha csym++; } } + if (objc_csym == NULL) + { + objc_csym = xmalloc (sizeof (*objc_csym)); + *objc_csym = objfile_csym; + set_objfile_data (objfile, objc_objfile_data, objc_csym); + } + } if (nsym != NULL) *nsym = csym; @@ -1792,3 +1814,9 @@ resolve_msgsend_super_stret (CORE_ADDR p return 1; return 0; } + +void +_initialize_objc_lang (void) +{ + objc_objfile_data = register_objfile_data (); +} This patch reduces runtime on a test case using 1636 shared libs without any Objective-C in them from 1105 to 450 seconds. Tested on Linux/x86_64 with no regressions. -- Paul Pluzhnikov 2009-05-01 Paul Pluzhnikov * objc-lang.c (objc_objfile_data): New variable. (find_methods): Skip objfiles without Obj-C methods. (_initialize_objc_lang): New function. Index: objc-lang.c =================================================================== RCS file: /cvs/src/src/gdb/objc-lang.c,v retrieving revision 1.77 diff -u -p -u -r1.77 objc-lang.c --- objc-lang.c 20 Mar 2009 23:04:33 -0000 1.77 +++ objc-lang.c 1 May 2009 21:50:10 -0000 @@ -76,6 +76,8 @@ struct objc_method { CORE_ADDR imp; }; +static const struct objfile_data *objc_objfile_data; + /* Lookup a structure type named "struct NAME", visible in lexical block BLOCK. If NOERR is nonzero, return zero if NAME is not suitably defined. */ @@ -1154,87 +1156,107 @@ find_methods (struct symtab *symtab, cha if (symtab) block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK); - ALL_MSYMBOLS (objfile, msymbol) + ALL_OBJFILES (objfile) { - QUIT; - - if ((MSYMBOL_TYPE (msymbol) != mst_text) - && (MSYMBOL_TYPE (msymbol) != mst_file_text)) - /* Not a function or method. */ + unsigned int *objc_csym; + unsigned int objfile_csym = 0; /* Counts ObjC symbols in this + objfile. */ + + objc_csym = objfile_data (objfile, objc_objfile_data); + if (objc_csym != NULL && *objc_csym == 0) + /* There are no ObjC symbols in this objfile. */ continue; - if (symtab) - if ((SYMBOL_VALUE_ADDRESS (msymbol) < BLOCK_START (block)) || - (SYMBOL_VALUE_ADDRESS (msymbol) >= BLOCK_END (block))) - /* Not in the specified symtab. */ - continue; + ALL_OBJFILE_MSYMBOLS (objfile, msymbol) + { + QUIT; + + if ((MSYMBOL_TYPE (msymbol) != mst_text) + && (MSYMBOL_TYPE (msymbol) != mst_file_text)) + /* Not a function or method. */ + continue; - symname = SYMBOL_NATURAL_NAME (msymbol); - if (symname == NULL) - continue; + if (symtab) + if ((SYMBOL_VALUE_ADDRESS (msymbol) < BLOCK_START (block)) || + (SYMBOL_VALUE_ADDRESS (msymbol) >= BLOCK_END (block))) + /* Not in the specified symtab. */ + continue; - if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '[')) - /* Not a method name. */ - continue; + symname = SYMBOL_NATURAL_NAME (msymbol); + if (symname == NULL) + continue; + + if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '[')) + /* Not a method name. */ + continue; - while ((strlen (symname) + 1) >= tmplen) - { - tmplen = (tmplen == 0) ? 1024 : tmplen * 2; - tmp = xrealloc (tmp, tmplen); - } - strcpy (tmp, symname); + while ((strlen (symname) + 1) >= tmplen) + { + tmplen = (tmplen == 0) ? 1024 : tmplen * 2; + tmp = xrealloc (tmp, tmplen); + } + strcpy (tmp, symname); - if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL) - continue; + if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL) + continue; - if ((type != '\0') && (ntype != type)) - continue; + objfile_csym++; - if ((class != NULL) - && ((nclass == NULL) || (strcmp (class, nclass) != 0))) - continue; + if ((type != '\0') && (ntype != type)) + continue; - if ((category != NULL) && - ((ncategory == NULL) || (strcmp (category, ncategory) != 0))) - continue; + if ((class != NULL) + && ((nclass == NULL) || (strcmp (class, nclass) != 0))) + continue; - if ((selector != NULL) && - ((nselector == NULL) || (strcmp (selector, nselector) != 0))) - continue; + if ((category != NULL) && + ((ncategory == NULL) || (strcmp (category, ncategory) != 0))) + continue; + + if ((selector != NULL) && + ((nselector == NULL) || (strcmp (selector, nselector) != 0))) + continue; - sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol)); - if (sym != NULL) - { - const char *newsymname = SYMBOL_NATURAL_NAME (sym); + sym = find_pc_function (SYMBOL_VALUE_ADDRESS (msymbol)); + if (sym != NULL) + { + const char *newsymname = SYMBOL_NATURAL_NAME (sym); - if (strcmp (symname, newsymname) == 0) - { - /* Found a high-level method sym: swap it into the - lower part of sym_arr (below num_debuggable). */ - if (syms != NULL) - { - syms[csym] = syms[cdebug]; - syms[cdebug] = sym; - } - csym++; - cdebug++; - } - else - { - warning ( + if (strcmp (symname, newsymname) == 0) + { + /* Found a high-level method sym: swap it into the + lower part of sym_arr (below num_debuggable). */ + if (syms != NULL) + { + syms[csym] = syms[cdebug]; + syms[cdebug] = sym; + } + csym++; + cdebug++; + } + else + { + warning ( "debugging symbol \"%s\" does not match minimal symbol (\"%s\"); ignoring", - newsymname, symname); - if (syms != NULL) - syms[csym] = (struct symbol *) msymbol; - csym++; - } - } - else + newsymname, symname); + if (syms != NULL) + syms[csym] = (struct symbol *) msymbol; + csym++; + } + } + else + { + /* Found a non-debuggable method symbol. */ + if (syms != NULL) + syms[csym] = (struct symbol *) msymbol; + csym++; + } + } + if (objc_csym == NULL) { - /* Found a non-debuggable method symbol. */ - if (syms != NULL) - syms[csym] = (struct symbol *) msymbol; - csym++; + objc_csym = xmalloc (sizeof (*objc_csym)); + *objc_csym = objfile_csym; + set_objfile_data (objfile, objc_objfile_data, objc_csym); } } @@ -1792,3 +1814,9 @@ resolve_msgsend_super_stret (CORE_ADDR p return 1; return 0; } + +void +_initialize_objc_lang (void) +{ + objc_objfile_data = register_objfile_data (); +}