-
Notifications
You must be signed in to change notification settings - Fork 69
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
Pass ObjectReference
to the is_movable
API
#1172
Open
k-sareen
wants to merge
1
commit into
mmtk:master
Choose a base branch
from
k-sareen:fix/is-object-movable
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I agree that the trait method
SFT::is_movable
should haveobject
as a one parameter (because a space can, in theory, refuse to move some objects but not others), I don't think object pinning should be involved here.The main use of
ObjectReference::is_movable
is foreign function interface (FFI) where the VM passes an object reference (or interior pointer) to native code. Ifis_movable
returns true, the VM will omit the pinning and unpinning operation around the native call (or the action of telling mmtk-core the object is an unmovable root when GC happens while the native function is being executed).But if
is_movable
answerstrue
because the pinning bit is set, the following thing may happen. Assume there are two mutator threads.(Update: I got the return values wrong. Now corrected.)
obj.is_movable
and getsfalse
true
(it is movable). Then the first mutator pins the object and then calls the native function.obj.is_movable
and getstrue
false
(it is not movable) because the first mutator pinned that object. It omits the pinning operation and calls the native function directly.The documentation of
ObjectReference::is_movable
simply says "Can the object be moved?" It is not very clear about how long the answer remain valid. Intuitively, ifObjectReference::is_movable
returnstrue
, it should mean "the object will never ever move until it is dead". But if the object cannot move because the pinning bit is set, it can once again become movable after we remove the pinning bit. This may cause some subtle confusion. We need to fix the documentation so that the VM binding developers know what to expect.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you have the return values swapped in your example. If the object is pinned then
is_movable
returnsfalse
.I agree that this is a valid use-case, but the documentation of
is_movable
in the SFT mentions object pinning. It is not the only use-case ofis_movable
, however. ART uses it when cloning objects, for example, to allocate the object with the correct semantics/allocator. I've just removed the non-moving allocator and replaced it with pin bits, and I tripped on this bug.I'm not sure what the best way to approach this is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, your example is true for the current state of affairs anyway. As in, if two threads pin the same object, then one thread may unpin it while the other thread is still using it. So this PR doesn't make the situation worse. I'm not sure if that is something we can resolve anyway as we would effectively need to implement a counter for the pinning metadata instead of a single bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The scenario Kunshan describes is an issue with our pinning semantic (which uses a boolean rather than a count). If you replace the call to
object.is_movable
withmemory_manager::is_pinned
in the scenario, you would get the same problem.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wks What are your thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the pinning counter and the semantics of
is_movable
are orthogonal.If we implement a per-object pinning counter and apply
pin_object
andunpin_object
unconditionally when calling native, there will be no problem.But if we use pinning counter, and also use
is_movable
to detect if an object is movable and elide the pin/unpin operation depending on the return value ofis_movable
, there will still be a problem. The scenario I described will still go wrong if the first mutator applies a pinning counter, and the second mutator elides the pinning/unpinning because it is "unmovable".The crux is still the semantics. I insist that
object.is_movable
returningfalse
should mean it can't be moved until it dies.But if you need to clone object and also clone some special semantics (e.g. whether it can be moved), we have to find other metadata to use.
Ruby also has a
dup
function that clones an object. It also copies the "write-barrier-unprotected" (WB-unprotected) property and its finalizers. CRuby uses a bitmap to identify if an object is "WB-unprotected", and uses an in-header bit for whether it is finalizable. Currently I just implemented the query of whether an object is "WB-unprotected" using a table lookup, which is as efficient as CRuby.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BTW, if you are sure there is no race, you can use
memory_manager::is_pinned
to query the pinning bit and then pin the copied object, too, if that's desired.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. I don't think this will get resolved over GitHub comments. It doesn't matter in my case since I never unpin objects (until they die), so I'll just keep this in my branch.