So it might be helpful to this discussion to talk about a use case.
Ironically, the cases that are presently very important to me do not
involve existential encapsulation at all, and do not need to involve a
vTable, because no method override occurs.

ILLUSTRATION 1

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.

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.

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
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.

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

Reply via email to