Skip to content

improve safety of ForkJoin.alloc with compiler-generated default values #231

@shwestrick

Description

@shwestrick

Introduced in 456c9c2, the function ForkJoin.alloc: int -> 'a array performs GC-safe parallel initialization of a polymorphic array. The implementation relies on monomorphization as well as an "uninitialization" primitive introduced in 946385f, called _prim "Array_uninit".

This "uninitialization" primitive sets an array cell to a GC-safe bogus value. Roughly speaking, the idea is to set every pointer-valued field to a "null" value, which in MLton takes the form of a bogus objptr. The GC checks for (and never traces) bogus objptrs, so we get GC-safety.

However, at the source level, ForkJoin.alloc is somewhat unsafe. If an uninitialized array contains pointer data, then reading from the array can return a bogus objptr, which could crash the program.

This is not a problem specific to MLton or MaPLe. Any "safe" language runs into a similar issue, and there are well-known solutions. For example, Go has zero values, where every type has a well-defined default value. This is very similar to what MaPLe is currently doing, but one difference is that Go has a source-level notion of nil pointers, which raises the unsafety issue to the source level. In other words, Go forces the programmer to think about nil pointers, which weakens the safety guarantees of the language and simplifies the implementation of the compiler and run-time system. MaPLe has no source-level notion of pointers, and would benefit greatly from a better solution.

I feel like a very reasonable (and perhaps not too difficult to implement) solution would just be to generate a default value for every type at which an "array uninitialization" occurs. This way, rather than setting pointer data to a bogus value, we could set it to a pre-determined global default. This would ensure that ForkJoin.alloc is always type-safe at the source level.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions