libera/#sicl - IRC Chatlog
Search
3:06:43
beach
Yesterday, I spent the day improving SICL LOOP and making it conform to the standard. Apparently, MIT LOOP has several issues, including some non-conforming behavior.
3:08:19
beach
Today, I should get back to creating a memory imagine in the host, but first, I think I need to solve the issue with target packages. Currently, symbols are host symbols during bootstrapping and the DEFPACKAGE macro creates a host package only.
3:11:51
beach
For the memory image, I have a function named POINTER that takes a heap-allocated object and returns its pointer value as a fixnum. The native version of that function is just a left shift by one position.
3:13:34
beach
If the fixnum value is in the table it is returned. Otherwise, a native version of the object is allocated in the memory image, using the allocator for the global heap. Then tag bits are added, and the result is added to the hash table.
3:14:27
beach
But the components of the object must also be filled in. The "natural" way of doing that would be by calling POINTER recursively.
3:14:56
beach
However, as we know, then it is very likely that we will blow the call stack of the host.
3:17:02
beach
The only issue is that the "natural" implementation of POINTER is a generic function, so it doesn't lend itself to an iterative solution then, or at least I don't immediately see one.
3:17:43
beach
So I am trying to split it up into an iterative part that handles the worklist, and a generic part that does the allocation. But I may have to skip the generic function.
3:18:21
beach
It is not a big deal since the number of classes of heap-allocated objects is fairly limited.
3:18:45
hayley
I recall writing a generic function with a work list for an equality predicate, but it probably would not help in figuring how to implement POINTER.
3:20:22
beach
For the specialized arrays, the contents needs to be treated as raw data, aside from the prefix of the rack which contains a list of slots, the dimensions, etc.
3:20:57
hayley
(The technique I used was to have a generic function called EQUAL-STEP, which would either return T and an alist of objects to traverse, if the objects weren't shown to be not equal with this step, or NIL if they were shown to be not equal.)
3:21:04
beach
So it would have been convenient to use generic dispatch, and maybe it's still possible.
3:23:45
hayley
So far I seem to be stuck thinking that this is like semispace copying, though. POINTER would perform a shallow "copy", and then continue with a deep copy using a work list. Then COPY would be the generic function?
3:27:49
beach
So the worklist could be this alist, and the elements would then be pairs of (<address> . <ersatz-object>).
3:28:24
beach
To process an item in the worklist, check whether the ersatz object is in the hash table. If it is, just write its pointer into the address.
3:28:40
hayley
...nah, it's only doing traversal and mutation of a tree which might have "reference" objects. Though I have an alist of objects and functions to set the place from whence the object came, which is like an address.
3:29:25
beach
If the ersatz object is not in the table, then allocate it, using a generic function. That generic function then returns an alist of its slots to be filled in.
3:33:52
hayley
For reference, I have the graph traversal function at <https://gitlab.com/cal-coop/netfarm/netfarm/-/blob/master/Code/Objects/MOP/rewrite-references.lisp#L30-66>; though I suppose you likely wouldn't need it.
3:54:24
beach
The main issue I fixed was that the APPEND clause should not copy last list that is appended.
3:54:30
beach
It was interesting because the main difficulty was figuring out the trick to the solution, which was keeping the tail pointer pointing not to the last CONS cell in the accumulated list, but to the last CONS cell that should not be copied in case more cells get attached.
3:54:35
beach
When more cells get attached as a result of another APPEND, an NCONC, or a COLLECT, the tail pointer is moved and CONS cells are copied on the way.
3:54:37
beach
The other interesting part was that there was no problem whatsoever figuring out how to modify the code accordingly. The fix involved adding more code to macro expanders, so some abstractions had to be created. But otherwise, the organization of the LOOP code seemed sane.
3:59:13
moon-child
something I noticed while looking at that code is that lists that were APPENDed were traversed twice: once when initially copied, and once again when moving to the end. I would guess this change in approach also fixed that
7:26:25
moon-child
random thought: it would be nice a printer could produce forms like (#1=#:foo #1#)