Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the use of usrToCell in gcMark [backport:1.2] #17709

Merged
merged 2 commits into from
Apr 14, 2021

Conversation

zah
Copy link
Member

@zah zah commented Apr 13, 2021

Recently, we've discovered a GC crash resulting from inlining of
the memory allocation procs that allowed the compiler to avoid
maintaining any references to the "user pointer" on the stack.
Instead, a "cell pointer" appeared there and all field accesses
were performed with adjusted offsets. This interfered with the
ability of the GC to mark the correct cell in the conservative
stack scans which lead to premature collection of objects.

More details here:
status-im@af69b3c

This commit closes another theoretical loophole that may lead to
the same problem. If a short proc is accessing both the object and
its reference count in a short sequence of instructions, the compiler
may be enticed to reduce the number of registers being used by storing
only a single pointer to the object and using offsets when reading
and writing fields. A perfectly good strategy would be to store only
the cell pointer, so the reference count updates can be performed
without applying offsets. Accessing the fields of the object requires
offsets anyway, but these can be adjusted at compile-time without any
loss. Following this strategy will lead to the same problem of marking
a wrong cell during the conservative stack scan, leading to premature
collection.

The problem is avoided by not using usrToCell in gcMark. Since
the cell discovery logic can already handle interior pointers, the
user pointers don't need to be adjusted for the GC to function correctly.

zah and others added 2 commits April 13, 2021 11:11
Recently, we've discovered a GC crash resulting from inlining of
the memory allocation procs that allowed the compiler to avoid
maintaining any references to the "user pointer" on the stack.
Instead, a "cell pointer" appeared there and all field accesses
were performed with adjusted offsets. This interfered with the
ability of the GC to mark the correct cell in the conservative
stack scans which lead to premature collection of objects.

More details here:
status-im@af69b3c

This commit closes another theoretical loophole that may lead to
the same problem. If a short proc is accessing both the object and
its reference count in a short sequence of instructions, the compiler
may be enticed to reduce the number of registers being used by storing
only a single pointer to the object and using offsets when reading
and writing fields. A perfectly good strategy would be to store only
the cell pointer, so the reference count updates can be performed
without applying offsets. Accessing the fields of the object requires
offsets anyway, but these can be adjusted at compile-time without any
loss. Following this strategy will lead to the same problem of marking
a wrong cell during the conservative stack scan, leading to premature
collection.

The problem is avoided by not using `usrToCell` in `gcMark`. Since
the cell discovery logic can already handle interior pointers, the
user pointers don't need to be adjusted for the GC to function correctly.
@Araq Araq added the merge_when_passes_CI mergeable once green label Apr 14, 2021
@narimiran narimiran merged commit 3b47a68 into devel Apr 14, 2021
narimiran pushed a commit that referenced this pull request Apr 14, 2021
* Remove the use of usrToCell in gcMark [backport:1.2]

Recently, we've discovered a GC crash resulting from inlining of
the memory allocation procs that allowed the compiler to avoid
maintaining any references to the "user pointer" on the stack.
Instead, a "cell pointer" appeared there and all field accesses
were performed with adjusted offsets. This interfered with the
ability of the GC to mark the correct cell in the conservative
stack scans which lead to premature collection of objects.

More details here:
status-im@af69b3c

This commit closes another theoretical loophole that may lead to
the same problem. If a short proc is accessing both the object and
its reference count in a short sequence of instructions, the compiler
may be enticed to reduce the number of registers being used by storing
only a single pointer to the object and using offsets when reading
and writing fields. A perfectly good strategy would be to store only
the cell pointer, so the reference count updates can be performed
without applying offsets. Accessing the fields of the object requires
offsets anyway, but these can be adjusted at compile-time without any
loss. Following this strategy will lead to the same problem of marking
a wrong cell during the conservative stack scan, leading to premature
collection.

The problem is avoided by not using `usrToCell` in `gcMark`. Since
the cell discovery logic can already handle interior pointers, the
user pointers don't need to be adjusted for the GC to function correctly.

(cherry picked from commit 3b47a68)
narimiran pushed a commit that referenced this pull request Apr 14, 2021
* Remove the use of usrToCell in gcMark [backport:1.2]

Recently, we've discovered a GC crash resulting from inlining of
the memory allocation procs that allowed the compiler to avoid
maintaining any references to the "user pointer" on the stack.
Instead, a "cell pointer" appeared there and all field accesses
were performed with adjusted offsets. This interfered with the
ability of the GC to mark the correct cell in the conservative
stack scans which lead to premature collection of objects.

More details here:
status-im@af69b3c

This commit closes another theoretical loophole that may lead to
the same problem. If a short proc is accessing both the object and
its reference count in a short sequence of instructions, the compiler
may be enticed to reduce the number of registers being used by storing
only a single pointer to the object and using offsets when reading
and writing fields. A perfectly good strategy would be to store only
the cell pointer, so the reference count updates can be performed
without applying offsets. Accessing the fields of the object requires
offsets anyway, but these can be adjusted at compile-time without any
loss. Following this strategy will lead to the same problem of marking
a wrong cell during the conservative stack scan, leading to premature
collection.

The problem is avoided by not using `usrToCell` in `gcMark`. Since
the cell discovery logic can already handle interior pointers, the
user pointers don't need to be adjusted for the GC to function correctly.

(cherry picked from commit 3b47a68)
@narimiran narimiran deleted the no-usrToCell-in-gcMark branch April 14, 2021 10:10
sthagen added a commit to sthagen/nim-lang-Nim that referenced this pull request Apr 14, 2021
Remove the use of usrToCell in gcMark [backport:1.2] (nim-lang#17709)
PMunch pushed a commit to PMunch/Nim that referenced this pull request Mar 28, 2022
* Remove the use of usrToCell in gcMark [backport:1.2]

Recently, we've discovered a GC crash resulting from inlining of
the memory allocation procs that allowed the compiler to avoid
maintaining any references to the "user pointer" on the stack.
Instead, a "cell pointer" appeared there and all field accesses
were performed with adjusted offsets. This interfered with the
ability of the GC to mark the correct cell in the conservative
stack scans which lead to premature collection of objects.

More details here:
status-im@af69b3c

This commit closes another theoretical loophole that may lead to
the same problem. If a short proc is accessing both the object and
its reference count in a short sequence of instructions, the compiler
may be enticed to reduce the number of registers being used by storing
only a single pointer to the object and using offsets when reading
and writing fields. A perfectly good strategy would be to store only
the cell pointer, so the reference count updates can be performed
without applying offsets. Accessing the fields of the object requires
offsets anyway, but these can be adjusted at compile-time without any
loss. Following this strategy will lead to the same problem of marking
a wrong cell during the conservative stack scan, leading to premature
collection.

The problem is avoided by not using `usrToCell` in `gcMark`. Since
the cell discovery logic can already handle interior pointers, the
user pointers don't need to be adjusted for the GC to function correctly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merge_when_passes_CI mergeable once green
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants