process_info(P,current_function) and HiPE (was Re: Bugs with hibernate/3 and HiPE)

Mikael Pettersson mikpe@REDACTED
Wed Sep 29 13:43:09 CEST 2010


Paul Guyot writes:
 > Mikael,
 > 
 > Thank you for your e-mail.
 > 
 > > Please investigate:
 > > a) when and how BEAM updates current_function, and
 > 
 > c_p->current is either set to NULL or to a pointer to an {M,F,A} instruction triplet.
 > 
 > It is set:
 > - on context switch (which are always when entering a function)
 > - when calling a NIF
 > - on apply_bif
 > - on hibernate
 > - on various exception handlers and signaling.
 > 
 > > b) when you're allowed to call process_info(P, current_function) on
 > > a BEAM-mode function and what it returns; what if the target process
 > > is currently running? does it stop or does process_info then return
 > > stale data
 > 
 > I guess process_info returns stale data (simply the value of process->current).
 > 
 > > c) to what extent the hibernate test relies on the above
 > 
 > It is only used to figure out if the process is or is not hibernating. Indepently from the test, what I am mostly concerned with is that erts_hibernate sets current to {erlang,hibernate,3} and when the process wakes up, we should set it to a proper value (either the function being executed or NULL). If the wake up function is native, this does not happen and it remains {erlang,hibernate,3}.
 > 
 > The gen_server_SUITE:hibernate/1 test passes when simply setting c_p->current to I-3 in beam_emu.c's OpCase(hipe_trap_call), i.e. defining current to be the called native function. However, this looks weird because the data is definitely incorrect when the process is later switched out, waiting for a message. So I suggest to also clear current when exiting hipe_mode_switch in wait or suspend states. This is the content of the patch below. If you're fine with it, I'll submit it to erlang-patches@REDACTED
 > 
 > Paul
 > -- 
 > Semiocast                    http://semiocast.com/
 > +33.175000290 - 62 bis rue Gay-Lussac, 75005 Paris
 > 
 > diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
 > index 8a0e12d..ce49299 100644
 > --- a/erts/emulator/beam/beam_emu.c
 > +++ b/erts/emulator/beam/beam_emu.c
 > @@ -4850,6 +4850,7 @@ apply_bif_or_nif_epilogue:
 >           * ... remainder of original BEAM code
 >           */
 >          ASSERT(I[-5] == (Uint) OpCode(i_func_info_IaaI));
 > +        c_p->current = I-3;
 >          c_p->hipe.ncallee = (void(*)(void)) I[-4];
 >          cmd = HIPE_MODE_SWITCH_CMD_CALL | (I[-1] << 8);
 >          ++hipe_trap_count;
 > diff --git a/erts/emulator/hipe/hipe_mode_switch.c b/erts/emulator/hipe/hipe_mode_switch.c
 > index e5de244..181f9c8 100644
 > --- a/erts/emulator/hipe/hipe_mode_switch.c
 > +++ b/erts/emulator/hipe/hipe_mode_switch.c
 > @@ -425,6 +425,7 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
 >        case HIPE_MODE_SWITCH_RES_SUSPEND: {
 >           p->i = hipe_beam_pc_resume;
 >           p->arity = 0;
 > +         p->current = NULL;
 >           erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS);
 >           if (p->status != P_SUSPENDED)
 >               erts_add_to_runq(p);
 > @@ -445,6 +446,7 @@ Process *hipe_mode_switch(Process *p, unsigned cmd, Eterm reg[])
 >           p->i = hipe_beam_pc_resume;
 >           p->arity = 0;
 >           p->status = P_WAITING;
 > +         p->current = NULL;
 >           erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_MSG_RECEIVE);
 >        do_schedule:
 >           {
 > 

I don't like this, it's adding what I believe are redundant assignments
in hot paths.  The essential problem is that BEAM's hibernate test expects
->current to change soon after wakeup from hibernation.  There is no special
event for this, only a plain apply of an MFA.  In the bug case, that MFA
is native and nothing in that path sets ->current.

If you look at the start of hipe_mode_switch() you see an assignment of
NULL to p->i.  Just add "p->current = NULL;" at the same place, with a
comment that BEAM's hibernation test relies on it, and drop these other
3 assignments to ->current.  That should be enough.

/Mikael


More information about the erlang-bugs mailing list