Skip to content

Improper but "silently succeeding" use of post write barrier #1129

@wks

Description

@wks

This is a sub-problem of #1038 which we decided to postpone after the MEP for removing ObjectReference::NULL (#1043).

MMTk's write barrier functions take target: ObjectReference as parameter. For example,

pub fn object_reference_write_pre<VM: VMBinding>(
    mutator: &mut Mutator<VM>,
    src: ObjectReference,
    slot: VM::VMEdge,
    target: ObjectReference,
) {
    mutator
        .barrier()
        .object_reference_write_pre(src, slot, target);
}

With #1043 merged, this form no longer works if target is NULL or any other non-reference values. But real-world programs may overwrite a field previously holding an object reference with NULL or a non-reference value.

However, all bindings are still working. That's because they transmute 0 to ObjectReference in C/C++ and pass them to Rust. Currently, the object-remembering write barrier simply ignores the slot and the target fields, so it is unaware that the ObjectReference variable is holding an illegal value. But we have to acknowledge that it is a bug and should be fixed.

We can simply change target to Option<ObjectReference>, with None representing a deleted edge.

However, object_reference_write will no longer work if target is None because MMTk core cannot write NULL or non-reference values to the slot.

pub fn object_reference_write<VM: VMBinding>(
    mutator: &mut Mutator<VM>,
    src: ObjectReference,
    slot: VM::VMEdge, // Edge::store(&self, target: ObjectReference) does not accept null target, which is intentional.
    target: ObjectReference,
);

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