-
-
Save havenwood/45f401f9015e07aaa7aa to your computer and use it in GitHub Desktop.
Edited
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
= Appendix D. Generational GC | |
Ruby 2.1 introduced a generational garbage collector (called RGenGC). | |
RGenGC (mostly) keeps compatibility. | |
Generally, the use of the technique called write barriers is required in extension | |
libraries for generational GC. RGenGC works fine without write barriers | |
in extension libraries. | |
If your library adheres to the following tips, performance can | |
be further improved. Especially, the "Don't touch pointers directly" section is | |
important. | |
== Incompatibility | |
You can't write RBASIC(obj)->klass field directly because it is const | |
value now. | |
Basically you should not write this field because MRI expects it to be an | |
immutable field, but if you want to do it in your extension you can use the | |
following functions: | |
VALUE rb_obj_hide(VALUE obj) :: | |
Clear RBasic::klass filed. The object will be an internal object. | |
ObjectSpace::each_object can't find this object. | |
VALUE rb_obj_reveal(VALUE obj, VALUE klass) :: | |
Reset RBasic::klass as klass. | |
== Write barriers | |
RGenGC doesn't require write barrier to support generational GC. However, | |
caring about write barrier can improve the performance of RGenGC. Please check | |
the following tips. | |
=== Don't touch pointers directly | |
In MRI (ruby.h), some macros to acquire pointers are supported such as | |
RARRAY_PTR(), RSTRUCT_PTR() and so on. | |
DO NOT USE THESE MACROS and instead use the corresponding C-APIs such as | |
rb_ary_aref(), rb_ary_store() and so on. | |
=== Consider whether to insert write barriers | |
You don't need to care about write barriers if you only use built-in | |
types. | |
If you support T_DATA objects, you may consider using write barriers. | |
Inserting write barriers into T_DATA objects only works with the following | |
type objects: (a) long-lived objects, (b) when a huge number of objects are | |
generated and (c) container-type objects that have references to other objects. | |
If your extension provides such a type of T_DATA objects, consider | |
inserting write barriers. | |
(a): short-lived objects don't become old generation objects. | |
(b): only a few oldgen objects don't have performance impact. | |
(c): only a few references don't have performance impact. | |
Inserting write barriers is a very difficult hack, it is easy to introduce | |
critical bugs. And inserting write barriers has several areas of overhead. | |
Basically we don't recommend you insert write barriers. Please carefully | |
consider the risks. | |
=== Combine with built-in types | |
Please consider utilizing built-in types. Most built-in types support | |
write barrier, so you can use them to avoid manually inserting write barriers. | |
For example, if your T_DATA has references to other objects, then you can | |
move these references to Array. A T_DATA object only has a reference to | |
an array object. Or you can also use a Struct object to gather a T_DATA | |
object (without any references) and an that Array contains references. | |
With use of such techniques, you don't need to insert write barriers anymore. | |
=== Insert write barriers | |
[AGAIN] Inserting write barriers is a very difficult hack, and it is easy to | |
introduce critical bugs. And inserting write barriers has several areas of | |
overhead. Basically we don't recommend you insert write barriers. | |
Please carefully consider the risks. | |
Before inserting write barriers, you need to know RGenGC algorithm (gc.c | |
will help you). Also, some macros in include/ruby/ruby.h and iseq.c will | |
help you. | |
For a complete guide for RGenGC and write barriers, please refer to [...]. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment