Toward efficient
Ruby 2.1
Koichi Sasada<ko1@heroku.com>

Heroku, Inc.
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

1

Agenda• Ruby 2.1 Schedule• Ruby 2.1 new “internal” features• Internal object management hooks• Object allocation tracing• GC hooks• RGenGC: Restricted Generational Garbage
Collection ← Today’s main topic• Ruby 2.1 expected “internal” features• Sophisticated inline cache invalidation mechanism• Memory efficient string management• Useful debugger
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada2Summary•We are implementing new features andimproving Ruby’s quality for Ruby 2.1•Especially introducing “Generational garbage
collector” which I’m working on will improvehuge performance•Ruby 2.1 is currently scheduled on Dec 25,
2013

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

3

Quoted “2.1”“2:1 And there went a man of the house ofLevi, and took to wife a daughter of Levi.”- Book of Exodus“2:1 さて、レビの家のひとりの人が行ってレビの娘をめとった。”- 出エジプト記

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

4

Quoted “2.1”In this presentation,
there are some quoted “2.1” sentence.
Idea of “Quoting” is from“Things a Computer Scientist Rarely Talks About”“コンピュータ科学者がめったに語らないこと”
by Donald E. Knuth
But no consideration in this presentation about them.
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

5

Who am I ?
•笹田耕一 (Koichi Sasada)• Matz team at Heroku, Inc.
• Full-time CRuby development•CRuby/MRI committer• Virtual machine (YARV) from Ruby 1.9• YARV development since 2004/1/1

6

Matz team at Heroku, Inc.
HierarchyMatz @ Shimane
Title collector

ko1 @ Tokyo
EDD developer

Communication
with Skype

Nobu @ Tochigi
Drunker7

Recent status
My leg with a bivalve cast

•5/2 I got sprain…
•5/27 I got cold…

•All: Please care about
yourself• Especially, do not walkwith book reading
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

8Quoted “2.1”“Object-oriented scripting language Ruby is a
programming language designed by Matsumoto.”- Efficient Implementation of Ruby Virtual Machine
Doctoral thesis by Koichi Sasada“オブジェクト指向スクリプト言語Rubyは，松本によって設計されたプログラミング言語である．”- 高速なRuby用仮想マシンの開発
笹田耕一, 博士論文
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

9Ruby’s rough history
1993 2/24
Birth of Ruby
(in Matz’ computer)

1996/12Ruby 1.0

1995/12Ruby 0.95

1999/12Ruby 1.4

1998/12Ruby 1.2

2013/02

2003/8Ruby 1.8

2000/6
Ruby 1.6

Ruby 2.0.0

2009/1
Ruby 1.9.0

1st release2004/1
Start YARV proj.
2000 Book:
Programming Ruby

2012/4
ISO Ruby

2004～
Ruby on Rails

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

10Quoted “2.1”“2.1 Changes from Ruby 1.9
Added and modified libraries from Ruby 1.9 arefollows”- Programming Ruby 1.9 Library edition
by Dave Thomas, with Chad Fowler and Andy Hunt

“2.1 Ruby 1.9のライブラリの変更点
Ruby 1.9で追加または変更されたライブラリは次のとおりです。”- プログラミングRuby 1.9 ライブラリ編
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

11

Ruby 2.0
•New features (see Rubyist Magazine)• Keyword arugments• Refinements• Module#prepend•Ruby 2.0.0-p195 was already released

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada12

# -*- rdoc -*-* aliased method:* ENV.to_h is a new alias for ENV.to_hash* incompatible changes:* Mutex#sleep may spurious wakeup. Checkafter wakeup.

* added Thread#thread_variables for getting alist of the thread local* system() and exec() closes non-standard filedescriptors

variable keys.

variable. See Net::HTTP::new for details.

(The default of :close_others option is changed
to true by default.)* NilClass* added Thread#thread_variable? for testing tosee if a particular thread

default. See Net::HTTP for details.

releases except for bug fixes.

* incompatible changes:* respond_to? against a protected method now
returns false unlessvariable has been set.

* added Thread#backtrace_locations which
returns similar information of

the second argument is true.

* __callee__ has returned to the original
behavior, and now

Kernel#caller_locations.

* File* extended method:reference information is supplied with. For a fulllist of changes

returns the called name but not the original
name in analiased method.

This speeds up connection by using a previously
negotiated session.

* new methods:* Net::HTTP#local_host* added method:* added getsid for getting session id (unix only).

* Thread#join and Thread#value now raises a
ThreadError if target thread* Net::HTTP#local_host=is the current or main thread.
* Kernel#inspect does not call #to_s anymore

with all sufficient information, see the ChangeLog
file.

* Net::HTTP#local_port=
File::FNM_EXTGLOB option is given.

