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

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

1

Agenda• Ruby’s rough history• 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• Parallel sweeping• Sophisticated inline cache invalidation mechanism• Memory efficient string management
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada2About this presentation• This presentation is advanced version of my lastpresentation at RubyKaigi 2013 (May)• Talked in Japanese (with English slides)• Recycle presentation (≒ Good lazy programmer)

Slide PDF is http://rvm.jp/t.pdf(temporary URL)

• I’m poor at English speaking• All contents I want to say are written in my slides• Please give me a question with slow/clear/easy English Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

3

This presentation is NOT about•Not about Rails application development•Not about Programming language design•Not about Mathematics•Not abou Functional programming languages•Not about Ruby programming language
Mainly about C programming language
because it is about “C”Ruby
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

4Who am I ?
• Koichi Sasada a.k.a ko1• 笹田耕一 in Kanji character• Japanese lesson: “1”• One in English• Mono in Greece• Eins in German• Un in French• Uno in Italian, Spanish• “Ichi” (“一” in Kanji) in Japanese• I’m the first son of my parents
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

5

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

6Matz team in Heroku

Nobu @ Tochigi
Patch monster

Matz @ Shimane
Title collector

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

ko1 @ Tokyo
EDD developer
7Matz team at Heroku
HierarchyMatz @ Shimane
Title collector

ko1 @ Tokyo
EDD developer

Communication
with Skype

Nobu @ Tochigi
Patch monster

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

8

Matz
Title collector• He has so many (job) title• Chairman - Ruby Association• Fellow - NaCl
• Chief architect, Ruby - Heroku• Research institute fellow – Rakuten• Chairman – NPO mruby Forum• Senior researcher – Kadokawa Ascii Research Lab• Visiting professor – Shimane University• Honorable citizen (living) – Matsue city
• Honorable member – Nihon Ruby no Kai•…

• This margin is too narrow to containEuruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

9

Nobu
Patch monster•Great patch creator

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

10

Nobu
Patch monster
Commit number per day
80
60
40
20
0
2008/7/1 2009/7/1 2010/7/1 2011/7/1 2012/7/1
Total
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

Trunk, Last 5 year
11

Nobu
Patch monster
Commit number per day
80
60
40
20
0
2008/7/1 2009/7/1 2010/7/1 2011/7/1 2012/7/1
Total

matz

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

Trunk, Last 5 year
12

Nobu
Patch monster
Commit number per day
80
60
40
20
0
2008/7/1 2009/7/1 2010/7/1 2011/7/1 2012/7/1
Total

matz

ko1

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

Trunk, Last 5 year
13

Nobu
Patch monster
Commit number per day
80
60
40
20
0
2008/7/1 2009/7/1 2010/7/1 2011/7/1 2012/7/1
Total

nobu

matz

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

ko1

Trunk, Last 5 year
14

Nobu
Patch monster
nagachika
embossshyouhei
mrkn
ayuminxibbarshirosaki
kou
ryan
nari
nahi
suke
wanabetaruisorah
charliesom
ktsj
nagai
ngoto
eregonluislavena
takano32
duerstkeiju
davidflanag
mneumannkanemoto
technoramazav
iwamatsu
murakenkouji
gotoyuzo
zsomborgsinclair
headiusakiyoshigotokenntalbottaaminejeg2
arton
kosakouema2
glassmichaldblacktmm1
shigek
eban
ocean
seki
ksaito
okkez
katsu
hsbt
siena
akira
evan
ttate
dave
wew
why
jim
ser
knu
shugo
zzak
1%
1%
1%
1%
1%
0%
1%
0%
0%
0%
0%
0%
0%
0%
0%
0%
0%
0%
0%
0%
e0%
0%
0%
0%
0%
an
a
yugui
1%
1%
marcandre
0%0%1%
tenderlove
2%
2%kazu
tadf
2%
mame
2%
matz
2%
3%
kosaki3%drbrain
3% ko1svn
3%usanaruse
4% 8%
9%Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

nobu
28%

akr
13%
Trunk, Last 5 year
15

Ko1
EDD developer
25

EurukoRubyKaigi

20
Ruby 2.0

15
RubyConf

10
5
0

EDD: Event Driven Development
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

16

Brief history of Ruby

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

17

Brief history of Ruby
1993 2/24
Birth of Ruby
(in Matz’ computer)2013/02
1996/12Ruby 1.0

1995/12Ruby 0.95

1999/12Ruby 1.4

1998/12Ruby 1.2

2003/8Ruby 1.8

2000/6
Ruby 1.6

Ruby 20th &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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

18

Brief history of Ruby
A.D. 330
Constantinople
foundedA.D. 1453
2013/02
The fall ofRuby 20th &Constantinople Ruby 2.0.0
A.D. 1821
The Greek War
of Independence

B.C. 490
Battle of Marathon
B.C. 431
Peloponnesian War“20 years” is not so long!
(compare with Greece history)
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

19ISO Ruby Standard• Published at 2012/04• ISO/IEC 30170:2012 Information technology -Programming languages – Ruby
• http://www.iso.org/iso/iso_catalogue/catalogue_ics/
catalogue_detail_ics.htm?ics1=35&ics2=060&ics3=&
csnumber=59579“ISO/IEC 30170:2012 specifies the syntax andsemantics of the computer programming language
Ruby, and the requirements for conforming Ruby
processors, strictly conforming Ruby programs, andconforming Ruby programs.”• Hybrid 1.8 and 1.9• Difference parts are “undefined”
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

20

Ruby 2.0
Stable version

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

21

Ruby 2.0
•New features• Keyword arugments• Refinements• Module#prepend•Ruby 2.0.0-p195p247 was already released

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada22

# -*- 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

are introduced for easy detection of available
constants on a

* GC

* improvements:* added Range#size for lazy size evaluation.

* LoadError* added method:=== C API updates* added Range#bsearch for binary search.

* change return value:* introduced the bitmap marking which
suppresses to copy a memory page

with Copy-on-Write.

transcodes to Encoding.default_internal if it is* new methods:* tmpdir* new methods:* incompatible changes:* Resolv::DNS#timeouts=* OpenSSL::OPENSSL_FIPS allows client
applications to detect whether OpenSSL* Dir.mktmpdir uses FileUtils.remove_entry
instead of* Signal.trap* Resolv::DNS::Config#timeouts=

is running in FIPS mode and to react to thespecial requirements this* Net::IMAP.default_port

might impy.

* TracePoint* Module* resolv

set.

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

* SSL/TLS support for the Next Protocol
Negotiation extension. Supportedwith OpenSSL 1.0.1 and higher.
* Time#to_s returned encoding defaults to USASCII but automatically* Signal

loaded.

works because str.lines returns an array. Replacelines withlong.

NEWS file of Ruby 2.0* added LoadError#path method to return thefile name that could not be* added Signal.signame which returns signal
name* 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.

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

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

changes in rdoc 4.0.

* Time* added method:== Changes since the 1.9.3 releaseprivate 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")* Iconv has been removed. Use String#encode
instead.

* Struct* Enumerator* added Kernel#caller_locations which returns
an array of* Mutex* added Struct#to_h returning values with keys
corresponding to the* 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.

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

* Thread* 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. ThisSee above.
See above.

also allows to programmatically decline (client)
renegotiation attempts.

* shellwords* rdocEuruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

23

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

24

Ruby versions•Which version of Ruby (MRI) do you use?
1. Ruby 1.8.7
2. Ruby 1.9.2
3. Ruby 1.9.3
4. Ruby 2.0.0 p0
5. Ruby 2.0.0 p195
6. Ruby 2.0.0 p247

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

25

PR

Ruby 2.0.0 is default at Heroku

https://blog.heroku.com/archives/2013/6/17/ruby-2-default-new-aps
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

26

Rubyist Magazine
Ruby 2.0 Special articles

http://magazine.rubyist.net/?Ruby200SpecialEn
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

