Sean O'Rourke wrote:
> 
> On Thu, 17 Jul 2003, Leopold Toetsch wrote:
> >   PC = ((op_func_t*) (*PC)) (PC, INTERP); // prederef functions
> >
> > To be able to switch function tables, this then should become:
> >
> >   PC = ((op_func_t*) (func_table + *PC)) (PC, INTERP);
> >
> > Thus predereferncing the function pointer would place an offset into
> > the function table, not an absolute address.
> >
> > Or is there a better way to do it?
> 
> Replacing the next instruction with a branch to the signal handler
> (like adding a breakpoint) out of the question?

Not "the next instruction" ... the next *branch* instruction.  And only
replace those branch instructions which could be loops.

> Of course, if we're sharing bytecode this is expensive, since you'd
> have to do something like this:
> 
>         bsr handler
>         ...
> handler:
>         if cur_thread == thread_with_signal goto real_handler
>         # replaced instruction
>         ret
> 
> which penalizes all other bytecode users.  I guess it depends how
> common we expect signal handling to be.

Actually, I'm thinking of something like the following... suppose the
original code is like:

   label_foo:
   loop body
   branch_address:
   branch label_foo

Add in the following:

   e_handler_foo:
   .local PerlHash handlers_with_events
   .local int i_have_an_event
   handlers_with_events = ....
   i_have_an_event = handlers_with_events[cur_thread]
   unless i_have_an_event, label_foo
   bsr dequeue_events_and_handle_them_all
   branch label_foo

And then, when an event occurs, replace "branch label_foo" with "branch
e_handler_foo".

When there are no events queued, for any thread, then we change "branch
e_handler_foo" back into "branch label_foo", for speed.

And we might even be able to do this with JIT!  At least, we can if we
can keep track of the addresses of all the "branch label_foo"s (so we
know what to replace), and if we can replace bits of code while the code
is running.

-- 
$a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
);{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "[EMAIL PROTECTED]
]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}

Reply via email to