[m-dev.] MR_{save/restore}_transient_hp().

Zoltan Somogyi zoltan.somogyi at runbox.com
Thu Jul 24 18:07:10 AEST 2014

On Thu, 24 Jul 2014 12:17:30 +1000, Paul Bone <paul at bone.id.au> wrote:
> What I don't know is when this says "from C" does it mean from foreign_proc
> macros?  And do I understand correctly that the concern is that the heap
> pointer is saved in a register that may be clobbered by external C code, and
> therefore I need to restore that pointer before allocating memory and save
> it again after allocating the memory?

The macros that have "transient" in their name are there to allow code to handle
a mismatch between the register model used by the Mercury low level abstract
machine (i.e. the registers are always there, and are modified only by explicit
assignments to them), and the sliding register windows on SPARC (the set of
visible registers changes with every call and return instruction, and therefore
those instructions implicitly change the values stored in the windowed registers).

The relevant criterion is not C code versus Mercury code, but code that can
make ISA calls and code that cannot. In grade asm_fast, Mercury does not
make ISA calls; it just does jumps. Foreign code that does not make calls
is the same. Foreign code that does make calls, and parts of the runtime
that make calls, do need to be protected against registers changing as if
by magic. If I recall correctly, the protocol is to save any transient registers
before the call or return (which copies them to the global variable or global
array slot reserved for them), and restore them after the call/return. Restore
is needed only before code that may use the relevant register. If Mercury
calls f which calls g, and only g uses a register, then g needs to restore it,
but f does not. If g can modify the register, then it needs to save it when it is
done, and the Mercury code calling f must restore it on return from f.

The relevant comment is this one in mercury_regs.h:

** The MR_save_transient_registers() and MR_restore_transient_registers()
** macros are similar to MR_save_mhal_registers() and
** MR_restore_mhal_registers() except that they only save/restore registers
** which can be affected by calling or returning from a C function (e.g.
** by sliding register windows on SPARCs).

Note that transient registers are a fruitful source of obscure and hard-to-
track-down bugs on SPARCs. Code that does not use them properly (or at
all) often works just fine on every ISA except SPARC, and there is no practical
way to track down or even detect such bugs without a SPARC machine.
Since SPARC is a dying architecture, it makes me wonder whether anyone
is still using Mercury on SPARC. If not, we should probably stop supporting it.


More information about the developers mailing list