Thread View: gnu.gdb.bug
1 messages
1 total messages
Started by Michael Tiemann
Fri, 01 Dec 1989 05:51
GDB vs GNU C++
Author: Michael Tiemann
Date: Fri, 01 Dec 1989 05:51
Date: Fri, 01 Dec 1989 05:51
117 lines
4150 bytes
4150 bytes
These diffs fix a performance bug I wrote into GDB about two years
ago. The bug is that when you ask GDB to print the value of `foo', it
has to look up `foo' in the various contexts that `foo' could belong
to. In the case of member functions, it must check whether `foo' is a
field of `this'. In the original code I wrote, I saved the wrong
cycles when I indirected `this' to get the structure definition so I
could look up the name in the type. In parallel with doing the
indirection for the name lookup, I had GDB go and fetch the object
from memory, so its value would be close at hand on a hit. Well, this
leads to slightly reduced performance in the case where the object is
small, it's just a call to ptrace that didn't need to be made.
However, I was wondering why GDB was taking so long to find that a
particular name was not in scope, and I found that my object, all 200K
of it, was being ptraced into my address space just to do the search!
Yow!
teacake% diff -c2 valops.c~ valops.c
*** valops.c~ Sun Nov 5 10:04:33 1989
--- valops.c Thu Nov 30 21:36:54 1989
***************
*** 1009,1017 ****
while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
! {
! arg1 = value_ind (arg1);
! COERCE_ARRAY (arg1);
! t = VALUE_TYPE (arg1);
! }
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
--- 1009,1013 ----
while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
! t = TYPE_TARGET_TYPE (t);
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
***************
*** 1030,1036 ****
char *t_field_name = TYPE_FIELD_NAME (t, i);
if (t_field_name && !strcmp (t_field_name, name))
! {
! return 1;
! }
}
if (TYPE_N_BASECLASSES (t) == 0)
--- 1026,1030 ----
char *t_field_name = TYPE_FIELD_NAME (t, i);
if (t_field_name && !strcmp (t_field_name, name))
! goto success;
}
if (TYPE_N_BASECLASSES (t) == 0)
***************
*** 1038,1042 ****
t = TYPE_BASECLASS (t, 1);
- VALUE_TYPE (arg1) = t; /* side effect! */
}
--- 1032,1035 ----
***************
*** 1048,1052 ****
/* Destructors are a special case. */
if (destructor_name_p (name, t))
! return 1;
while (t)
--- 1041,1045 ----
/* Destructors are a special case. */
if (destructor_name_p (name, t))
! goto success;
while (t)
***************
*** 1064,1067 ****
--- 1057,1069 ----
}
return 0;
+
+ success:
+ t = VALUE_TYPE (arg1);
+ while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
+ {
+ arg1 = value_ind (arg1);
+ COERCE_ARRAY (arg1);
+ t = VALUE_TYPE (arg1);
+ }
}
teacake%
This could still be done better: `check_field' should not read in the
whole object. It should be up to the caller to decide whether to
ptrace in the memory. Right now the following code from
`lookup_symbol' (symtab.c)
/* C++: If requested to do so by the caller,
check to see if NAME is a field of `this'. */
if (is_a_field_of_this)
{
int v = (int) value_of_this (0);
*is_a_field_of_this = 0;
if (v && check_field (v, name))
{
*is_a_field_of_this = 1;
return 0;
}
}
is the only place where check_field is called, and it clearly is not
using its value. Since the published interface of `check_field' does
not indicate that it brings values in from disk, I advocate removing
that paging-in mis-feature altogether, but I'll leave the final
decision to Jim.
Michael
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads