Encoding polymorphic values (sum types) in the heap can be trivially done by a type code/index (or simply tag) in the value's header.
For large per-tag pools of monotypal objects, the pool range itself can serve as identifying the type. A pointer into the pool can be checked against all known pool extents to extract the tag. Unfortunately this makes memory relocation difficult, and prohibits the use of multiple pools for the same tag.
A better approach when the heap supports baseable pointers (such as arcmem), is to store the tag of a pool at its beginning; a pointer into the pool can then be based to the pool header, amortizing the cost of a type tag.
All three mentioned approaches suffer from the issue however that casts are expensive as we need to copy values just to change their type, even though the actual attributes of the value did not change.
For the case where the number of types for a sum type S is smaller than the alignment of S, which is invariant, the type index (or tag) can instead be stored