27

Ruby 2.1
Next version

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

28

Ruby 2.1 release plan announcement“I, Naruse, take over the release manager of Ruby
2.1.0 from mame. Ruby 2.1.0 is planed to releasein 2013-12-25. 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-core:54726] Announce take over the
release manager of Ruby 2.1.0
by NARUSE, Yui
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada29

2013/12/25!

http://www.flickr.com/photos/htakashi/5285103341/ by Takashi Hososhima
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

30

Ruby 2.1 schedule
2013/02
Ruby 2.0.0

RubyKaigi2013
5/30, 31, 6/1

We arehere!

Euruko2013
6/28, 29

2013/12/25
Ruby 2.1.0

RubyConf2013
11/8-10

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

31

Ruby 2.1 release plan announcement“I, Naruse, take over the release manager of Ruby
2.1.0 from mame. Ruby 2.1.0 is planed to releasein 2013-12-25. 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-core:54726] Announce take over the
release manager of Ruby 2.1.0
by NARUSE, Yui
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

32

Ruby 2.1 schedule (more)
We arehere!

RubyConf2013
11/8-102013/07
Dev-meeting
w/Matz2013/06
Call for Feature
Proposal (CFP)

2013/10Preview1
2013/09
Feature freeze

2013/12/25
Ruby 2.1.0

2013/12RC
2013/11
Preview2

https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/ReleaseEngineering210
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

33

Ruby 2.1 schedule (more^2)
2013/12/25
Ruby 2.1.0

B.C. 490
Battle of Marathon

A.D. 1453
The fall ofConstantinople

B.C. 431
Peloponnesian War
A.D. 330
Constantinople
foundedWe arehere!

A.D. 1821
The Greek War
of Independence

Ruby 2.1 will be release Immediately!
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

34

Ruby 2.1
•New features

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada35

# -*- 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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

36

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

• I heard Matz has some ideas.

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

37

Back to Ruby 2.0

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

38

Quote about Ruby 2.0 from Heroku blog

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

39

Me!

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

40

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

41

Mention about “Speed” of 2.0
Ruby 2.0 has a faster garbage collector and is Copy on Write
friendly. Copy on Write or COW is an optimization that can
Short summary:uses whenbitmapreduce the memory footprintof a RubyGC
process
it ismarking
and memory
CoW friendly
copied. Instead of allocating
duplicatewhen aprocess is forked, COW allows multiple processes to sharethe same memory until one of the processes needs tomodify a piece of information. Depending on the program,
this optimization can dramatically reduce the amount ofmemory 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.
Short summary:Let’s
try Unicorn!
If you’re not already runninga concurrent
backendconsidertrying the Unicorn web server.
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

42

Only mention about GC?
I DON’T work on GC!
People love GC performance

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada43｡+.｡ヽ(*>∀<*)ﾉ｡.+。
Let’s consider about
GC/memory management!

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

44

Ruby 2.1 development

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

45

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

Today’s topic

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

46

Ruby 2.1
Internal hooks for memory management

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

47

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

48

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

49

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

50

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
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

51

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
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

52

Ruby 2.1
RGenGC: new garbage collection

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

53

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.
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

54

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

55

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

56

GC Lecture

RGenGC: BackgroundMark & Sweep
Root objects
traverse
freemarkedtraverse

traverse

markedtraverse

markedmarkedtraversefree

1. Mark reachable
objects from rootobjects
2. Sweep unmarked
objects (collection
and de-allocation)

Collect unreachable
objects

markedfree
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

57

GC Lecture

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 n-th 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)
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

58

GC Lecture

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

59

GC Lecture

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

Root objects
traverse

new/
free

new
old
traverse

traversenew/freecollectnewoldtraverse
new
old

new
old
traverse
newold• Mark and promote to oldgeneration• 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.
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

60

GC Lecture

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 oldgeneration• 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.
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

61

GC Lecture

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
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

62

GC Lecture

