This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [RFA]: Remove linear search for C++




OK, I committed the following:


2000-10-12  Elena Zannoni  <ezannoni@kwikemart.cygnus.com>

	From Daniel Berlin <dberlin@redhat.com> :

	* symtab.c (lookup_symbol_aux): New function. Renamed from
 	lookup_symbol. Move code to do demangling/case sensitivity to
 	lookup_symbol().
  	(lookup_symbol): Now wrapper for lookup_symbol_aux, so we can
 	perform case sensitivity/demangling without leaking memory.  Move
 	code to do demangling/case sensitivity from old_lookup_symbol to
 	here.
	(lookup_partial_symbol): Use SYMBOL_SOURCE_NAME instead of
 	SYMBOL_NAME.
	(lookup_block_symbol): Use SYMBOL_SOURCE_NAME instead of
 	SYMBOL_NAME. Don't do linear search in case of C++.

  	* symfile.c (compare_symbols): Use SYMBOL_SOURCE_NAME instead of
 	SYMBOL_NAME.
  	(compare_psymbols): Same here.

Index: symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.18
diff -c -u -p -r1.18 symfile.c
--- symfile.c	2000/09/02 00:09:06	1.18
+++ symfile.c	2000/10/12 16:37:15
@@ -212,8 +212,7 @@ compare_symbols (const PTR s1p, const PT
 
   s1 = (struct symbol **) s1p;
   s2 = (struct symbol **) s2p;
-
-  return (STRCMP (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2)));
+  return (STRCMP (SYMBOL_SOURCE_NAME (*s1), SYMBOL_SOURCE_NAME (*s2)));
 }
 
 /*
@@ -241,8 +240,14 @@ compare_symbols (const PTR s1p, const PT
 static int
 compare_psymbols (const PTR s1p, const PTR s2p)
 {
-  register char *st1 = SYMBOL_NAME (*(struct partial_symbol **) s1p);
-  register char *st2 = SYMBOL_NAME (*(struct partial_symbol **) s2p);
+  register struct partial_symbol **s1, **s2;
+  register char *st1, *st2;
+
+  s1 = (struct partial_symbol **) s1p;
+  s2 = (struct partial_symbol **) s2p;
+  st1 = SYMBOL_SOURCE_NAME (*s1);
+  st2 = SYMBOL_SOURCE_NAME (*s2);
+
 
   if ((st1[0] - st2[0]) || !st1[0])
     {
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.15
diff -c -u -p -r1.15 symtab.c
--- symtab.c	2000/09/04 08:29:25	1.15
+++ symtab.c	2000/10/12 16:37:16
@@ -83,6 +83,13 @@ static struct partial_symbol *lookup_par
 
 static struct symtab *lookup_symtab_1 (char *);
 
+static struct symbol *lookup_symbol_aux (const char *name, const
+					 struct block *block, const
+					 namespace_enum namespace, int
+					 *is_a_field_of_this, struct
+					 symtab **symtab);
+
+
 static void cplusplus_hint (char *);
 
 static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
@@ -572,17 +579,14 @@ fixup_psymbol_section (struct partial_sy
    can probably assume it will never hit the C++ code).  */
 
 struct symbol *
