freenode/#clasp - IRC Chatlog
Search
14:44:19
beach
I am redoing the bootstrapping procedure for the third (and last) time. It is now using much more production code and much less bootstrapping-specific code.
14:46:49
beach
Step 1. Create host classes in a first-class global environments that have SICL names like standard-class etc.
14:47:23
beach
Step 2. Instantiate those to create bridge objects, pretending that some of them are classes and some are generic functions.
14:47:53
beach
Step 3. Use bridge classes to create ersatz objects with the same shape as final SICL objects.
14:48:34
beach
Step 4. Load the rest of the system to create a graph isomorphic to the one in the SICL executable.
14:58:03
Colleen
Bike: drmeister said 17 hours, 23 minutes ago: - I think I can do anything I want in with the FuncallableInstance_O objects that describe single dispatch generic functions and we can fix them up later. I'll create a rack of whatever size I need and store whatever I need within it. I'll make the entry point a function that knows how to dispatch with whatever is in the rack. I'll keep a list of these single dispatch generic functions so we can fix
14:58:03
Colleen
Bike: drmeister said 7 hours, 1 minute ago: I eliminated a lot of the old single dispatch generic function machinery including the cache. No more ECL cache. My dispatch method is a little squirrely because I often only use DEFMETHOD for a base class and derived classes need to be recognized.
15:11:05
drmeister
Bike: I implemented that single-dispatch rewrite - it was mostly ripping out code.
15:14:46
Bike
i already have a bunch of non-gf funcallable instances used for clos in things. it's kinda neat
15:15:04
drmeister
I did do something that I wasn't really happy about - but the performance looks good. Can I run it past you?
15:15:57
drmeister
It's how I did the dispatch. Each single-dispatch generic function is implemented as a FuncallableInstance_O. I point to the single_dispatch_entry_point C++ function.
15:16:40
drmeister
In the rack I store a ComplexVector_T_O that has alternating class followed by a SingleDispatchMethod_sp pointer.
15:17:07
drmeister
Every DEFMETHOD adds a pair of entries to this table. The receiver class and a method.
15:17:50
drmeister
When you call one of these functions - it gets the class of the argument that it dispatches on (most cases the first argument - but in a few cases the second argument).
15:19:11
drmeister
Now - the problem: in the clasp code - there are lots of places where we declare a DEFMETHOD for a base class but not derived classes - but we expose the derived classes to Common Lisp.
15:20:06
drmeister
The single dispatch generic functions need to handle the derived classes. In C++ the methods are 'virtual' and they overload the base class method.
15:20:58
drmeister
I walk the class-precedence-list of the argument class and look each parent class up in the method table.
15:22:11
drmeister
Ultimately I want to expand the method table to include all valid derived classes (sort of satiate it) and then compile a discriminating function using our fastgf code.
15:25:21
drmeister
I thought I might run a pass over all of the single-dispatch generic functions and sort of satiate their method tables by adding all derived classes of whatever classes is in the method table. These are static C++ methods - they aren't as flexible as generic function methods.
15:26:36
Bike
i suppose dispatch overhead is probably pretty small compared to everything llvm is doing
15:29:13
drmeister
Yeah - when I profile it 1. Calls to single dispatch generic functions are a lot cleaner now. 2. There is no visible overhead.
15:29:47
drmeister
This allowed me to rip out the cache.cc contents and a lot of SingleDispatchXXX classes.
15:32:40
drmeister
I figure with the method table we can compile up a discriminating function and install it.
15:34:03
drmeister
I've stripped down SingleDispatchGenericFunction_O to a stub and I use that to define the _Class of the FuncallableInstance_O
15:35:22
drmeister
It is starting to dawn on me that I will have a bit of a problem with image save/load to link all these function pointers up.
15:36:51
drmeister
It's a linking problem to link C++ functions and methods in the executable to GC managed objects.
16:09:13
drmeister
I'll backup one commit on my machine, check the timing and if it doesn't look too bad I'll proceed.
16:28:23
drmeister
Bike: I read series of tweets that says that one big difference between X86-64 and ARM processors is the memory ordering in multithreaded situations.
16:29:26
drmeister
Apple solved the problem by adding X86-64 memory ordering to their ARM hardware so they could switch to X86-64 ordering when emulating X86-64.
16:29:30
Bike
yeah x86-64 is strongly ordered iirc, so loads are automatically acquire and stores are automatically release
16:43:02
drmeister
If I want to find all derived classes of a builtin class - I have to walk the list of all builtin classes and crawl through their class-precedence-lists - right?
16:43:55
drmeister
We don't store the relationship between classes and their derived classes any other way - that would be cumbersome because in general it's a bunch of trees.
16:54:24
drmeister
Not in this case - we stick with single inheritance because C++ multiple inheritance and garbage collection is a nightmare.
16:57:04
drmeister
I think it's why Java doesn't support multiple inheritance. I think you get two of the three: tracing garbage collection, performance, multiple-inheritance.
17:05:14
drmeister
With old single dispatch generic functions - 4m30s - I don't usually see such reproducible timing.
17:05:30
beach
I think Java doesn't support multiple inheritance because at the time, it seemed to require two-level dispatch tables like C++ has.
17:18:24
beach
I also wonder whether the vtables of C++ are required by the standard. I hear about them often, which makes me think they are required, but I can't see why that would be the case.
17:23:46
beach
Anyway, I am not sticking around for possible information. I am off to fix dinner for my (admittedly small) family.
17:43:48
Bike
beach: no, vtables aren't required, they're just the usual strategy for C++. i found a paper comparing them in java with something pretty close to your clos method https://www.usenix.org/legacy/event/jvm02/full_papers/zendra/zendra_html/index.html
18:09:23
karlosz
one of the extensions noted is how we can split out unwind into a local unwind followed by a simple-unwind out of the function
18:10:38
karlosz
also thinking of making a new instruction called simple-unwind and just making it a separate pass so we don't need to reanalyze the same unwinds again and again
18:11:16
karlosz
im not an expert on clos but doesn't the change-class strategy cause some problems if people wanna subclass their own unwind?
18:12:56
karlosz
it doesn't really, but it's also not a big deal to make it a post pass, since it can run as late as possible without problem
18:13:13
Bike
i had simplicity as a slot before, which would be fine with subclassing, but switching to doing it this way doesn't obviously slow things down
18:13:26
karlosz
the main thing is that now that i've extended it to look through local functions recursively, its no longer a simple lookup
18:14:07
karlosz
but if there were 1000 unwinds to the same tag you'd have an issue since it doesn't scale nicely anymore with the recursive look through
19:15:41
karlosz
../../src/core/funcallableInstance.cc:353 Adding method to single dispatch method for function EXTEND receiver-class #S(BUILT-IN-CLASS CONS )
19:22:06
drmeister
I did - sorry - I'll take it out in a little while. I accidentally, prematurely pushed some changes to the master branch.
19:23:58
drmeister
I discovered that I don't populate the class-direct-subclasses slot of builtin classes when clasp boots up. I'm fixing that now. Once I have those I'll be able to satiate single dispatch generic functions quickly.
19:25:09
karlosz
Bike: i just pushed the change to IFI which makes it a little more like how things are in AST
19:25:38
karlosz
basically now there are conditional-test instructions like eq-test which must have ifi as its use. that way the backend can handle them specially
19:26:51
drmeister
Is there an equivalent of HIR graphs for BIR? I haven't seen you guys post anything since BIR was developed.
19:28:17
Bike
which i honestly prefer because it's a faster turnaround than going through dot, but i could put together something with graphviz too
19:28:48
Bike
https://github.com/clasp-developers/clasp/blob/master/src/lisp/kernel/cleavir/translate.lisp#L1131-L1136
19:31:07
Bike
that part is pretty much the same as in hir actually, except that in bir it's blocks that have them, not instructions directly
19:31:24
karlosz
Bike: could be good. with graphviz i think we could just splay the text onto the basic block structure like the way llvm ir does
19:34:56
karlosz
Bike: now that i'm looking at the case of (lambda (x) (if (not x) 1 2)) specifically, is there a reason why we inline the NOT on the ast level, but not fully inline it?