Update to MMTk core PR #1457 - #160
Conversation
|
The segfault is from the following call stack But a bigger problem is that the thread is doing GC, and is trying to disable collection while in a GC -- mmtk/mmtk-core#1457 forbits that. |
|
Here is what happened. In CRuby, In the failed test, the error happens during a copying GC when using MMTk. It was iterating over a global hash table (allocated by xmalloc, not in GC heap) and updating the keys and values. Because the keys are object references, and CRuby is not using address-based hashing, if a key is moved, it needs to be removed from the hash table and inserted again. By inserting into the hash table it may result in rehashing, and calling We know that
It worked in CRuby's default GC because disabling GC simply sets a flag. While using MMTk, we implemented This should be straightforward to fix.
|
|
Thanks for the explanation. I thought |
|
I made a few changes. It now calls
I also disabled two test cases about
So I don't think it makes sense to mimic the behavior of CRuby's default GC. Instead, CRuby's default GC should be fixed. |
|
There are many test cases that depend on CRuby's existing non-nest-counted behavior. There are utilities like def without_gc
prev_disabled = GC.disable
yield
ensure
GC.enable unless prev_disabled
endIt is used like this: def test_match_no_match_no_matchdata
EnvUtil.without_gc do
h = {}
ObjectSpace.count_objects(h)
prev_matches = h[:T_MATCH] || 0
_md = /[A-Z]/.match('1') # no match
ObjectSpace.count_objects(h)
new_matches = h[:T_MATCH] || 0
assert_equal prev_matches, new_matches, "Bug [#20104]"
end
endAnd there is This means if we change the behavior of But implementing CRuby's old non-nesting behavior is also difficult. If one thread triggered the GC and multiple threads want to disable GC, then all of them need to block for GC. But if the GC-enabled state is non-nesting, only one thread can change the GC-enabled state, and this means it needs to be protected by a mutex. We can't just let CRuby threads block on a Mutex instead of a safepoint. |
|
Would it be helpful if we allow a build-time flag (or a runtime flag) to make the nesting depth to be at most 1? What else do we need to support Ruby disable semantics? |
Yes. I think it will make things easier if mmtk-core can provide the following two functions:
The two functions will increase or decrease the disabled depth by Actually, providing either one of them is sufficient to support the use case of CRuby, but for consistency, I think it is helpful to provide them both. Another reason for introducing the |
|
The test case I'll rerun the test. |
The MMTk core reintroduced the `disable_collection` and `enable_collection`. They are implemented in MMTk core and has a built-in depth counter which requires invocations of `enable_collection` to be paired with the same number of `disable_collection` invocations. On the Ruby side, we implemented CRuby-style `GC.disable` and `GC.enable` methods without depth counting on top of MMTk's new API, ensuring existing test cases pass. `GC.start` will not trigger GC when GC is disabled, making it behave differently from CRuby's default GC. Some related test cases are excluded when using MMTk. Related PRs: - mmtk/mmtk-core#1457 - mmtk/mmtk-ruby#160
The MMTk core reintroduced the `disable_collection` and `enable_collection`. They are implemented in MMTk core and has a built-in depth counter which requires invocations of `enable_collection` to be paired with the same number of `disable_collection` invocations. On the Rust side, we updated the API wrappers, removed code related to the old API and updated the `mmtk-core` and `ruby` repo dependencies. Related PRs: - mmtk/mmtk-core#1457 - mmtk/ruby#98
No description provided.