freenode/#sicl - IRC Chatlog
Search
14:01:17
beach
OK, let's say we have two types of calls to functions. 1. A GENERAL call which is a call to a function being the value of some arbitrary form, and 2. A SIMPLE call which is a call to a global, named function with a fixed argument list.
14:01:28
beach
A general call always calls THE entry point in the function object. A simple call is subject to call-site optimization according to the draft paper. The function object has two slots, in addition to THE entry point, containing a FAST entry point and a DEBUGGING entry point.
14:01:41
beach
One of those two is always the value of THE entry point, normally the fast one. Snippets are not restricted to the entry point of a function and can call any point in the callee.
14:01:53
beach
Also, let's say the reified thread is passed as an implicit argument, probably in a register. The thread contains a slot containing a DEBUGGER thread if the thread is being debugged or NIL otherwise. The debugging entry point of a function checks the reified thread and if it is NIL, the fast version of the function is jumped to. Otherwise the debugging version is used.
14:02:03
beach
When a breakpoint is set in a function, these things happen. 1. The debugging entry point is copied to THE entry point so that general calls get the debugging version of the function. 2. Snippets are recreated so that they check the reified thread before calling some point either in the fast version of the function or in the debugging version.
14:02:05
beach
So the penalty for a thread not being debugged is a test of a slot in the reified thread but only for functions with at least one breakpoint in it.
14:06:50
beach
If I write a followup paper to the debugging paper, I probably won't talk about the snippets, because that's not the important part here. The important part is that we can dynamically change which entry point of a function is being called when a breakpoint is set or removed in it.
14:07:15
heisig
Sounds good. Having the reified thread in some register is probably a good idea anyway. The only thing I haven't understood is the value of the DEBUGGER thread.
14:07:28
beach
The more important idea is the thing of changing the return addresses. That, too, can be mentioned without discussing snippets.
14:07:55
heisig
Is DEBUGGER the thread doing the debugging? If so, does that mean that SICL will always have exactly one debugger thread?
14:08:07
beach
OK, so the debugging paper says that breakpoints are handled by the debugged thread communicating with the debugger thread.
14:10:56
beach
But breakpoints communicate with the debugger thread as indicated by the slot in the reified debugged thread.
14:11:17
heisig
So it would not be possible to have multiple developers debug the same code, say, in a system running in production.
14:13:06
heisig
I see. Every thread has zero or one debugger threads attached. Thanks for clarifying this.
14:18:00
beach
Before and after each form evaluation, the debugged thread queries the debugger thread to see whether there is a breakpoint there.
14:19:07
heisig
Which is a good thing, I would say. It would be weird to have the state of the debugger creep into the code being debugged.
14:19:09
beach
Which is good, because otherwise, code being debugged by two different people would see breakpoints set by the other.
14:21:01
beach
So the logic that chooses the entry point and creates the snippets must react to orders from the debugger(s).
14:21:23
beach
If at least one debugger thread has a breakpoint in some function, that logic must do what I said before.
14:25:11
heisig
I should use this moment of clarity to set up my JIT compiler infrastructure in SBCL.
14:25:54
beach
And if I omit the snippet discussion from the debugging paper, then all return addresses on the stack are into callers, so they can just be altered to go to the debugged "continuation".
15:19:25
Bike
no ansi-test failures for ctype subtypep now, hooray. this is definitely not the prettiest code i've ever written, though https://github.com/Bike/ctype/blob/main/disjunction.lisp#L15-L53
15:27:34
Bike
in this case it's mostly just weird algebra. subctypep and disjointp are pretty easy to understand (i hope), they determine subtypep and disjointness relationships, and return T T, NIL T, or NIL NIL like subtypep does
15:28:23
Bike
anyway, at this point i think it's not returning any incorrect results, and returning enough correct results to satisfy the standard
15:51:59
beach
How do I use your SUBTYPEP to implement ARRAY-UPGRADED-ELEMENT-TYPE if your code requires an existing version of the latter?
16:01:18
Bike
you can just define u-a-e-t like (defun upgraded-array-element-type (ts &optional env) (cond ((subtypep ts 'bit env) 'bit) ((subtypep ts 'base-char env) 'base-char) ... (t 't))), right? the subtypep calls won't need upgraded-array-element-type unless the element type is itself an array type, and even then it will eventually terminate
16:26:35
beach
How often is UPGRADED-ARRAY-ELEMENT-TYPE called with something other than the precise type in a very simple form?
16:28:33
beach
More questions: Do you intend to use this new SUBTYPEP for type inference in Cleavir?
16:29:22
Bike
that was the original idea. i mean, i don't intend to incorporate it into cleavir, but cleavir has hooks so it can use pre-parsed types like this if the client type system works that way