I won't go into what I think about performing reflection on stalled
functions except to say I think debugging is the only valid reason to
do it.

As for GC, there are ways to implement precise GC of the stack that
don't need a frame pointer. The most obvious is tagged data, but that
isn't necessary either. Another possibility is to make it IP-based
(like exceptions). Since the compiler knows the frame layout, it can
associate with each user function a small GC function that processes
the frame, identifies the caller from the return address and
progressively calls the callers GC function, etc.

[I'm actually a fan of making GC based on special purpose functions as
much as possible rather than embedding pointer maps everywhere and
having generic code interpret them. IME using special functions
simplifies the GC and it's interface to the runtime (GC only needs to
know how to call a function given a data object) and results in better
data locality and cache behavior.]

>for example, due to this deficiency one has to use another location to hold>a list of linked exception frames, which actually hurts raw performance in>general (universally keeping the frame pointer allows very lightweight>exception handling, since the only time anything is actually done specially>is during the exception itself, but otherwise the code is structured as if>there were no exception handler).>>now, with no frame pointer, the compiler has to go and endlessly link in and>unlink exception frames (representing the try block), which is not free...>and the compiler can't just simply add this cheaper approach, because it is>not possible to implicitly unwind.

This all depends on the implementation. I can easily envision using
dual stacks: a control stack with fixed sized structures and a
separate data stack framed implicitly. I can think of a few other
unconventional implementations as well.

I understand that one of the goals of your project is to mix in
existing code, but that particular focus is coloring your thoughts.
Features like frame pointers evolve because they are either necessary
or helpful in a particular context. Change the context and they can
become irrelevant.

>the issue is not so much debugging, but the frame-pointer may be useful in>in implementing many kinds of compiler and runtime features, which are then>fouled up by the presence of code in the call frame which does not allow>proper unwinding, and where the information necessary for this unwinding is>not available.

I'm not disagreeing with you ... frame pointers are useful for lots of
things. I'm just playing devil's advocate to get you thinking about
it.

>the lack of information leads to many kinds of difficulties, which is partly>why traditionally C and C++ are forced to use conservative garbage>collectors, ... when, technically, it would not cost much for the compiler>to leave the necessary information in the app itself (be it something as>simple as a frame pointer, to the symbol table, to the type annotations of>variables and functions, ...).

Sorry, this is a fallacy. Completely precise GC is not possible in C
or C++ ... the language semantics don't allow it. The best that can
be achieved without revising the language specs is to be conservative
in the stack and to be as precise as possible in the global roots and
heap. It is possible to be precise in the heap unless there are
untagged unions ... if so, you are back to guessing.

Bartlett, Boehm, Detlef, Ellis and others have written at length about
the problems of adding GC to uncooperative languages. Boehm, in
particular, has written a lot about how to improve conservative
pointer guessing by eliminating impossible values. Detlef and Ellis
have a current proposal for a library based GC to be added to C++.
Google is your friend.