-lookup_symbol (const char *name, register const struct block *block,
+lookup_symbol (const char *name, const struct block *block,
 	       const namespace_enum namespace, int *is_a_field_of_this,
 	       struct symtab **symtab)
 {
-  register struct symbol *sym;
-  register struct symtab *s = NULL;
-  register struct partial_symtab *ps;
-  struct blockvector *bv;
-  register struct objfile *objfile = NULL;
-  register struct block *b;
-  register struct minimal_symbol *msymbol;
+  char *modified_name = NULL;
+  char *modified_name2 = NULL;
+  int needtofreename = 0;
+  struct symbol *returnval;
 
   if (case_sensitivity == case_sensitive_off)
     {
@@ -594,9 +598,45 @@ lookup_symbol (const char *name, registe
       for (i= 0; i < len; i++)
         copy[i] = tolower (name[i]);
       copy[len] = 0;
-      name = copy;
+      modified_name = copy;
     }
+  else 
+      modified_name = (char *) name;
+
+  /* If we are using C++ language, demangle the name before doing a lookup, so
+     we can always binary search. */
+  if (current_language->la_language == language_cplus)
+    {
+      modified_name2 = cplus_demangle (modified_name, DMGL_ANSI | DMGL_PARAMS);
+      if (modified_name2)
+	{
+	  modified_name = modified_name2;
+	  needtofreename = 1;
+	}
+    }
+
+  returnval = lookup_symbol_aux (modified_name, block, namespace,
+				 is_a_field_of_this, symtab);
+  if (needtofreename)
+    free (modified_name2);
+
+  return returnval;	 
+}
+
+static struct symbol *
+lookup_symbol_aux (const char *name, const struct block *block,
+	       const namespace_enum namespace, int *is_a_field_of_this,
+	       struct symtab **symtab)
+{
+  register struct symbol *sym;
+  register struct symtab *s = NULL;
+  register struct partial_symtab *ps;
+  register struct blockvector *bv;
+  register struct objfile *objfile = NULL;
+  register struct block *b;
+  register struct minimal_symbol *msymbol;
 
+
   /* Search specified block and its superiors.  */
 
   while (block != 0)
@@ -987,7 +1027,7 @@ lookup_partial_symbol (struct partial_sy
 	    {
 	      do_linear_search = 1;
 	    }
-	  if (STRCMP (SYMBOL_NAME (*center), name) >= 0)
+	  if (STRCMP (SYMBOL_SOURCE_NAME (*center), name) >= 0)
 	    {
 	      top = center;
 	    }
@@ -1190,9 +1230,7 @@ lookup_block_symbol (register const stru
     {
       /* Reset the linear search flag so if the binary search fails, we
          won't do the linear search once unless we find some reason to
-         do so, such as finding a C++ symbol during the binary search.
-         Note that for C++ modules, ALL the symbols in a block should
-         end up marked as C++ symbols. */
+         do so */
 
       do_linear_search = 0;
       top = BLOCK_NSYMS (block);
@@ -1210,22 +1248,19 @@ lookup_block_symbol (register const stru
 	    }
 	  inc = (inc >> 1) + bot;
 	  sym = BLOCK_SYM (block, inc);
-	  if (!do_linear_search
-	      && (SYMBOL_LANGUAGE (sym) == language_cplus
-		  || SYMBOL_LANGUAGE (sym) == language_java
-	      ))
+	  if (!do_linear_search && (SYMBOL_LANGUAGE (sym) == language_java))
 	    {
 	      do_linear_search = 1;
 	    }
-	  if (SYMBOL_NAME (sym)[0] < name[0])
+	  if (SYMBOL_SOURCE_NAME (sym)[0] < name[0])
 	    {
 	      bot = inc;
 	    }
-	  else if (SYMBOL_NAME (sym)[0] > name[0])
+	  else if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
 	    {
 	      top = inc;
 	    }
-	  else if (STRCMP (SYMBOL_NAME (sym), name) < 0)
+	  else if (STRCMP (SYMBOL_SOURCE_NAME (sym), name) < 0)
 	    {
 	      bot = inc;
 	    }
@@ -1247,19 +1282,8 @@ lookup_block_symbol (register const stru
       while (bot < top)
 	{
 	  sym = BLOCK_SYM (block, bot);
-	  inc = SYMBOL_NAME (sym)[0] - name[0];
-	  if (inc == 0)
-	    {
-	      inc = STRCMP (SYMBOL_NAME (sym), name);
-	    }
-	  if (inc == 0 && SYMBOL_NAMESPACE (sym) == namespace)
-	    {
-	      return (sym);
-	    }
-	  if (inc > 0)
-	    {
-	      break;
-	    }
+	  if (SYMBOL_MATCHES_NAME (sym, name))
+	    return sym;
 	  bot++;
 	}
     }


Elena



Daniel Berlin writes:
 > 
 > Once again, I don't have a changelog handy to paste from.
 > It hasn't changed anyway, unless i'm misremembering.
 > I have an exam tomorrow, so it's quite possible i *am* misremembering,
 > and someone did request changelog modifications to the previous patch.
 > 
 > 
 > Elena, this includes the suggested modifications to lookup_symbol, so
 > that needstofreename gets initialized to 0, reducing the amount of
 > code. I have an odd feeling I missed something when changing that
 > code, so i'd appreciate it if you'd double check it for me.
 > It's probably just my stress level, but ....
 > 
 > Index: symfile.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/symfile.c,v
 > retrieving revision 1.18
 > diff -c -3 -p -r1.18 symfile.c
 > *** symfile.c	2000/09/02 00:09:06	1.18
 > --- symfile.c	2000/10/11 03:55:07
 > *************** compare_symbols (const PTR s1p, const PT
 > *** 212,219 ****
 >   
 >     s1 = (struct symbol **) s1p;
 >     s2 = (struct symbol **) s2p;
 > ! 
 > !   return (STRCMP (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2)));
 >   }
 >   
 >   /*
 > --- 212,218 ----
 >   
 >     s1 = (struct symbol **) s1p;
 >     s2 = (struct symbol **) s2p;
 > !   return (STRCMP (SYMBOL_SOURCE_NAME (*s1), SYMBOL_SOURCE_NAME (*s2)));
 >   }
 >   
 >   /*
 > *************** compare_symbols (const PTR s1p, const PT
 > *** 241,248 ****
 >   static int
 >   compare_psymbols (const PTR s1p, const PTR s2p)
 >   {
 > !   register char *st1 = SYMBOL_NAME (*(struct partial_symbol **) s1p);
 > !   register char *st2 = SYMBOL_NAME (*(struct partial_symbol **) s2p);
 >   
 >     if ((st1[0] - st2[0]) || !st1[0])
 >       {
 > --- 240,253 ----
 >   static int
 >   compare_psymbols (const PTR s1p, const PTR s2p)
 >   {
 > !   register struct partial_symbol **s1, **s2;
 > !   register char *st1, *st2;
 > ! 
 > !   s1 = (struct partial_symbol **) s1p;
 > !   s2 = (struct partial_symbol **) s2p;
 > !   st1 = SYMBOL_SOURCE_NAME (*s1);
 > !   st2 = SYMBOL_SOURCE_NAME (*s2);
 > ! 
 >   
 >     if ((st1[0] - st2[0]) || !st1[0])
 >       {
 > Index: symtab.c
 > ===================================================================
 > RCS file: /cvs/src/src/gdb/symtab.c,v
 > retrieving revision 1.15
 > diff -c -3 -p -r1.15 symtab.c
 > *** symtab.c	2000/09/04 08:29:25	1.15
 > --- symtab.c	2000/10/11 03:55:08
 > *************** static struct partial_symbol *lookup_par
 > *** 83,88 ****
 > --- 83,95 ----
 >   
 >   static struct symtab *lookup_symtab_1 (char *);
 >   
 > + static struct symbol *lookup_symbol_aux (const char *name, const
 > + 					 struct block *block, const
 > + 					 namespace_enum namespace, int
 > + 					 *is_a_field_of_this, struct
 > + 					 symtab **symtab);
 > + 
 > + 
 >   static void cplusplus_hint (char *);
 >   
 >   static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
 > *************** fixup_psymbol_section (struct partial_sy
 > *** 572,588 ****
 >      can probably assume it will never hit the C++ code).  */
 >   
 >   struct symbol *
 > ! lookup_symbol (const char *name, register const struct block *block,
 >   	       const namespace_enum namespace, int *is_a_field_of_this,
 >   	       struct symtab **symtab)
 >   {
 > !   register struct symbol *sym;
 > !   register struct symtab *s = NULL;
 > !   register struct partial_symtab *ps;
 > !   struct blockvector *bv;
 > !   register struct objfile *objfile = NULL;
 > !   register struct block *b;
 > !   register struct minimal_symbol *msymbol;
 >   
 >     if (case_sensitivity == case_sensitive_off)
 >       {
 > --- 565,578 ----
 >      can probably assume it will never hit the C++ code).  */
 >   
 >   struct symbol *
 > ! lookup_symbol (const char *name, const struct block *block,
 >   	       const namespace_enum namespace, int *is_a_field_of_this,
 >   	       struct symtab **symtab)
 >   {
 > !   char *modified_name = NULL;
 > !   char *modified_name2 = NULL;
 > !   int needtofreename=0;
 > !   struct symbol *returnval;
 >   
 >     if (case_sensitivity == case_sensitive_off)
 >       {
 > *************** lookup_symbol (const char *name, registe
 > *** 594,601 ****
 >         for (i= 0; i < len; i++)
 >           copy[i] = tolower (name[i]);
 >         copy[len] = 0;
 > !       name = copy;
 >       }
 >   
 >     /* Search specified block and its superiors.  */
 >   
 > --- 584,630 ----
 >         for (i= 0; i < len; i++)
 >           copy[i] = tolower (name[i]);
 >         copy[len] = 0;
 > !       modified_name = copy;
 >       }
 > +   else 
 > +     {    
 > +       modified_name = (char *)name;
 > +     }
 > +   modified_name2 = modified_name; 
 > +   /* If we are using C++ language, demangle the name before doing a lookup, so
 > +      we can always binary search. */
 > +   if (current_language->la_language == language_cplus)
 > +     {
 > +       modified_name2 = cplus_demangle (modified_name, DMGL_ANSI |
 > + 				       DMGL_PARAMS);
 > +       needtofreename=1;
 > +     }
 > +   
 > +   if (!modified_name2)
 > +     {
 > +       modified_name2 = modified_name;
 > +     }
 > +   returnval = lookup_symbol_aux (modified_name2, block, namespace,
 > + 				 is_a_field_of_this, symtab);
 > +   if (needtofreename)
 > +     free(modified_name2);
 > + 
 > +   return returnval;	 
 > + }
 > + 
 > + static struct symbol *
 > + lookup_symbol_aux (const char *name, const struct block *block,
 > + 	       const namespace_enum namespace, int *is_a_field_of_this,
 > + 	       struct symtab **symtab)
 > + {
 > +   register struct symbol *sym;
 > +   register struct symtab *s = NULL;
 > +   register struct partial_symtab *ps;
 > +   register struct blockvector *bv;
 > +   register struct objfile *objfile = NULL;
 > +   register struct block *b;
 > +   register struct minimal_symbol *msymbol;
 > + 
 >   
 >     /* Search specified block and its superiors.  */
 >   
 > *************** lookup_partial_symbol (struct partial_sy
 > *** 987,993 ****
 >   	    {
 >   	      do_linear_search = 1;
 >   	    }
 > ! 	  if (STRCMP (SYMBOL_NAME (*center), name) >= 0)
 >   	    {
 >   	      top = center;
 >   	    }
 > --- 1017,1023 ----
 >   	    {
 >   	      do_linear_search = 1;
 >   	    }
 > ! 	  if (STRCMP (SYMBOL_SOURCE_NAME (*center), name) >= 0)
 >   	    {
 >   	      top = center;
 >   	    }
 > *************** lookup_block_symbol (register const stru
 > *** 1190,1198 ****
 >       {
 >         /* Reset the linear search flag so if the binary search fails, we
 >            won't do the linear search once unless we find some reason to
 > !          do so, such as finding a C++ symbol during the binary search.
 > !          Note that for C++ modules, ALL the symbols in a block should
 > !          end up marked as C++ symbols. */
 >   
 >         do_linear_search = 0;
 >         top = BLOCK_NSYMS (block);
 > --- 1220,1226 ----
 >       {
 >         /* Reset the linear search flag so if the binary search fails, we
 >            won't do the linear search once unless we find some reason to
 > !          do so */
 >   
 >         do_linear_search = 0;
 >         top = BLOCK_NSYMS (block);
 > *************** lookup_block_symbol (register const stru
 > *** 1210,1231 ****
 >   	    }
 >   	  inc = (inc >> 1) + bot;
 >   	  sym = BLOCK_SYM (block, inc);
 > ! 	  if (!do_linear_search
 > ! 	      && (SYMBOL_LANGUAGE (sym) == language_cplus
 > ! 		  || SYMBOL_LANGUAGE (sym) == language_java
 > ! 	      ))
 >   	    {
 >   	      do_linear_search = 1;
 >   	    }
 > ! 	  if (SYMBOL_NAME (sym)[0] < name[0])
 >   	    {
 >   	      bot = inc;
 >   	    }
 > ! 	  else if (SYMBOL_NAME (sym)[0] > name[0])
 >   	    {
 >   	      top = inc;
 >   	    }
 > ! 	  else if (STRCMP (SYMBOL_NAME (sym), name) < 0)
 >   	    {
 >   	      bot = inc;
 >   	    }
 > --- 1238,1256 ----
 >   	    }
 >   	  inc = (inc >> 1) + bot;
 >   	  sym = BLOCK_SYM (block, inc);
 > ! 	  if (!do_linear_search && (SYMBOL_LANGUAGE (sym) == language_java))
 >   	    {
 >   	      do_linear_search = 1;
 >   	    }
 > ! 	  if (SYMBOL_SOURCE_NAME (sym)[0] < name[0])
 >   	    {
 >   	      bot = inc;
 >   	    }
 > ! 	  else if (SYMBOL_SOURCE_NAME (sym)[0] > name[0])
 >   	    {
 >   	      top = inc;
 >   	    }
 > ! 	  else if (STRCMP (SYMBOL_SOURCE_NAME (sym), name) < 0)
 >   	    {
 >   	      bot = inc;
 >   	    }
 > *************** lookup_block_symbol (register const stru
 > *** 1247,1265 ****
 >         while (bot < top)
 >   	{
 >   	  sym = BLOCK_SYM (block, bot);
 > ! 	  inc = SYMBOL_NAME (sym)[0] - name[0];
 > ! 	  if (inc == 0)
 > ! 	    {
 > ! 	      inc = STRCMP (SYMBOL_NAME (sym), name);
 > ! 	    }
 > ! 	  if (inc == 0 && SYMBOL_NAMESPACE (sym) == namespace)
 > ! 	    {
 > ! 	      return (sym);
 > ! 	    }
 > ! 	  if (inc > 0)
 > ! 	    {
 > ! 	      break;
 > ! 	    }
 >   	  bot++;
 >   	}
 >       }
 > --- 1272,1279 ----
 >         while (bot < top)
 >   	{
 >   	  sym = BLOCK_SYM (block, bot);
 > ! 	  if (SYMBOL_MATCHES_NAME (sym, name))
 > ! 	    return sym;
 >   	  bot++;
 >   	}
 >       }
 > 
 > 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]