(it used to call redefined #to_s).

* String#codepoints

four characters long. This led to awkward
situations where an export witha password with fewer than four characters was
possible, but accessing the* String#bytes
The most notable change is an update to the ri
data format (ri data must

be regenerated for gems shared across rdoc
versions). Further API changes

are internal and won't affect most users.

* syslog
These methods no longer return an Enumerator,
although passing a* Added Syslog::Logger which provides a Logger
API atop Syslog.
block is still supported for backwards
compatibility.

file afterwards failed. OpenSSL::PKey::RSA,
OpenSSL::PKey::DSA and

OpenSSL::PKey::EC therefore now enforce thesame check when exporting a* Syslog::Priority, Syslog::Level, Syslog::Option and
Syslog::MacrosSee
https://github.com/rdoc/rdoc/blob/master/History.rdoc for a list of* added method:== Changes since the 1.9.3 release* GC* improvements:* added Range#size for lazy size evaluation.

* LoadError* added method:=== C API updates

are introduced for easy detection of available
constants on a

* introduced the bitmap marking which
suppresses to copy a memory page

* added Range#bsearch for binary search.

* change return value:with Copy-on-Write.

* resolv* tmpdir* new methods:* incompatible changes:* Resolv::DNS#timeouts=* Dir.mktmpdir uses FileUtils.remove_entry
instead ofwith OpenSSL 1.0.1 and higher.

transcodes to Encoding.default_internal if it is* new methods:* OpenSSL::OPENSSL_FIPS allows client
applications to detect whether OpenSSL* Signal.trap* Resolv::DNS::Config#timeouts=* added Signal.signame which returns signal
nameis running in FIPS mode and to react to thespecial requirements this* Net::IMAP.default_port

might impy.

* TracePoint* Module* SSL/TLS support for the Next Protocol
Negotiation extension. Supported

set.

* added method:* introduced the non-recursive marking which
avoids unexpected stack overflow.

works because str.lines returns an array. Replacelines with

each_line in such cases.
* Net::HTTP#connect uses local_host andlocal_port if specified.

* Time#to_s returned encoding defaults to USASCII but automatically* Signal* rexml* Net::IMAP.default_imap_port* new class. This class is replacement of
set_trace_func.

Code like str.lines.with_index(1) { |line,
lineno| ... } no longer

running system.

long.

NEWS file of Ruby 2.0* added LoadError#path method to return thefile name that could not beloaded.

changes in rdoc 4.0.

* Time* net/imap* NUM2SHORT() and NUM2USHORT() added. They
are similar to NUM2INT, but short.

private key to PEM with a password - it has to beat least four characters* Range* extended method:* rb_newobj_of() and NEWOBJ_OF() added. They
create a new object of a given class.

* OpenSSL requires passwords for decrypting
PEM-encoded files to be at least* Net::HTTP#local_port* File.fnmatch? now expands braces in thepattern if* String#lines* Shellwords#shelljoin() accepts non-string
objects in the given
This version is largely backwards-compatible withprevious rdoc versions.

* Process* incompatible changes:

Note that each entry is kept so brief that no reason
behind or* SSL sessions are now reused across connections
for a single instance.

* added nil.to_h which returns {}* Fiber#resume cannot resume a fiber which
invokes "Fiber#transfer".

* Shellwords#shellescape() now stringifies thegiven object using to_s.

array, each of which is stringified using to_s.

* Fiber* added method:* rdoc has been updated to version 4.0* String#chars
OpenSSL::SSL::OP_DONT_INSERT_EMPTY_FRAGME
NTS.

= NEWS for Ruby 2.0.0

This document is a list of user visible featurechanges made between* Support for "0/n" splitting of records as BEAST
mitigation via* gzip and deflate compression are now
requested for all requests by* REXML::Document#write supports Hasharguments.

FileUtils.remove_entry_secure. This means thatapplications should not

See above.

change the permission of the created temporary
directory to makeaccessible from other users.

* Net::IMAP.default_tls_port* Merge Onigmo.

https://github.com/k-takata/Onigmo* ostruct=== Library updates (outstanding ones only)* added method:
Easy to use and efficient implementation.

* GC::Profiler* added method:* added Module#prepend which is similar to
Module#include,* builtin classes* added GC::Profiler.raw_data which returns
raw profile data for GC.

however a method in the prepended module
overrides the

Many new features!!
* Net::IMAP.default_imaps_port* Signal.trap raises ArgumentError
when :SEGV, :BUS, :ILL, :FPE, :VTALRM* OpenStruct#[], []=* Hash* added method:* added method:

XML declaration is used for XML document
encoding.

* Syck has been removed. YAML now completelydepends on libyaml being

installed.

* OpenStruct#hash* RubyGems* zlib* Updated to 2.0.0.preview2* Added streaming support for Zlib::Inflate andZlib::Deflate. This allows

explicitly requested such as system(..., fd=>fd).

* ObjectSpace.reachable_objects_from(obj)* incompatible changes:* random parameter of Array#shuffle! andArray#sample now

will be called with one argument, maximum
value.

* OpenStruct#to_h converts the struct to a hash.
[experimental]* added Hash#to_h as explicit conversion
method, like Array#to_a.

* added method:* cgi* added Module#refinements, which returns
refinements defined in the* added String#b returning a copied string
whose encoding is ASCII-8BIT.

receiver. [experimental]* Hash#default_proc= can be passed nil to clear
the default proc.

* added Module#using, which imports
refinements into the receiver.

[experimental]* change return value:* String#lines now returns an array instead of an
enumerator.

* String#chars now returns an array instead ofan enumerator.

* Kernel* CGI#header has been renamed to
CGI#http_header andaliased to CGI#header.

* When HTML5 tagmaker called, overwrite
CGI#header,

processing of a stream without the use of large
amounts of memory.
* OpenStruct.new also accepts an OpenStruct /Struct.

* Added support for the new deflate strategies
Zlib::RLE and Zlib::FIXED.

of OpenSSL::ASN1::Primitive now raise TypeError
when calling to_der on an* Zlib streams are now processed without the GVL.
This allows gzip, zlib andinstance whose value is nil. All instances of
OpenSSL::ASN1::Constructive* pathname* String#codepoints now returns an array
instead of an enumerator.

* added method:* added Kernel#Hash conversion method like
Array() or Float().
* Enumerable* added Kernel#using, which imports
refinements into the current scope.

* Module#define_method accepts a
UnboundMethod from a Module.

CGI#header function is to create a <header>element.

* String#bytes now returns an array instead ofan enumerator.
* Module#const_get accepts a qualified
constant string, e.g.

Object.const_get("Foo::Bar::Baz")* Struct* Enumerator* added Kernel#caller_locations which returns
an array of* Mutex* added Struct#to_h returning values with keys
corresponding to the* Iconv has been removed. Use String#encode
instead.

* TLS 1.1 & 1.2 support by setting
OpenSSL::SSL::SSLContext#ssl_version to* Pathname#find returns an enumerator if noblock is given.
* `gem search` now defaults to --remote and isanchored like gem list.

frame information objects.
* added Enumerator#size for lazy size
evaluation.

* extended method:* extended method:* rake* rake has been updated to version 0.9.5.

* Kernel#warn accepts multiple args in like puts.

:TLSv1_1_client. The version being effectively
used can be queried* new features:* added IO#wait_writable method.

* Thread* added IO#wait_readable method as alias of
IO#wait.

* Kernel#caller accepts second optional
argument `n' which specify

required caller size.

* ENV* Kernel#to_enum and enum_for accept a blockfor lazy size evaluation.

disable documentation, --document=rdoc toonly generate rdoc.

* Added %i and %I for symbol list creation (similar
to %w and %W).

with OpenSSL::SSL#ssl_version. Furthermore, it isalso possible to* OpenStruct new methods can conflict withcustom attributes named"each_pair", "eql?", "hash" or "to_h".
* Only ri-format documentation is generated bydefault.
This version is backwards-compatible withprevious rake versions and* Default source encoding is changed to UTF-8.
(was US-ASCII)* `gem server` uses RDoc::Servlet from RDoc 4.0
to generate HTML* Thread#join, Thread#value

contains many bug fixes.

=== Compatibility issues (excluding feature bug
fixes)

blacklist the new TLS versions with
OpenSSL::SSL:OP_NO_TLSv1_1 and

See above.

See
OpenSSL::SSL::OP_NO_TLSv1_2.

For an expanded list of updates and bug fixes see:* incompatible changes:* added method:* Enumerator.new accept an argument for lazy
size evaluation.

* Added --document to replace --rdoc and --ri.
Use --no-document todocumentation.

* added Mutex#owned? which returns the
mutex is held by current

thread or not. [experimental]

See above.
=== Language changes:TLSv1_2, :TLSv1_2_server, :TLSv1_2_client
or :TLSv1_1, :TLSv1_1_server* io/wait* added method:
instance variable names.

* added method:* Dir.mktmpdir in lib/tmpdir.rb
deflate streams to be processed in parallel.

* A gem can have arbitrary metadata throughGem::Specification#metadata* added method:* added Kernel#__dir__ which returns a current
dirname.

* Improved support for default gems shippingwith ruby 2.0.0+* extended method:

unless the second argument is true.

permitted.
* iconv[experimental]

raise NoMethodError in the same case.
Constructing such values is still* Kernel#respond_to? against a protected method
now returns false

RubyGems 2.0.0 features the following
improvements:* Consistently raise an error when trying toencode nil values. All instances* extended method:

value that is out-of-range.

* added Enumerable#lazy method for lazy
enumeration.

* extended method:* openssl* extended method:* when given Range arguments, Array#values_at
now returns nil for each

* added method:* Add HTML5 tag maker.

Also, the close-on-exec flag is set by default for
all new file descriptors.

This means file descriptors doesn't inherit tospawned process unless* new method:* String* added method:* added Array#bsearch for binary search.

* The :close_others option is true by default forsystem() and exec().

* objspace* OpenStruct#eql?
* added main.define_method which defines a
global function.

* added Module#refine, which extends a classor module locally.

XML document encoding. Without :encoding
option, encoding in* toplevel* OpenStruct#each_pair

are specified.

* yaml* new methods:* incompatible changes:

corresponding method in the prepending
module.

* Array* REXML::Document#write supports
new :encoding option. It changes* Net::IMAP.default_ssl_port* Mutex#lock, Mutex#unlock, Mutex#try_lock,Mutex#synchronize

and Mutex#sleep are no longer allowed to be
used from trap handler

and raise a ThreadError in such case.

* added Thread#thread_variable_get for getting
thread local variables(these are different than Fiber local variables).

* added Thread#thread_variable_set for setting
thread local variables.

* AddedOpenSSL::SSL::SSLContext#renegotiation_cb. A
user-defined callback* net/http* new features:* Proxies are now automatically detected fromthe http_proxy environment

http://rake.rubyforge.org/doc/release_notes/rake0_9_5_rdoc.html for a list

* Array#values_at* Mutex#lock, Mutex#unlock, Mutex#try_lock,Mutex#synchronize and Mutex#sleep

https://github.com/rubygems/rubygems/blob/mas
ter/History.txt
of changes in rake 0.9.3, 0.9.4 and 0.9.5.

may be set which gets called whenever a newhandshake is negotiated. This

also allows to programmatically decline (client)
renegotiation attempts.

See above.
See above.
* shellwords* rdoc13

“Ruby is almost matured as aprogramming language with 2.0 ”
http://itpro.nikkeibp.co.jp/article/NEWS/20130214/456322/
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

14

Ruby 2.1 release announcement“I‘m planning to call for feature proposals soon like
2.0.0 [ruby-core:45474], so if you have a suggestion
you should begin preparing the proposal.”“ちなみに、Ruby 2.1.0 は2013年12月25日のリリースを予定しています。そのうち 2.0.0 の時のように機能提案募集をするつもりなので、われこそをという方はそろ
そろネタの仕込みを始めてくださいませ。”- [ruby-core:54726] Announce take over the releasemanager of Ruby 2.1.0
by NARUSE, Yui
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

15

Ruby 2.1 schedule
2013/022013/12Ruby 2.0.0

Ruby 2.1.0

RubyKaigi2013
5/30, 31, 6/1

Euruko2013
6/28, 29

RubyConf2013
11/8-10

Events are important for
EDD (Event Driven Development) Developers
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

16

Ruby 2.1
•New features

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada17

# -*- rdoc -*= NEWS for Ruby 2.1.0
This document is a list of user visible feature changes made between
releases except for bug fixes.
Note that each entry is kept so brief that no reason behind orreference information is supplied with. For a full list of changes
with all sufficient information, see the ChangeLog file.
== Changes since the 2.0.0 release=== Language changes=== Core classes updates (outstanding ones only)* GC* added environment variable:* RUBY_HEAP_SLOTS_GROWTH_FACTOR: growth rate of the heap.
* IO* extended methods:* IO#seek accepts symbols (:CUR, :END, :SET) for 2nd argument.
* Kernel* New methods:* Kernel#singleton_method* Mutex* misc* Mutex#owned? is no longer experimental.
* String* New methods:* String#scrub and String#scrub! verify and fix invalid byte sequence.
* extended methods:* If invalid: :replace is specified for String#encode, replace
invalid byte sequence even if the destination encoding equals tothe source encoding.
* pack/unpack (Array/String)* Q! and q! directives for long long type if platform has the type.
=== Core classes compatibility issues (excluding feature bug fixes)* IO* incompatible changes:* open ignore internal encoding if external encoding is ASCII-8BIT.
* Module#ancestors
The ancestors of a singleton class now include singleton classes,
in particular itself.

See NEWS file=== Stdlib updates (outstanding ones only)* Digest* extended methods:* Digest::Class.file takes optional arguments for its constructor* Matrix* Added Vector#cross_product.

Now, much smaller than Ruby 2.0* Net::SMTP* Added Net::SMTP#rset to implement the RSET command* Pathname* New methods:* Pathname#write* Pathname#binwrite* OpenSSL::BN* extended methods:* OpenSSL::BN.new allows Fixnum/Bignum argument.
* open-uri* Support multiple fields with same field name (like Set-Cookie).
* Resolv* New methods:* Resolv::DNS.fetch_resource* One-shot multicast DNS support* Support LOC resources* Rinda::RingServer, Rinda::RingFinger* Rinda now supports multicast sockets. See Rinda::RingServer andRinda::RingFinger for details.
* Socket* New methods:* Socket.getifaddrs* StringScanner* extended methods:* StringScanner#[] supports named captures.
* Tempfile* New methods:* Tempfile.create=== Stdlib compatibility issues (excluding feature bug fixes)* URI* incompatible changes:* URI.decode_www_form follows current WHATWG URL Standard.
It gets encoding argument to specify the character encoding.
It now allows loose percent encoded strings, but denies ;-separator.
* URI.encode_www_form follows current WHATWG URL Standard.
It gets encoding argument to convert before percent encode.
UTF-16 strings aren't converted to UTF-8 before percent encode by default.
=== C API updates

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

18

Quoted “2.1”“Character set and CES which application should support isdifferent by users. However, it is not high priority to support
one application supports multi-CES.”- Implementation of Practical Multilingual Text Manipulation for Ruby (academic paper)by Yukihiro Matsumoto(translated by Koichi Sasada)“アプリケーションが対応すべき文字集合およびCESはユーザごとに異なるが、1つのアプリケーションが同時に複数のCESに対応する必要性はさほど高くない。”- Ruby における実用的な多言語処理の実装（論文）松本 行弘
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

19

Ruby 2.1 features•Refine m17n introduced from Ruby 1.9• String#scrub, String#scrub!
• Verify and fix invalid byte sequence.

• More efforts? I heard Matz has some ideas.

•Refine features introduced from Ruby 2.0• Keyword arguments• Refinements• Module#prepend
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

20

Quote about 2.0 from Heroku blog

21

Of course, Ruby 2.0.0 is ready on Heroku!
22

Me!

23

24

Mention about “Speed”
Ruby 2.0 has a faster garbage collector and is Copy on
Write friendly. Copy on Write or COW is an optimization
summary:
GCofusesbitmapthat can reduce the Shortmemoryfootprint
a Rubyprocess
when it is copied. Insteadof allocating
duplicatemarking
and CoWfriendlymemory when a process is forked, COW allows multiple
processes to share the same memory until one of theprocesses needs to modify a piece of information.
Depending on the program, this optimization candramatically reduce the amount of memory used to run
multiple processes. Most Ruby programs are memory
bound, so reducing your memory footprint with Ruby
2.0 may allow you to run more processes in fewer dynos.
If you’re not already Shortrunninga concurrent
summary:Let’s backend
try Unicorn!
consider trying the Unicorn web server.
25

（；ﾟ Дﾟ）
Only mention about GC!!??
(I don’t work on GC)

26

｡+.｡ヽ(*>∀<*)ﾉ｡.+。
Let’s consider about
GC/memory management!

27

Ruby 2.1 internal features•Internal hooks for memory management•RGenGC: Restricted generational garbage
collection

Today’s topic

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

28

Internal hooks for memory management
What’s nice?
•You can collect more detailed analysis•Examples• Collect object allocation site information• Collect usage of allocated objects• Measure GC performance from outside

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

29

Internal hooks for memory management• Added events• RUBY_INTERNAL_EVENT_NEWOBJ• When object is created• RUBY_INTERNAL_EVENT_FREEOBJ• When object is freed• RUBY_INTERNAL_EVENT_GC_START• When GC is started• RUBY_INTERNAL_EVENT_GC_END• When GC is finished

GC
Start

Mark Sweep

GC
End
Sweep

Sweep

Sweep

Sweep

Ruby
Stop the(Ruby)World

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

30

Internal hooks for memory management*Caution*•You can *NOT* trace these events using
TracePoint (introduced from 2.0)
•You need to write C-ext to use them, because
events are invoked during GC, etc

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

31

Internal hooks for memory management
Sample features•ObjectSpace. trace_object_allocations• Trace object allocation and record allocation-site• Record filename, line number, creator method’s id and class• Usage:
ObjectSpace.trace_object_allocations{ # record only in the blocko = Object.new
file = ObjectSpace.allocation_sourcefile(o) #=> __FILE__
line = ObjectSpace.allocation_sourceline(o) #=> __LINE__ -2}• Demonstration
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada32

Internal hooks for memory management
Postponed job•You may want to write hooks in Ruby
→ Use ‘Postponed job’
• ‘Postponed jobs’ run at same timing as finalizers• Usage: rb_postponed_job_register(func, data)• `func(data)’ will be called at a safe-point•See an sample code in “ext/objspace/gc_hooks.c”• ObjectSpace.after_gc_(start|end) = proc{GC.start}• Proc is called after GC
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada33

“2.1 Structure of VALUE and objects

Quoted “2.1”

In ruby, the contents of an object is expressed by a C structure,
always handled via a pointer. A different kind of structure is used foreach class, but the pointer type will always be VALUE.”- Ruby Hacking Guide
by Minero Aoki

“2.1 VALUEとオブジェクト構造体
rubyではオブジェクトの実体を構造体で表現し、扱うときは常に ポ

インタ経由で扱う。構造体のほうはクラスごとに違う型を使うが、ポインタのほうはどのクラスの構造体でも常にVALUE型だ。 “- Rubyソースコード完全解説
青木峰郎
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

34

RGenGC: Summary•RGenGC: Restricted Generational GC• New GC algorithm allows mixing “Write-barrier
protected objects” and “WB unprotected objects”• No (mostly) compatibility issue with C-exts•Inserting WBs gradually• We can concentrate WB insertion efforts for major
objects and major methods• Now, Array, String, Hash, Object, Numeric objects
are WB protected• Array, Hash, Object, String objects are very popular in Ruby
• Array objects using RARRAY_PTR() change to WB unprotected
objects (called as Shady objects), so existing codes still works.
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

35

RGenGC: Agenda•Background• Generational GC• Ruby’s GC strategy•Proposal: RGenGC• Separating into sunny and shady objects• Shady objects at marking• Shade operation•Implementation
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

36

RGenGC: Background
Current CRuby’s GC•Mark & Sweep• Conservative• Lazy sweep• Bitmap marking• Non-recursive marking•C-friendly strategy• Don’t need magical macros in C source codes• Many many C-extensions under this strategy

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

37

Quoted “2.1”“2.1 About Mark&Sweep GC
Mark&Sweep GC consists of mark and sweep phase.”- Garbage Collection-Algorithms and Implementations
By Narihiro Nakamura, Hikaru Aikawa(translated by Koichi Sasada)“2.1

マークスイープGCはその名の通り、マークフェーズとスイープフェーズから成ります。”-ガベージコレクションのアルゴリズムと実装
By 中村成洋、相川光
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

38

RGenGC: BackgroundMark & Sweep
Root objects
traverse
markedtraverse
markedtraverse
marked

1. Mark reachable
objects from rootobjectsfree
free
2. Sweep unmarked
traverse
objects (collection
Collect
and de-allocation)
unreachable
markedobjects

traverse
markedfree

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

39

RGenGC: Background
Generational GC (GenGC)•Weak generational hypothesis: Most objects die
young → Concentrating reclamation effort on theyoungest objects•Separate young generation and old generation• Create objects as young generation• Promote to old generation after surviving nth GC• In CRuby, n == 1 (after 1 GC, objects become old)

•Usually, GC on young space (minor GC)•GC on both spaces if no memory (major/full GC)
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

40

RGenGC: Background
Generational GC (GenGC)•Minor GC and Major GC can use different GC
algorithm• Popular combination→ Minor GC: Copy GC, Major GC: M&S• On the CRuby’s: both Minor&Major GCs should
be M&S because CRuby’s GC (and existing codes)
based on conservative M&S algorithm

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

41

RGenGC: Background: GenGC[Minor M&S GC]
1st MinorGC• Mark reachable objects
from root objects.

Root objects
traverse
new/
free

new
traverse

traverse

new/
free

collect
newtraverse
new

new
traversenew• Mark and promote to oldgen• Stop traversing after old
objects→ Reduce mark overhead• Sweep not (marked orold) objects• Can’t collect Some
unreachable objects•
Don’t collect old object
old/
free

even
if it is unreachable.
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

42

RGenGC: Background: GenGC[Minor M&S GC]
2nd MinorGC• Mark reachable objects
from root objects.

Root objects
traverse
new/
free

old
ignoreignorenew/freecollectoldignoreold

oldignoreold• Mark and promote to oldgen• Stop traversing after old
objects→ Reduce mark overhead• Sweep not (marked orold) objects• Can’t collect Some
unreachable objects•
Don’t collect old object
old/
free

even
if it is unreachable.
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

43

RGenGC: Background: GenGC[Major M&S GC]• Normal M&S• Mark reachable objects fromroot objects

Root objects
traverse

new/
free

new
traverse

traverse

new/
free

• Mark and promote to old gen• Sweep unmarked objects

collectoldtraverseold• Sweep all unreachable(unused) objects

newtraverse
old

old/
free
collect
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

44

Quoted “2.1”“2.1 The mark-sweep algorithm
From the viewpoint of the garbage collector,
mutator threads perform just three operationsof interest, New, Read and Write, which eachcollection algorithm must redefine
appropriately.”- The Garbage Collection Handbook
by Richard Jones, Antony Hosking, Eliot Moss

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

45

RGenGC: Background: GenGC
WB & Remember Set (RSet)•Old objects refer young
objects→ Minor GC causes
marking leak!!

old

old

old

• Because minor GC ignoresreferenced objects by old
objects

new
Can’t mark new object!
→ Sweeping living object! (BUG)

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

46

RGenGC: Background: GenGC
WB & Remember Set (RSet)
Rememberset (RSet)
old

old

• At minor GC, mark all
remembered objects

old

new

new

•Add an old object into
Remember set (RSet) if an
old object refer new
objects

new•To detect [old→new] typereferences, insert “Writebarrier”• “Generating references” ==“Write”

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

47

RGenGC: Background: GenGC[Minor M&S GC] w/ RSet
Rememberset (RSet)

Root objects
traverse
new
traverse

collect
new/
new/
free
free

old
ignoreignoreold

traverseoldold•Mark reachable
objects from rootobjects• Remembered objects
are also root objects• Stop traversing after old
objects•Sweep not (marked orold) objects

new
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

48

RGenGC: Problem
Write-barrier (WB) and CRuby• To introduce generational garbage collector, WBs
are necessary to detect [old→new] type reference• Write-barrier (WB) example in Ruby world• (Ruby) old0[0] = new0 # [old0 → new0]• (Ruby) old1.foo = new0 # [old1 → new1]• Write-barriers miss causes terrible failure• WB miss→ Remember-set registration miss→ (minor GC) marking-miss → Terrible GC BUG!!

• All of C-extensions need perfect Write-barriers• Manipulate Ruby objects in C language (in C-ext)• C-level WBs are needed
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

49

RGenGC: Problem
Inserting WBs into C-extensions (C-ext)• Problem: Compatibility• Example (C) RARRAY_PTR(old0)[0] = new1
• There are Many Many C-exts’ sources like that

•CRuby core code uses C-APIs, but we can rewrite
all of source code (with terrible debugging!!)•We can’t rewrite all of C-exts which are writtenby 3rd party

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

50

RGenGC: Problem
Inserting WBs into C-extensions (C-ext)“Two options”
Current
Choice[Give up on GenGC]or[GenGC with re-writing all of Cextensions without C-exts compatibility]

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

51

RGenGC:
Related work on Ruby’s GenGC•Kiyama, et. al. GenGC for CRuby• Straightforward implementation for Ruby 1.6• Need WBs in correct places• High development cost
• Can’t keep compatibility → Drop all C-exts•Nari, et.al longlife GC for CRuby• Introduce GenGC only for Node object• No compatibility issues because C-exts don’t use
node• Now CRuby doesn’t use many number of node
objects• High development cost (to guarantee WBs)
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

52

RGenGC:
Related work on Ruby’s GenGC•Make interpreter with other language
infrastructures which have GC• JRuby, IronRuby• Can’t keep compatibility with current C-exts•Separate core heap and CRuby C-ext heap
• High development cost

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

53

RGenGC: Challenge•How to insert Write-barriers?
• In Ruby-core, we can chnage w/ huge effort• However, we can’t touch existing C-exts ← Problem•Several approaches• Separate heaps into the WB world and non-WB
world• Need to re-write whole of Ruby interpreter• Need huge development effort• WB auto-insertion• Modify C-compiler• Need huge development effort
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

54

RGenGC:
Challenge to introduce GenGC•Create GC algorithm permits WB protected
objects AND WB un-protected object in thesame heap

RGenGC: Restricted Generational
Garbage Collection
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

55

RGenGC: Goal
Inserting WBs into C-extensions (C-ext)“2 → 3 options”[Give up on GenGC]or[GenGC with re-writing all of Cextensions without C-exts compatibility]or
New[Use RGenGC]
choice!!
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

56

RGenGC:
Key idea•Introduce Shady object• In this context, “Shady” means questionable,
doubtful, etc• Something feeling dark
• 日陰者, in Japanese

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

57

Google image search: “日陰者”

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

58

RGenGC:
Key Idea• Separate objects into two types• Shady Object: WB Unprotected• Sunny Object: WB Protected

Shady（´･ω･`）

Shady: doubtful,questionable, ...
An antonym of
the word “Shady”

Sunny＼（＾o＾）／• Decide this type at creation time
• A class don’t care about WB → Shady obj• A class care about WB → Sunny obj• Currently, most of classes DON’t care about WB,
so most of objects are created as Shady objects.
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

59

RGenGC:
Key Idea•Sunny objects can change
to Shady objects

VM
Create• “Shade” operation• In the C program doesn’tcare about RGenGC• Example

Shade• ptr = RARRAY_PTR(ary)• In this case, we can’t insert WB for
ptr operation, so VM shade “ary”

Sunny
obj

Shady
obj

Shady object can’tchange into sunny object

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

60

RGenGC
Key Idea: Rule
•Mark “Shady objects” correctly• At Marking
1. Don’t promote shady objects to old objects
2. Remember shady objects pointed from old
objects• At Shade operation for old sunny objects
1. Demote objects
2. Remember shaded shady objects

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

61

RGenGC[Minor M&S GC w/Shady object]
1st MinorGC

Root objects
traverse

traversenew

new

Rememberset (RSet)remembercollect
new/
new/
free
free

traverse
new
traverse

traverse
new

new
traverseoldnewmark andremembertraverse•Mark reachable objects
from root objects• Mark shady objects, and*don’t promote* to old
gen objects• If shady objects pointed
from old objects, thenremember shady objects
by RSet.
→ Mark shady objects
every minor GC!!

old
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

62

RGenGC[Minor M&S GC w/Shady object]
2nd MinorGC

Root objects
traverse

traversenewoldRememberset (RSet)collect
new/
new/
free
free

ignoreoldignoreignorenewoldtraverse

traverse•Mark reachable objects
from root objects• Mark shady objects, and*don’t promote* to old
gen objects• If shady objects pointed
from old objects, thenremember shady objects
by RSet.
→ Mark shady objects
every minor GC!!

traverse
old

new

old
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

63

RGenGC[Shade operation]
Rememberset (RSet)
old

old

•Old sunny objects → Shadeobjects• Example: RARRAY_PTR(ary)• (1) Demote object (old → new)
• (2) Register it to Remember Set

Shady

new

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

64

RGenGC
Timing chart
2.0.0 GC (M&S w/lazy sweep)
Ruby

Mark

Sweep

Sweep

Sweep

Sweep

Sweep

Stop the (Ruby)
World

w/RGenGC (Minor GC)
RubyMark Sweep

Stop the(Ruby)
World

Sweep

Sweep

Sweep

Sweep

• Shorter mark time (good)• Same sweep time (not good)• (little) Longer execution time b/c WB (bad)
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

65

RGenGC
Number of marking objects
2.0.0 GC (M&S w/lazy sweep)
Living object counts

w/RGenGC (Minor GC)(a)

Living object counts# of old
object(#old)(c)

Freed object counts(b)Freed object counts# of freed# of newobject (#new) but remembered (a) # of old objects by WB(b) # of shady objects pointed by old
objects(c) # of old but shady objects
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

66

RGenGC
Number of marking objects(a)w/RGenGC (Minor GC)
Living object counts# of old
object(#old)(c)(b)
Freed object counts# of freed# of new(a) # of old objects by WB
object (#new) but remembered (b) # of shady objects pointed by old
objects(c) # of old but shady objects

Marking space

Number of unused,uncollected objs

Sweeping
space

Traditional GenGC#new + (a)

(a)

#new

RGenGC#new + (a) + (b) + (c)(a) + (b)Full heap

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

67

RGenGC
Discussion: Pros. and Cons.
•Pros.
• Allow WB unprotected objects (shady objects)• 100% compatible w/ existing extensions (and standard classes/methods)• Inserting WBs step by step, and increase
performance gradually• We don’t need to insert all WBs into interpreter core at a time
• We can concentrate into popular (frequent) classes/methods.
• We can ignore minor classes/methods.

• Simple algorithm, easy to develop (done!)

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

68

RGenGC
Discussion: Pros. and Cons.
•Cons.

• Increasing “unused, but not corrected objects
until full/major GC• Remembered objects (caused by well known GenGC algorithm)• Remembered shady objects (caused by RGenGC algorithm)• WB insertion (potential) bugs

• RGenGC permit shady objects, but sunny objects needcorrect/perfect WBs. But inserting correct/perfect WBs is difficult.
• This issue is out of scope. We have another idea against thisproblem (out of scope).

• Can’t reduce Sweeping time

• But many (and easy) well-known techniques to reduce sweeping
time (out of scope).
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

69

Quoted “2.1”“2.1 Character set…”- C Reference manual
By Samuel P. Harbison III, Guy L.Steele Jr.
“2.1 文字集合
一つのCソースファイルは、一つの文字集合に含まれる文字の並びである。”
-C リファレンスマニュアル
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

70

RGenGC
Implementation• Introduce two flags into RBasic• FL_KEEP_WB: WB protected or not protected• 0 → unprotected → Shady object• 1 → protected → Sunny object• Usage: NEWOBJ_OF(ary, struct RArray, klass, T_ARRAY | FL_KEEP_WB);• FL_OLDGEN: Young gen or Old gen?
• 0 → Young gen• 1 → Old gen• Don’t need to touch by user program• Remember set is represented by bitmaps• Same as marking bitmap• heap_slot::rememberset_bits• Traverse all object area with this bitmap at first
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

71

RGenGC
Implementation: WB operation API•OBJ_WRITE(a, &a->x, b)‘a’• Declare ‘a’ aggregates ‘b’‘&a->x’• Write: *&a->x = b• Write barrier• OBJ_WRITE(a, b) returns “a”

b

oldv

•OBJ_WRITTEN(a, oldv, b)• Declare ‘a’ aggregates ‘b’ and old value is ‘oldv’• Non-write operation• Write barrier
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

72

RGenGC
Implementation: WB operation API•T_ARRAY• RARRAY_PTR(ary) causes shade operation• Can’t get RGenGC performance improvement• But works well •Instead of RARRAY_PTR(ary), use alternatives• RARRAY_AREF(ary, n) → RARRAY_PTR(ary)[n]• RARRAY_ASET(ary, n, obj) → RARRAY_PTR(ary)[n] =obj w/ Write-barrier• RARRAY_PTR_USE(ary, ptrname, {...block...})• Only in block, pointers can be accessed by `ptrname’ variable(VALUE*).
• Programmers need to insert collect WBs (miss causes BUG).
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

73

RGenGC
Incompatibility•Make RBasic::klass “const”• Need WBs for a reference from an object to a
klass.
• Only few cases (zero-clear and restore it)• Provide alternative APIs
• Now, RBASIC_SET_CLASS(obj, klass) andRBASIC_CLEAR_CLASS(obj) is added. But they should be internal
APIs (removed soon).
• rb_obj_hide() and rb_obj_reveal() is provided.

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

74

RGenGC
Implementation•RGENGC_CHECK_MODE in gc.c
• 1: Enable assertions• 2: Enable “WB checking” mode

•WB checking mode

• (1) do minor GC• (2) do major/full GC• (3) compare result with (1) and (2)• If living objects in (2) but not living in (1) it should be BUG!!

• Not a perfect (implementation limitation), but agood method to detect bugs
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

75

RGenGC
Implementation•Macros in ruby/ruby.h• USE_RGENGC• You can enable/disable RGenGC with this macro.

• RGENGC_WB_PROTECTED_???
• RGENGC_WB_PROTECTED_ARRAY, RGENGC_WB_PROTECTED_HASH,RGENGC_WB_PROTECTED_STRING, RGENGC_WB_PROTECTED_OBJECT,
RGENGC_WB_PROTECTED_FLOAT, RGENGC_WB_PROTECTED_COMPLEX,RGENGC_WB_PROTECTED_RATIONAL, RGENGC_WB_PROTECTED_BIGNUM• Now, only supports above types (T_???).
• T_CLASS, T_MODULE and T_DATA is needed to support with high priority.

• You can enable/disable RGenGC for each types.

• If you have trouble with RGenGC, try to disable them.
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

76

RGenGC
Performance evaluation•Ideal micro-benchmark for RGenGC• Create many old objects at first• Many new objects (many minor GC, no major GC)•RDoc• Same RDoc generation as Ruby’s trunk

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

77

RGenGC
Performance evaluation (micro)
600000000• Shorter mark time (good)• Same sweep time (not good)

Execution time by RDTSC

500000000

400000000

mark (RGENGC)

300000000

sweep (RGENGC)
mark
sweep

200000000

Good marktime 
100000000

Same sweep
time 

0

1

2

3

4

5

6

7

8

9

10 11 12 13 14 15 16 17 18 19 20 21 22 23

GC count

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

78

RGenGC
Performance evaluation (RDoc)
400
350

Several major/full
GC peaks

300

250
ms

Mark Time(ms)Sweep Time(ms)200

RGenGC/Mark Time(ms)150
Fasterminor
100 GCRGenGC/Sweep Time(ms)

50

1
15
29
43
57
71
85
99
113
127
141
155
169
183
197
211
225
239
253
267
281
295
309
323
337
351

0

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

Total GC countis different
79

RGenGC
Performance evaluation (RDoc)
60000
50000

ms

40000
Total markTotal sweep

30000
20000
10000
0
NormalRGenGC

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

80

sec

RGenGC
Performance evaluation (RDoc)
225
220
215
210
205
200
195
190
185
180
175

Impressive!!
Execution time

NormalRGenGC

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

Of course, this is “Graph magic”.
If a students submits this graph,his score is fail.
81

RGenGC
Performance evaluation (RDoc)
250

About 15% speedup!

200
150

Execution time

100
50
0
NormalRGenGC
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

82

RGenGC: Summary•RGenGC: Restricted Generational GC• New GC algorithm allow mixing “Write-barrier
protected objects” and “WB unprotected objects”• No (mostly) compatibility issue with C-exts•Inserting WBs gradually• We can concentrate WB insertion efforts for major
objects and major methods• Now, Array and String objects are WB protected• Array and String objects are very popular in Ruby
• Array objects using RARRAY_PTR() change to WB unprotected
objects (called as Shady objects), so existing codes work well
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

83

RGenGC
Future work
•Minor GC / Major GC timing• Too many major GC → slow down
• Too few major GC → memory consumption issue, etc•Make more sunny objects (especially T_CLASS)•Optimize remember set representation•Inserting WBs w/ application profiling• Profiling system• Benchmark programs•Detection system for WBs insertion miss

• RGENGC_CHECK_MODE (2, in gc.c) is not enough
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

84

RGenGC
Issues: Terminology•Matz rejected the word “Sunny”•“Shady” has a meaning of “questionable,
doubtful, …”, but “Sunny” has no meaning of
against “questionable, doubtful, etc”.

Shady（´･ω･`）

Sunny＼（＾o＾）／

Doubtful,questionable, etc???

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

85

RGenGC
Issues: Terminology• This is a last presentation to use “Shady” and“Sunny”• We will replace codes and documents with:• “Shady” → “WB unprotected”• “Sunny” → “WB protected”• Or• “Shady” → “Shady” (remain)• “Sunny” → “Normal” (not shady)

If you have any idea of the words,
please let us know.
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

86

Quoted “2.1”“2:1 Now when Jesus was born in Bethlehem of
Judaea in the days of Herod the king, behold, there
came wise men from the east to Jerusalem,”- Gospel of Matthew“2:1 イエスがヘロデ王の代に、ユダヤのベツレヘム

でお生れになったとき、見よ、東からきた博士たちがエルサレムに着いて言った、”- マタイによる福音書
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

87

Ruby 2.1 expected “internal” features• Sophisticated inline cache invalidation mechanism• Memory efficient string management & Symbol GC• Fine-grain memory protection to detect WB
insertion miss• Signal thread• More efficient inter-process migration technique• JIT compilation for small part of Ruby code
• Introduce fastpath C-methods type
• Inlined Proc.call invocation• AOT Compiler and extending “require” behavior• Useful debugger
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

88Sophisticated inline cacheinvalidation mechanism•From Ruby 1.9 (YARV), inline cache technique
is used in several codes• Inline method caching ← Huge opportunity• Constant lookup•…

•Cache invalidation with only one variable“global_state_version”•Invalidate inline cache, other non-related
inline caches are also invalidated
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

89

Sophisticated inline cacheinvalidation mechanism•Invalidate all classes’ method cache
ObjectRedefine X,
invalidate all ofclasses

X

X1

Y

X2

Z

Z1

Z2

X1a
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

90

Sophisticated inline cacheinvalidation mechanism“This patch adds class hierarchy method
caching to CRuby. This is the algorithm used by
JRuby and Rubinius.”[ruby-core:55053] [ruby-trunk - Feature #8426][Open]
Implement class hierarchy method cachingby Charlie Somerville

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

91

Sophisticated inline cacheinvalidation mechanism•Invalid only sub-classes under effective class
ObjectRedefine X,
invalidate X and
X’s subclasses

X

X1

Y

X2

Z

Z1

Z2

X1a
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

92

Memory efficient string management•Each string has their string body (spaceacquired by malloc())
String“String body”
ptr

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

93

Memory efficient string management•For some strings have same “string body”,
they has own string body each other.
StringStringStringStringStringString

ptr
ptr
ptr
ptr
ptr
ptr

“String body”“String body”“String body”“String body”“String body”“String body”

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

94

Memory efficient string management•It can be shared by strings w/ dirty bit.
StringStringStringStringString→ Reduce memory consumption!!
“String body”(shared by 5 places)

ptr
ptr
ptr
ptr
ptr

† Sharing string body is implemented now
if a string object is duped.
This technique is more aggressive approach.
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

95

Memory efficient string management•This mechanism can work with Symbol
management
StringStringStringStringString→ GC-able Symbol“String body”(shared by 5 places)

ptr
ptr
ptr
ptr
ptr

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

96

Quoted “2.1”“2:1 And the heavens and the earth were finished,
and all the host of them.”- Genesis“2:1 こうして天と地と、その万象とが完成した。”
- 創世記

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

97

Agenda• Ruby 2.1 Schedule• Ruby 2.1 new “internal” features• Internal object management hooks• Object allocation tracing• GC hooks• RGenGC: Restricted Generational Garbage
Collection ← Today’s main topic• Ruby 2.1 expected “internal” features• Sophisticated inline cache invalidation mechanism• Memory efficient string management• Useful debugger
RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

98Summary•We are implementing new features andimproving Ruby’s quality for Ruby 2.1•Especially introducing “Generational garbage
collector” which I’m working on will improvehuge performance•Ruby 2.1 is currently scheduled on Dec 25,
2013

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

99

Thank you
Any questions?
Koichi Sasada
Heroku, Inc.
<ko1@heroku.com>

RubyKaigi 2013 Toward efficient Ruby 2.1 by Koichi Sasada

100