stack manipulation APIs
lukas.stadler at jku.at
Mon Apr 7 04:20:58 PDT 2008
Steven Shaw wrote:
> On 27/03/2008, Lukas Stadler <lukas.stadler at jku.at> wrote:
>> This could lead to all sorts of harmful behavior, like exiting a
>> monitor twice, etc. Should this be possible, or will only a
>> restricted case be implemented? There would have to be a big red
>> sign (and possibly some kind of verifier) with all the things that
>> aren't allowed in such code.
>> I recently looked at the apache commons Javaflow library - they
>> implement storing the current stack state using only bytecode
>> instrumentation and a small and unintrusive runtime framework. (I
>> can write a short summary of how they're doing this if anyone is
>> interested.) I think that, as their implementation is inherently
>> safe, we could partly adopt its behaviour.
> Hi Lukas, I'd like to hear how the Javaflow works at the byte level
> and what they do with monitor entry/exit. I assume they implement
> multi-shot continuations?
Yes, they implement multi-shot continuations. The javaflow library is a
prime example of the power of bytecode-rewriting. It uses a thread-local
object "StackRecorder" to control the behavior of the modified methods.
A thread can be in one of three states: execute, capture or restore.
Depending on this state the methods behave completely different:
execute: normal execution with no special behavior. "finally" - clauses
will only be executed in this state.
capture: whenever a method call returns the current method stores its
local variables to the StackRecorder and returns immediately.
restore: when a method is called it restores its local variables from
the StackRecorder and continues at the old location.
This also makes it clear how javaflow handles monitor entry/exit - it
doesn't. It implicitly releases and locks the monitors.
Javaflow also doesn't provide any way to implement a dynamic-wind
structure - but this could be implemented relatively easy. I assume it
just wasn't needed.
BTW I met with Peter Feigl last week who is an expert for Scheme
While talking about continuations and Scheme implementations in general
and it became clear that if (big if!) a scheme implementation supports
fully-fledged continuations then it does so by copying the contents of
the stack. Some implementations use a segmented stack approach that
copies stack segments on-demand. This could also be achieved in the MLVM
by inserting handlers into the stack return addresses (like
deoptimization does) every x frames or every ~y bytes.
Interestingly most uses of continuations can be replaced by simple
non-local exits - and a good compiler can detect these most of the time
by escape analysis!
One thing that came up was how continuations behave if they are called
in different threads (maybe at the same time?). Scheme itself doesn't
define any behavior for this case. Another interesting problem are
delimited continuations - part of the stack is turned into a function
that returns a value.
A good library of research papers for Scheme implementations:
More information about the mlvm-dev