This is the mail archive of the gdb@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]
Other format: [Raw text]

Re: struct environment


On Tue, 17 Sep 2002 03:47:36 -0400, Andrew Cagney
<ac131313@ges.redhat.com> said:

Daniel's already chimed in on this, and I think I agree with
everything he's said, but let me throw in my own two cents as well.

> Per the original thread, this should be prototyped on a branch (you
> can then cut your self loose for a bit :-).

I thought about that; here's a question I have with regards to that.
It seems to me that, if I wanted to make large numbers of changes all
at once, then a branch would clearly be the way to go: nobody's going
to want to see a monolithic patch without having it be well-tested.

But nobody likes monolithic patches anyways; whenever somebody posts a
large patch, it's followed by complaints asking for the patch to be
broken up into smaller pieces, and the original poster then says it's
not possible.  If you want smaller pieces, then incremental changes
are are the way to go; I seem to recall that, in the original
discussion back in April, a branch was proposed because people didn't
believe that doing this incrementally was possible.

I'm confident that doing it incrementally is possible; that's why I'm
proposing adapting the existing functionality by first handling struct
block, and then handling the global environment; and, in turn, I'm
handling struct block in a three-phase process, such that the
semantics are unchanged after each phase and that, in turn, each phase
can be broken up into multiple patches so that, say, the Java
maintainers don't have to be confronted with changes to mdebugread.c.

I don't mind doing this on a branch, and even doing it incrementally
on a branch.  I'm not enough of an expert on CVS to know how easy it
is to merge in incremental branch changes to the mainline; but I
assume CVS will help me with that.  But it would still be a pain, I
think: if I'm going to do it incrementally, and take the care to leave
GDB in a useable state at all times, I'd rather do it on mainline.

> Having done this for regcache and reggroup it is worth it -> you get
> to see what actually works rather than what everyone else thinks
> should work.  You can also pick out the cleanups that will make the
> final change easier.  For instance - tightening up the way GDB
> creates symbol tables (DanielB suggested moving psymtab into stabs)
> an performs lookups on them.

Personally, I'd rather tighten up the interface to symbol lookups
first and only then move on to optimizations like changing how
reading in a part of the symbol information is implemented.

> Btw, try ``struct nametab''?  These are just tables for mapping a name
> onto a symbol?

Right, but "nametab" = "table of names", whereas it's really a table
of symbols, i.e. a symtab.  But that name's already used elsewhere.

> Have a look at how I've been evolving ``struct frame_info'' and
> ``struct cmd_list_element[?]'':

Thanks for the pointer; I'll give it a look.

> - tighten up the existing interface so that you know how things are
>   really used (rather than how you think things are used).  My trick
>   was to do a temp rename of a field and then convert to accessor
>   methods anything that didn't compile.

> - with a tight interface, re-implement the internals.

I think these are a pretty good description of what I'm actually
doing.  Except that, I've broken up your first step somewhat: rather
than renaming a field, I'm adding a new field that provides the same
functionality as existing fields, then converting the accessors over a
little more gradually, then deleting the existing field.  It lets me
make my patches a lot smaller.

> Having also gone over the original thread, two things come to mind:

> - what effect will this have on GDB's foot print?  The original
>   proposal was to put these things everwhere (structs, unions, ...).
>   I don't think that is necessary and would cause serious bloat.

I certainly want to put them in blocks, to use them to represent the
global environment, and to use them to represent namespaces; those are
the core name->symbol translation areas.

It seems to me that the main borderline issue is whether or not to use
them to represent fields in structures/classes.  The advantage of
that, from the C++ (and presumably Java) point of view, is that there
are times when you can refer to fields of structures as if they were
variables; the existing solution, namely the is_a_field_of_this
argument to lookup_symbol, is ugly, probably not flexible enough to
handle C++ and Java correctly (e.g. what about nested classes in
Java?), and complicates the interface for code that doesn't need this
functionality (e.g. when debugging C code).

But, as you say, that leads to code bloat: struct field really is
smaller than struct symbol, after all.  And it might well be the
casethat making struct field a special case of struct symbol would
make life more complicated for, say, C code that wants to use struct
field.

So no, I'm not proposing converting structs, unions, etc. over to
this; I don't think that's a good idea for now, and possibly not a
good idea ever.

>   Instead, initially, I think these tables could be simple linear
>   lists (that is what ``struct block'' currently implements so it
>   can't be any worse :-) (just the global / final table is special
>   :-).

For struct block, I'm tracking existing design extremely closely.
Currently, struct block has these options:

* Hash tables.  (Used almost everywhere.)
* Lists that aren't sorted by name.  (Used in blocks that are the body
  of functions, and in Java's dynamic class table.)
* Lists that are sorted by name.  (Used by mdebugread.c in places
  where hash tables should be used.)

Most of these can't grow, but jv-lang.c and mdebugread.c both have
code by which lists can grow.

When the struct block conversion is done, the only change will be that
sorted lists will go away (since they're only used by mdebugread.c,
which should be converted over to using hash tables instead), and that
the common code in jv-lang.c and mdebugread.c to allow lists that grow
will all be in one place.  No other changes: extremely similar data
structures, exactly the same algorithms.

> - Am I correct to think that the objective is to create a directed
>   acyclic graph of nametabs and have lookups search through each in
>   turn.

Not quite as Daniel has explained; C++'s name lookup rules are pretty
complicated.  Which isn't to say that we have to track those name
lookup rules perfectly: e.g. it's not the end of the world if we don't
notice that a name lookup is ambiguous where a C++ compiler would be
required to notice that.  But it is, I think, a bad idea if we miss a
symbol that we should find, or if we return the wrong symbol instead
of the right one.

> In terms of operations, I would concentrate on determing exactly GDB
> needs (rather than you think it needs) GDB is 15 years old so chance
> has it the operations have been identified already.  I know of two
> operations off hand:

> 	print foo
> which gets turned into struct symbol *lookup("foo",``block'') and,
> 	print foo<tab>
> which turns into ``const char **tabexpand("foo", ``block'')''.  Any others?

I don't see tabexpand anywhere.  Maybe it's been subsumed by
search_symbols?

David Carlton
carlton@math.stanford.edu


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