This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


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

Re: a .NET alternative (GJC et al)


On 30-Jul-2001, Florian Weimer <Florian.Weimer@RUS.Uni-Stuttgart.DE> wrote:
> Fergus Henderson <fjh@cs.mu.oz.au> writes:
> 
> > Certainly it could be done without support from the GCC back-end.
> 
> Are you sure?

Yes, I'm sure.

> Certain types of optimizations could result in code
> which drops a pointer to a specific object by some arithmetic on it
> and later resurrects it.

That doesn't matter.  The code that the front-end would generate
would ensure that the back-end could not legitimately make such
optimizations in a way that would break the GC.

E.g. for source such as

	void foo() {
		Foo *p;
		Bar *q;
		int x;

		... code using p, q, and x ...
	}

the front-end could generate intermediate code that looks like this:

	class StackFrame {
		virtual void mark_frame() = 0;
	};

	extern StackFrame *current_frame;

	void foo() {
		struct Locals : public StackFrame {
			Foo *p;
			Bar *q;
			StackFrame *prev;
			void mark_frame() { mark(p); mark(q); }
		} locals;
		int x;

		locals.prev = current_frame;
		current_frame = &locals;

		... code using x, locals.p, and locals.q ...
	}

Then the garbage collector can trace the stack by following the `prev'
chain from `current_frame'.  (The mark_frame() method I have here
is only an example; in general you might need other methods, or you
might just store some RTTI information there.)
		
The reason that this technique works is that the back-end compiler can't do any
fancy optimizations on locals.p and local.q, since &locals has been
stored in a global variable and so any function call might update them.
(Actually, to make things thread-safe, it might be better to always pass
`current_frame' as the first argument to every function call, rather than 
using a global variable, but that is just a minor detail.)

The drawback of this technique is that the back-end compiler can't do any
fancy optimizations on locals.p and locals.q ...

Of course the compiler can do whatever fancy optimizations it wants on x,
and it can cache the values of locals.p and locals.q in registers between
function calls (if it does appropriate alias analysis), but it can't cache
their values in registers across function calls.

Now, my intuition is that this problem with preventing fancy optimizations
is going to be bad for performance.  However, I must confess that I
haven't actually implemented it and measured it.  So it might turn out
to be tolerable in practice.

> In addition, isn't the determination of the exact root set only
> possible with type-accurate stack scanning which seems to imply
> backend support?

No, the front-end can structure the structure the stack in such a way
that it can do type-accurate stack scanning without back-end support.
See above.

> > For most of us the main reason to use type-accurate GC rather than
> > conservative GC is to get better performance.  An approach like that
> > would defeat the purpose.
> 
> Are you sure?  I feel somewhat strange when openly trading correctness
> for speed. ;-)

Those of use who are using writing GCC front-ends for languages that have
GC, i.e. Java and Mercury, have *already* traded that correctness for speed.
Given that our current implementation already works for our current users,
I think most of our current users won't want to use something which runs slower.

-- 
Fergus Henderson <fjh@cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.


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