So now, I could use the new model.. :)

I have changed the way children and parent relations are managed, by making
a separate childmap table in a bsym_table.

This allows unordered additions to the table: the childmap is updated when you 
add
a child, whether or not the parent exists in the table.

Unfortunately, now we have a "Not_found" exception.

Removed 1 variables in 2 passes
REMOVED CHILD SYMBOL index_310
REMOVED CHILD SYMBOL index_311
HIB:Examining function join_mf_300<300> for inlinable calls
Gen body caller = 300, callee=join_mc302<306>
Lazy INLINING join_mc302<306>(()) into 300 .. INPUT:
return (match case 1)(join_mv_300<301>);
Inline tail apply : return (join_mh302<305> ());
Gen body caller = 300, callee=join_mh302<305>
Lazy INLINING join_mh302<305>(()) into 300 .. INPUT:
return b<3792>;
Inline tail apply : return (join_mh304<308> ());
Fatal error: exception Not_found
// Include directories = build/release/lib build/release/src/flx_pkgconfig
//BINDING
//BINDING OK time 0.137329
//BINDING
//BINDING OK time 0.302422
//OPTIMIZING


Yeah, it's occuring AFTER the //OPTIMISING which is out of sync due to a 
buffering
problem previously mentioned ;(

The question is: what invariants apply to the table?

In the old days, there was no entry for a module in the table:
modules were only for lookup. However now they exist,
whereas type variables used to have a table entry and now don't.

So there's an expectation that at certain points in time a table is closed
under usage, meaning all things used by something in the table
imply that thing is also in the table. The invariant can be broken transiently,
indeed it has to be when complex optimisations apply.

So the problem is now I don't know what is causing the problem:
it doesn't seem right that "full_use_closure" which is used for garbage
collecting the table doesn't actually include the parent relationship:
however module parents don't actually get used by anything (if they
have a use, it is only to get the qualified name of the symbol for
debugging purposes).

However it is not all that clear. Modules can be nested in functions!
The parenting chain has to be handled specially. When closures
are calculate the "display" is a list of stack frames of enclosing
functions, but this is not the same as the list of parents: the
modular parents would have to be removed.

This wasn't necessary before, since there were no modular parents :(

It gets REALLY hairy when dealing with type-classes.

I have no idea what is causing the problem above. Some code
is probably assuming if X is in the table, its parent is too.

Note that the optimiser is *extremely* sensitive to all this stuff.
Just consider the "cloning/reparenting" operation which is done
when a function is inlined into another: all the children get inlined too,
with specialisations (both type and value parameter-> argument
substitutions get applied).

There are rules about what you can inline: the function has to be
visible. The normal rule is that inside a function f, you can see f,
its ascendants (parents, recursively), and all f's children (our
siblings).

The rule for binding is as above *including modules* in the formula,
but allowing "open" to change the relationships as well as allowing
explicit qualification.

But after binding the rule is different: it excludes modules.
If modules are accidentally taken into account all hell will break lose.

So now .. I don't know what to do. I also changed things around to support
the pre-binding of libraries, so now many things have a 0 (root) parent.
I find this with some debugging:

Used symbols parent not marked as used: symbol: 4032, parent=3973
Used symbols parent not marked as used: symbol: 4038, parent=3973
Used symbols parent not marked as used: symbol: 4130, parent=3973
Used symbols parent not marked as used: symbol: 4354, parent=3973
Used symbols parent not marked as used: symbol: 4361, parent=3973
Used symbols parent not marked as used: symbol: 4372, parent=3973
Used symbols parent not marked as used: symbol: 4375, parent=3973
Used symbols parent not marked as used: symbol: 4378, parent=3973
Used symbols parent not marked as used: symbol: 4421, parent=3973
Used symbols parent not marked as used: symbol: 4427, parent=3973
Used symbols parent not marked as used: symbol: 4435, parent=3973
Used symbols parent not marked as used: symbol: 4436, parent=0
Used symbols parent not marked as used: symbol: 4441, parent=0
Used symbols parent not marked as used: symbol: 4447, parent=0
Used symbols parent not marked as used: symbol: 4453, parent=0
Used symbols parent not marked as used: symbol: 4479, parent=4460
Used symbols parent not marked as used: symbol: 4721, parent=4480
Used symbols parent not marked as used: symbol: 4728, parent=4480
Used symbols parent not marked as used: symbol: 4775, parent=4480
Used symbols parent not marked as used: symbol: 4923, parent=4480
Used symbols parent not marked as used: symbol: 5022, parent=4940
Used symbols parent not marked as used: symbol: 5024, parent=5023
Used symbols parent not marked as used: symbol: 5041, parent=5023
Used symbols parent not marked as used: symbol: 5055, parent=5023
Used symbols parent not marked as used: symbol: 5219, parent=5023
Used symbols parent not marked as used: symbol: 5232, parent=5023
Used symbols parent not marked as used: symbol: 5234, parent=5233


This means the table isn't closed under "usage including parentage".

The modular parents are essential for emitting original names,
in the old days the unbound symbol table was used to find this.
DIdn't work so well when new functions got sythesised though ;(

In the new scenario, we have to include the module for closure,
but then the parent/child relation is not the same as the 
true_parent/child relation (excludes modules), and it is dang difficult
to see how to make cloning/reparenting work and keep all the links
correct and maintain BOTH relations. For example:

   fun f() { module A { fun g(){} } fun k()(); A::g(); k(); }}

Really, g and k are siblings. The both get a f's display PLUS
the "this" pointer of f passed to them. When they're inlined,
*their children* (not shown in example) have to be reparented
to f. The point is the module A is irrelevant.

So actually g has two parents, f and A: f is the true parent,
A is just for debugging. So when g's kids are reparented by inlining they
should become children of f.

The problem here is: if we do NOT copy modular parents when we're garbage
collecting the symbol table based on usage, we have dangling parent pointers.
If we DO copy them, we need two distinct ways to calculate all parent/child 
relations
and we have to use the right one everywhere ;(

If we do NOT copy modular parents, we could adjust the parent pointers to the
true parent to get closure. It will mess up printing qualified names but 
simplify the
table. The thing is .. if we're going to do this the very first time we garbage 
collect
the table it would be better if we just didn't put any modules in the table in 
the
first place. 

Don't even think about asking how type-classes should work .. :)

bottom line: I have no idea what's causing the bug, but I also have no idea
what invariants really have to be preserved so it makes looking for the bug
irrelevant: got to have design invariants before you can look for places the
invariants are broken.



--
john skaller
skal...@users.sourceforge.net





------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to