RGenGC: Background: GenGC
Problem: mark missRoot objects
traverse
new
traverse• Old objects refer young objects→ Ignore traversal of old object→ Minor GC causes
marking leak!!
• Because minor GC ignoresreferenced objects by old objects

oldignoreignoreCan’t mark new object!
old

old
old

ignore→ Sweeping living object!
(Critical BUG)

new
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

63

GC Lecture

RGenGC: Background: GenGC
Introduce Remember set (Rset)
Root objects
traverse
new
traverse
oldignoreignore

old

old
old

Rememberset (RSet)

1. Detect creation of an[old->new] typereference
2. Add an [old object]
Remember
into Remember set(RSet) if an old objectrefer new objects

newEuruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

64

GC Lecture

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

Root objects
traverse
new
traverse
oldignoreignore

old

old
old

traverse
traverse

collect
new/
new/
free
free

1. Mark reachable
objects from rootobjects• Remembered objects
are also root objects

2. Sweep not (marked
or old) objects

newEuruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

65

GC Lecture

RGenGC: Background: GenGC
Write barrier•To detect [old→new] type references, weneed to insert “Write-barrier” into
interpreter for all “Write” operation

old

new

“Write barrier”[Old->New] type reference
Detected!
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

66

GC Lecture

RGenGC: Background: GenGC
Write barriers in Ruby
•Write barrier (WB) example in Ruby world• (Ruby) old_ary[0] = new0 # [old_ary → new0]• (Ruby) old_obj.foo = new1 # [old_obj → new1]
old_ary0

old_obj
new0

1

foo

2

bar

new1

3
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

67

GC Lecture

RGenGC: Background
Difficulty of inserting write barriers•To introduce generational garbage collector,
WBs are necessary to detect [old→new] typereference•“Write-barrier miss” causes terrible failure
1. WB miss
2. Remember-set registration miss
3. (minor GC) marking-miss
4. Collect live object → Terrible GC BUG!!

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

68

RGenGC: Problem
Inserting WBs into C-extensions (C-exts)• All of C-extensions need perfect Write-barriers• C-exts manipulate objects with Ruby’s C API• C-level WBs are needed• Problem: How to insert WBs into C-exts?

• There are many WB required programs in C-exts• Example (C): RARRAY_PTR(old0)[0] = new1
• Ruby C-API doesn’t require WB before• CRuby interpreter itself also uses C-APIs• How to deal with?

• We can rewrite all of source code of CRuby interpreter to
add WB, with huge debugging effort!!
• We can’t rewrite all of C-exts which are written by 3rd
party
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

69

RGenGC: Problem
Inserting WBs into C-extensions (C-exts)
Two options
Performance

Compatibility

1

Give up GenGC

Poor

Good
(No problem)

2

GenGC with rewriting all of C exts

Good

Most of C-exts
doesn’t work

Current
conservative

choiceTrade-off of Speed and Compatibility
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

70

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)
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

71

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

72

RGenGC: Challenge•Trade-off of Speed and Compatibility• Can we achieve both speed-up w/ GenGC andkeeping compatibility?

•Several possible 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
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

73

RGenGC: Our approach•Create new generational GC algorithm
permits WB protected objects AND WB unprotected object in the same heap

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

74

RGenGC: Invent 3rd option
1

Give up GenGCGenGC with re2
writing all of C codes3

Use new RGenGC

Performance

Compatibility

Poor

Good
(No problem)

Good

Most of C-exts
doesn’t work

Good

Most of C-exts
works!!

Ruby 2.1
choiceBreaking the trade off. You can praise us!!
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

75

RGenGC:
Key idea•Introduce Shady object• I use the word “Shady” asquestionable, doubtful, …
• Something feeling dark
• 日陰者, in Japanese

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

76

RGenGC:
Key Idea•Separate objects into two types Shady: doubtful,• Normal Object: WB Protected• Shady Object: WB Unprotected

Normal＼（＾o＾）／

questionable, ...

Shady（´･ω･`）•We are not sure that a shady object points
new objects or not•Decide this type at creation time
• A class care about WB → Normal object• A class don’t care about WB → Shady object
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

77

RGenGC:
Key Idea•Normal objects can bechanged to Shady objects

VM
Create• “Shade operation”• C-exts don’t care about WB,
objects will be shady objects
Shade• Example
NormalShady• ptr = RARRAY_PTR(ary)obj
obj• In this case, we can’t insert WB for
ptr operation, so VM shade “ary”

Now, Shady object can’tchange into normal object
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

78

RGenGC
Key Idea: Rule
•Treat “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 normal objects
1. Demote objects
2. Remember shaded shady objects

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

79

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

Root objects

Rememberset (RSet)traverse
remembernewoldcollect
new/
new/
free
free

traverse
newoldtraverse
new
old

old

traverse
shadymark 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!!

oldnew
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

80

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

Root objects

Rememberset (RSet)traverse

oldcollect
new/
new/
free
free

ignoreoldignoreignoretraverse

shady

old

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
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

81

RGenGC[Shade operation]
Rememberset (RSet)
old

old

Shady
old

new

•Anytime Object can give up to
keep write barriers→ [Shade operation]•Change old normal objects toshade objects• Example: RARRAY_PTR(ary)(1) Demote object (old → new)(2) Register it to Remember Set

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

82

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)Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

83

RGenGC
Number of objects
2.0.0 GC (M&S)# of Living objects

w/RGenGC (Minor GC)# of Living objects# of old
objects(#old)(c)# of Freed objects

(a)

(b)
# of Freed objects# of freed# of newobjects (#new) but remembered (a) # of old objects by WB(b) # of shady objects pointed by old
objects(c) # of old but shady objects
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

84

RGenGC
Number of objects(a)w/RGenGC (Minor GC)# of Living objects# of old
object(#old)(c)(b)# of Freed object# 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

Mark&Swep GC# of Living objects

0

Full heap

Traditional GenGC#new + (a)

(a)

#new

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

85

RGenGC
Discussion: Pros. and Cons.
•Pros.
• Allow WB unprotected objects (shady objects)• 100% compatible w/ existing extensions which don’t care about WB• A part of CRuby interpreter which doesn’t care about WB• 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 (effective) classes/methods.
• We can ignore minor classes/methods.

• Simple algorithm, easy to develop (already done!)

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

86

RGenGC
Discussion: Pros. and Cons.
• Cons.

• Increasing “unused, but not collected objects until
full/major GC• Remembered normal objects (caused by traditional GenGC algorithm)• Remembered shady objects (caused by RGenGC algorithm)• WB insertion bugs (GC development issue)• RGenGC permit shady objects, but sunny objects need correct/perfect
WBs. But inserting correct/perfect WBs is difficult.
• This issue is out of scope. We have another idea against this problem(out of scope).

• Can’t reduce Sweeping time

• But many (and easy) well-known techniques to reduce sweeping time(out of scope).

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

87

RGenGC
Implementation: WB support status
Type name

Status

T_OBJECTSupported

T_CLASS

Supported

Possible to change into shady

T_ICLASS

Supported

Possible to change into shady

T_MODULE

Supported

Possible to change into shady

T_FLOAT

Supported

T_STRING

Supported

T_REGEXP

Supported

T_ARRAY

Supported

Possible to change into shady / more efforts are needed

T_HASH

Supported

Possible to change into shady

T_STRUCT

Supported

T_BIGNUM

Supported

T_FILE

Unsupported

T_DATA

Supported

T_MATCH

Unsupported Most of MatchData objects are short-lived

T_RATIONAL

Supported

T_COMPLEX

Supported

T_NODE

Comment

Only InstructionSequence objects are supported

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

Unsupported Most of Node objects are short-lived

88

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
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

89

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
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

90

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).
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

91

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.

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

92

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
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

93

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

94

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

Execution time by RDTSC

500000000

400000000

mark (RGENGC)
sweep (RGENGC)

300000000

mark
200000000

sweep

Good marktime 
100000000

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi SasadaSame sweep
time 
95

RGenGC
Performance evaluation (RDoc)
450

Several major/full
GC peaks

350
300

Mark Time (ms)250

Sweep Time (ms)200

RGenGC: Mark Time (ms)150
Faster minor

100

RGenGC: Sweep Time (ms)

GC

50
0

Total GC countis different* Disabled lazy sweep
to measure correctly.

1
19
37
55
73
91
109
127
145
163
181
199
217
235
253

Execution time (ms)400

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

96

Accumulated execution time(ms)

RGenGC
Performance evaluation (RDoc)
45000
40000
35000
30000
25000
20000
15000
10000
5000
0

About x7 speedup!

Mark Time (ms)M&S

Sweep Time (ms)RGenGC* Disabled lazy sweep to measure correctly.

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

97

RGenGC
Performance evaluation (RDoc)
Total execution time (sec)

200
150

About 20% speedup!
48.71345729
14.9694922

100
136.613831

136.5777977

M&S

RGenGC50

0
Exec time (sec)

GC time (sec)* Disabled lazy sweep to measure correctly.

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

98

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

99

RGenGC
Future work
•Minor GC / Major GC timing tuning• Too many major GC → slow down
• Too few major GC → memory consumption issue•Inserting WBs w/ application profiling• Profiling system• Benchmark programs•Debugging/Detecting system for WBs bugs
•Improve sweeping performance
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

100

Ruby 2.1
Other internal features

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

101

Ruby 2.1 expected “internal” features• Parallel sweeping• 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• Inlined Proc.call invocation• AOT Compiler and extending “require” behavior• Useful debugger
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

102

Parallel sweeping
Background•RGenGC improve performance only for“marking” phase•RGenGC doesn’t improve “sweeping phase”
performance

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada103

Accumulated execution time(ms)

Parallel sweeping
Background (revisit Rdoc evaluation)
45000
40000
35000
30000
25000
20000
15000
10000
5000
0

Almost same

Mark Time (ms)M&S

Sweep Time (ms)RGenGC

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

104

Parallel sweeping
Background (revisit 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)Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

105

Parallel sweeping
Introduce sweeping threads (ideal)
w/RGenGC (Minor GC)
RubyMark Sweep

Sweep

Sweep

Sweep

Sweep

Stop the(Ruby)
World

w/RGenGC (Minor GC) w/Parallel sweeping
Ruby

Mark Sweep

Stop the(Ruby)
World

Sweeping thread

Sweep in parallel

Wait for next GC

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

106

Parallel sweeping
Ideal•Hide most of sweeping time

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

107

Parallel sweeping
Real•Increase synchronization cost
•Increase program complexity•Our preliminary evaluation (implemented in
one night, buggy one) doesn’t show goodscore
•To be continued…
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

108

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
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

109

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

X

X1

Y

X2

Z

Z1

Z2

X1a
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

110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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

111

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
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

112

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

113

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”

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

114

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.
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

115

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

116

Questions and answers

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

117

Questions and Answers
RGenGC and CoW friendly•No problem because only touch flags foroldgen and shadyEuruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

118

Questions and Answers
GC + Threads•Parallel GC• Run GC process in parallel (simultaneously)• Parallel marking• Parallel sweeping (in today’s talk)•Concurrent GC / Incremental GC• Run ruby threads (mutator threads) and GC threads
concurrently• Major GC consumes huge time (same as currentGC) → Need concurrent GC to reduce pause time
• New WB API is also designed for concurrent GC
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

119Agenda• Ruby’s rough history• 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• Parallel sweeping• Sophisticated inline cache invalidation mechanism• Memory efficient string management
Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

120Summary•We are implementing new features andimproving Ruby’s quality for Ruby 2.1•Especially introducing new “Generational
garbage collector” will achieve huge
performance improvement•Ruby 2.1 is currently scheduled on Dec 25,
2013. Don’t miss it!

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

121

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

Euruko 2013 Toward more efficient Ruby 2.1 by Koichi Sasada

122