* README.EXT: add a document about RGenGC.

Reviewed by havenwood.
  [misc #8962]
* README.EXT.ja: ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44374 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
ko1 2013-12-24 05:00:37 +00:00
Родитель f7979abc84
Коммит 215c40b813
3 изменённых файлов: 121 добавлений и 0 удалений

Просмотреть файл

@ -1,3 +1,11 @@
Tue Dec 24 13:48:45 2013 Koichi Sasada <ko1@atdot.net>
* README.EXT: add a document about RGenGC.
Reviewed by havenwood.
[misc #8962]
* README.EXT.ja: ditto.
Tue Dec 24 12:11:43 2013 Koichi Sasada <ko1@atdot.net>
* include/ruby/ruby.h (RARRAY_ASET): try to avoid compiler warning.

Просмотреть файл

@ -1491,6 +1491,103 @@ RB_EVENT_HOOKS_HAVE_CALLBACK_DATA ::
= Appendix C. Functions available for use in extconf.rb
See documentation for {mkmf}[rdoc-ref:MakeMakefile].
= 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
(http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29).
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 field. 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 to be klass.
We expect the `klass' is hidden class by rb_obj_hide().
== Write barriers
RGenGC doesn't require write barriers 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 (include/ruby/ruby.h), some macros to acquire pointers to the
internal data structures 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 about RGenGC algorithm
(gc.c will help you). Macros and functions to insert write barriers are
available in in include/ruby/ruby.h. An example is available in iseq.c.
For a complete guide for RGenGC and write barriers, please refer to [...].
/*
* Local variables:

Просмотреть файл

@ -1627,6 +1627,22 @@ pkg_config(pkg, option=nil) ::
optionが指定された場合は、上記の配列の代わりにそのオプションを
指定して得られた出力をstripしたものを返す
= Appendix D. 世代別GC
Ruby 2.1から世代別GCに対応しました。我々はこれをRGenGCと呼んでいます。
RGenGCは、過去の拡張ライブラリにほぼ互換性を保つように開発されている
ため、拡張ライブラリ側の対応はほぼ不要です。
ただし、対応をすることで性能を向上することができる可能性があります。もし
拡張ライブラリに高い性能が必要である場合は対応を検討して下さい。
とくにRARRAY_PTR()/RHASH_PTR()のようなマクロを用いてポインタに直接アクセ
スするようなコードは書かないようにして下さい。代わりに、rb_ary_aref(),
rb_ary_store() などの、適切な API 関数を利用するようにして下さい。
そのほか、対応についての詳細は README.ext の「Appendix D. Generational
GC」を参照して下さい。
/*
* Local variables:
* fill-column: 60