On Thu, Feb 26, 2015 at 9:37 AM, Jonathan S. Shapiro <[email protected]> wrote: > In Coyotos, there are several kinds of objects at the API level. All are > named by capabilities and have OIDs. It is intentionally unspecified whether > the OID space is partitioned by type. In some versions of the kernel objects > have been tracked in a unified hash table. > > In C, the idiom for this is to have an ObjectHeader struct as the first > element of (e.g.) the Process struct, and do ad-hoc downcasting. That idiom > cannot be done in a safe language.
Sure you can. You just need to prove some way or another that the object in question was really initialized as the more specific structure. This can be done with dependent types, a true proof system, or some special-purpose fragment of dependent types. (Which may have already been written about, or I could try to [re]discover.) > In C++, the idiom would be to have Process derive from ObjectHeader, and > perhaps use RTTI to do a checked downcast. That idiom *can* be done in a > safe language. By the above, there doesn't need to be a one-size-fits-all representation of dynamic type. But the complexity of safely allowing custom RTTI might not be worth it to you. I'm not saying it would have to be full-blown, get-a-PhD dependent type theory, but it would probably be more complex than a baked-in RTTI protocol. > In BitC v0, neither idiom is possible, because one structure definition > cannot extend another. > > It turns out that this "checked downcast" approach is being used pervasively > in Coyotos, because the object identity between the ObjectHeader and its > associated (e.g.) Process is actually important. It simply would not work to > separate the two parts into structures that are mutually cross-pointed. If > nothing else, the additional storage used for those pointers would exhaust > the available kernel *virtual* memory range. Yes, kernels really *are* that > tight, and no, 64-bit address spaces *don't* help. > > The ObjectHeader contains a type code for the object, and there are a very > few procedures associated with these objects that dispatch on the type code, > but no virtual overrides occur in this scenario. > > I really do not see a solution to this **other than** allowing one struct to > extend another and introducing the capacity for dynamic downcast. The kind of option I'm pointing out is essentially that, but the RTTI format and downcast operation are defined within the language, rather than being baked into the language, as in OO languages. > The > problem here combines "is a kind of" with "is identically a", and it is > driven by data layout concerns rather than any need for existential > encapsulation. > > ILLUSTRATION 2 > > This is an essentially similar problem, though with heavier use of dispatch > on that type code. With a user-defined RTTI protocol, dynamic dispatch would of course be user-implemented as well. > There are a few objects in Coyotos that can cause hardware mapping entries > to be produced. How dependencies and information necessary for invalidation > are tracked depends on the object type. We end up with a structural > hierarchy that looks like: > > Link -- double link pointers > Ageable -- adds pointer to per-type agelist head > ObjectHeader -- object type code, locks, various common metadata > MemHeader -- used to track HW maps derived from this object > GPT -- state of Guarded Page Table > Page -- phys addr and size > > Here again both layout and final size of the object are tightly constrained. > It truly is an "extends" relationship, but the need for dynamic downcast > makes it a bit interesting. > > It's the dynamic downcast that has me thinking in terms of inheritance here. > Structure extension per se isn't difficult, though even that introduces a > nominal subtyping relation. > > shap _______________________________________________ bitc-dev mailing list [email protected] http://www.coyotos.org/mailman/listinfo/bitc-dev
