This commit is to attempt fixing this error:
http://ci.rvm.jp/results/trunk-gc-asserts@ruby-sky1/2353281
Each non-full heap_page struct contains a reference to the next page
that contains free slots. Compaction could fill any page, including
pages that happen to be linked to as "pages which contain free slots".
To fix this, we'll iterate each page, and rebuild the "free page list"
depending on the number of actual free slots on that page. If there are
no free slots on the page, we'll set the free_next pointer to NULL.
Finally we'll pop one page off the "free page list" and set it as the
"using page" for the next allocation.
```
irb(main):001:0> RUBY_VERSION
=> "2.6.5"
irb(main):002:0> S = Struct.new(:foo, keyword_init: true)
=> S(keyword_init: true)
irb(main):003:0> S.new({foo: 23424}, 234) # I don't think this is intentional
=> #<struct S foo=23424>
irb(main):004:0>
```
Tightening this up should inform users when they are confused about
whether a struct is `keyword_init`.
This update does not add any new codepoint assignments, it just
expands the range of emoji codepoint sequences recommended for
public interchange.
Depending on how emoji data files are cached, this commit may
require manual intervention in some build environments
(including some CI systems).
When we compact the heap, various st tables are updated, particularly
the table that contains the object id map. Updating an st table can
cause a GC to occur, and we need to prevent any GC from happening while
moving or updating references.
Since the current working directory is not involved in `Tempfile`
and `Dir.mktmpdir` (except for the last resort), it is incorrect
to derive the traversal path from it. Also, since the rubyspec
temporary directory is created under the build directory, this is
not involved in the target method. Fixed sporadic errors in
test-spec.
Some test cases in rubygems assume that /tmp/Gemfile does not exist.
If it does, they fail with very difficult-to-understand message:
```
[ 149/2108] TestGemBundlerVersionFinder#test_bundler_version_with_bundle_update_bundler = 0.00
1) Failure:
TestGemBundlerVersionFinder#test_bundler_version_with_bundle_update_bundler [/home/mame/work/ruby/test/rubygems/test_gem_bundler_version_finder.rb:38]:
Expected Gem::Version.new("2.0.2") to be nil.
```
I spent one hour to debug this issue. To prevent the same accident,
this change makes the test suite stop when /tmp/Gemfile explicitly.
Previously this was restricted to only gcc because of the
GCC_VERSION_SINCE check (which explicitly excludes clang).
GCC 3.3.0 is quite old so I feel relatively safe assuming that all
reasonable versions of clang support this.
This reverts commit 60a7f9f446.
We can't have Ruby objects pointing at T_ZOMBIE objects otherwise we get
an error in the GC. We need to find a different way to update
references.
When we run finalizers we have to copy all of the finalizers to a new
data structure because a finalizer could add another finalizer and we
need to keep draining the "real" finalizer table until it's empty.
We don't want Ruby programs to mutate the finalizers that we're
iterating over as well.
Before this commit we would copy the finalizers in to a linked list.
The problem with this approach is that if compaction happens, the linked
list will need to be updated. But the GC doesn't know about the
existence of the linked list, so it could not update references. This
commit changes the linked list to be a Ruby array so that when
compaction happens, the arrays will automatically be updated and all
references remain valid.
We need to ensure that labels are pinned while disassembling. If the
compactor runs during disassembly, references to these labels could go
bad, so this commit just ensures that the labels can't move until we're
done.
Fiber#transfer prevents calling Fiber#resume on the receiver of the
transfer method, not the fiber calling transfer.
Transfering back to a fiber does not allow later calling resume on
the fiber. Once transfer has been called on a fiber, you can never
call resume on the fiber.
Calling resume on a transferred fiber is not a double resume error,
it is a different FiberError (cannot resume transferred Fiber).
For details on the differences between transferred fibers and
regular fibers, see Sasada-san's RubyKaigi 2017 presentation (in
short, Fiber#transfer is for coroutine, Fiber#resume is for
semi-coroutine).