Impossible states in full-state frame making (OSR)
Created by: wks
There was a proposal about the OSR before, https://github.com/microvm/microvm-meta/issues/5
According to our discussion recently, we decided that:
- the state of a frame is the PC and a set of local variable values.
- It should be only possible to continue from some designated "OSR points", or the beginning of a basic block, rather than from arbitrary point in the code. This reduces the compiler's burden to generate stack maps.
- The client supplies an arbitrary subset of local variables and their values and
- if a variable is supplied but is never used, it has no effect on the execution and is simply ignored.
- if a variable is not supplied but is used later, it gives undefined behaviour.
But this leads to a problem: the supplied state may never be reproducible from normal execution. For example:
.funcsig @foo_sig = @i64 (@i64 @i64)
.funcdef @foo VERSION @foo_v1 <@foo_sig> (%a %b) {
%entry:
%x = MUL <@i64> %a %b
%y = ADD <@i64> %x @i64_0 // The rhs is the constant 0.
%trap = TRAP <@void>
// OSR continues here
CALL @print (%x)
CALL @print (%y)
RET <@i64> %y
}
Assume we perform an OSR and construct a frame which continues after the %trap
instruction with local variable values: %a = 6; %b = 9; %x = 42; %y = 54
. Then the value %x = 42
is impossible.
But the code generator may consider "adding zero" as a no-op and thus generates the machine code that aliases the register of %x
and %y
. For example:
foo:
push rbx ; save callee-saved register
mov rbx, rdi ; do multiplication. rbx holds the value of %x and also %y
mul rbx, rsi
mov rdi, rbx ; prepare to call @print (%x)
call print
mov rdi, rbx ; prepare to call @print (%y)
call print
pop rbx
ret
Then it is impossible to create such a state as mentioned above. This implies that either
- we require that such state construction must be possible and require the code generator not to generate the code like above, or
- we further restrict our API on frame state construction.