Skip to content

Explore adding finalizer metadata without storing in the block #39

Description

@schveiguy

The existing D GC has 2 bits which define finalization -- a FINALIZE bit, and a STRUCT_FINAL bit. The first bit determines whether there is a finalizer or not. The second bit determines where the finalizer is located. With a struct, the finalizer is stored in a TypeInfo pointer inside the block (stored usually at the end of the block), and the finalizer is accessed from there.

With a class, the typeinfo already exists in the object because all classes have a typeinfo pointer (classinfo). So no extra pointer to the typeinfo is stored.

The new GC always stores a finalizer pointer in the block if there is a finalizer. This means that a class finalizer must store something. We currently store the pointer value 0x1 as the finalizer to indicate the finalizer really is in the class object itself.

However, a mechanism that exists in D cannot be supported because of this. Namely, if you initialize a monitor on the object instance, it will allocate a monitor object and set a pointer to it in the object instance. If the block is not yet set for finalization, it adds the FINALIZE bit to the block, thereby registering the block for finalization (to destroy the monitor) on destruction.

With the new GC, since we add the typeinfo pointer when finalizing, this means that if the block wasn't previously allocated with enough space to store the "fake pointer", then we can't add it later.

Options to make this work that I have thought of:

  • Just always allocate enough space so it can be added later. Requires 8 extra bytes per allocation.
  • Rework the metadata bits such that we can have a special case for a block with an internal finalizer without consuming more than 1 byte. This is very possible because of how we encode the length of the block. Requires 1 extra byte per allocation.
  • Somehow store the special case in the extent flags. Perhaps only for large enough blocks? Minimum class object size is 16 bytes. Requires no extra data in the block, but need to find another bit for each slot in the extent.

Maybe others? This issue is here to remind me of the thought process.

See related issue: schveiguy/sdc#1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions