Ruby 2.1 のすべて
Koichi Sasada
Heroku, Inc.
ko1@heroku.com

tochigirubykaigi05 2013/09/21

1About this presentation• In this presentation, I will show you about Ruby 2.1
which I know.

tochigirubykaigi05 2013/09/21

2

Ruby 2.1 release planannouncement“I, Naruse, take over the release manager of Ruby 2.1.0
from mame. Ruby 2.1.0 is planed to release in 2013-1225. I‘m planning to call for feature proposals soon like
2.0.0 [ruby-core:45474], so if you have a suggestion youshould begin preparing the proposal.”- [ruby-core:54726] Announce take over the releasemanager of Ruby 2.1.0
by NARUSE, Yuitochigirubykaigi05 2013/09/21

3

2013/12/25!

http://www.flickr.com/photos/htakashi/5285103341/ by Takashi Hososhimatochigirubykaigi05 2013/09/21

4

Ruby 2.1 schedule (more)
We arehere!

RubyConf2013
11/8-102013/7, 8, 10
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/10Preview2

https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/ReleaseEngineering210
tochigirubykaigi05 2013/09/21

5

Ruby 2.1 Changes• Syntax changes• Required keyword argument• “r”, “i”, “f” suffix• “def” sentence returns a symbol of method name• Runtime changes• String#scrub• Object tracing• Refinement is no longer experimental features• Performance improvements• RGenGC: Generational GC• klasscache - the class hierarchy invalidation patch• Other changes
tochigirubykaigi05 2013/09/21

6

Syntax
Required keyword argument• “Keyword argument” from Ruby 2.0 is a alternativeof optional argument• def foo(foo=1, bar: 2); end• foo(); foo(100); foo(100, bar: 200) # OK

• “Required keyword argument” is a not optional
keyword argument• def foo(foo=1, bar: ); end• foo(); foo(100); # NG: missing keyword: bar• foo(100, bar: 200) # OKtochigirubykaigi05 2013/09/21

7

Syntax“r” suffix for Rational numbers• To represent ½, in Ruby “Rational(1, 2)”→ Too long!!
• Introduce “r” suffix½ → 1/2r• “[digits]r” represents “Rational([digits], 1)”• 1/2r #=> 1/Rational(2, 1)• 1/Rational(2, 1) #=> Rational(1/2)

tochigirubykaigi05 2013/09/21

8

Syntax“i” suffix for Complex numbers• We already have “Integer#i” method to makeimaginary number like “1+2.i”• We already introduced “r” suffix for Rational→ No reason to prohibit “i” suffix!!
• [digits]i represents “Complex(0, [digits])”• 1+2i #=> 1+Complex(0, 2)• 1+Complex(0, 2) #=> Complex(1, 2)• You can mix “r” and “i” suffix
tochigirubykaigi05 2013/09/21

9

Syntax“f” suffix for String• String literal “foo” creates new objects each time• 10.times{p “foo”.object_id} #=> show different objects• To support mutable strings• “foo”f (‘f’ suffix) creates same/frozen string• 10.times{p “foo”f.object_id} #=> show only one object id• Aggregate same frozen strings• p(“foo”f.object_id, “foo”f.object_id) #=> same object id• Mainly for performance• Target is framework such as ERb, etc
tochigirubykaigi05 2013/09/21

10Syntax“def” returns a name symbol• p(def foo; end) #=> nil @Ruby 2.0 and before• p(def foo; end) #=> :foo @Ruby 2.1• Usecase• private static void def main(args) …; end

tochigirubykaigi05 2013/09/21

11

Runtime changes
String#scrub• Problem: How to verify/fix invalid byte sequence?
• From Ruby 2.1, we introduce two methods“String#scrub” and “String#scrub!” to verify and fix
invalid byte sequence.

tochigirubykaigi05 2013/09/21

12

Runtime changes
Object tracing• 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}

tochigirubykaigi05 2013/09/21

13

Performance improvement
RGenGC: Generational GC• Issue: M&S is slow
• Issue: Introducing generational GC causes serious
compatibility problem• Proposal: Introduce new GC algorithm RGenGC(Restricted Generational GC) without compatibilityproblem

tochigirubykaigi05 2013/09/21

14Performance improvement
Current GC: Mark & Sweep
Root objects
traverse
freemarkedtraverse

traverse

markedtraverse

markedfree

1. Mark reachable
objects from rootobjects
2. Sweep unmarked
objects (collection andde-allocation)markedtraverse

Collect unreachable
objects

markedfree
tochigirubykaigi05 2013/09/21

15

RGenGC: Background
Generational GC (GenGC)

GC Lecture• Weak generational hypothesis: Most objects die young →Concentrating reclamation effort on the youngest 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)

tochigirubykaigi05 2013/09/21

16

GC Lecture

RGenGC: Background
Difficulty of inserting write barriers• To introduce generational garbage collector, WBs arenecessary to detect [old→new] type reference• “Write-barrier miss” causes terrible failure
1.
2.
3.
4.

WB miss
Remember-set registration miss(minor GC) marking-missCollect live object → Terrible GC BUG!!

tochigirubykaigi05 2013/09/21

17

Performance improvement
RGenGC: Generational GC• RGenGC: Restricted Generational GC• New GC algorithm allows mixing “Write-barrierprotected objects” and “WB unprotected objects”• No (mostly) compatibility issue with C-exts• Inserting WBs gradually• We can concentrate WB insertion efforts for majorobjects 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 unprotectedobjects (called as Shady objects), so existing codes still works.
tochigirubykaigi05 2013/09/21

18

Performance improvement
klasscache: the class hierarchy invalidation• Invalidate all classes’ method cache
ObjectRedefine X,invalidate all ofclasses

X

X1

Y

X2

Z

Z1

Z2

X1a
tochigirubykaigi05 2013/09/21

19

Performance improvement
klasscache: the class hierarchy invalidation“This patch adds class hierarchy method caching toCRuby. This is the algorithm used by JRuby andRubinius.”[ruby-core:55053] [ruby-trunk - Feature #8426][Open]
Implement class hierarchy method cachingby Charlie Somervilletochigirubykaigi05 2013/09/21

20

Performance improvement
klasscache: the class hierarchy invalidation• Invalid only sub-classes under effective class
ObjectRedefine X,
invalidate X andX’s subclasses

X

X1

YX2

Z

Z1

Z2

X1a
tochigirubykaigi05 2013/09/21

21

Planned changes• Sophisticated Symbol management• Collectable symbols

tochigirubykaigi05 2013/09/21

22

Current symbol management (-Ruby 2.0.0)

Heap
global_symbols

T_STRING“foo”

last_id

T_STRING

ID

sym_id“foo”

0x123id_str
op_syms[]

“bar”

0x456

…

…

ID

T_STRING

0x123

“foo”

0x124

“bar”

…

…

T_STRING“bar”

tochigirubykaigi05 2013/09/21

rb_intern(char *cstr, enc) {/* pseudo code */str = make_fake_str(cstr, enc)
if (st_lookup(sym_id, str, &id)) { return id }else {
str = make_true_str(cstr, enc);
ID id = last_id++;st_insert(sym_id, cstr, id)
st_insert(id_str, id, cstr)}

23

Proposed symbol management v4 (Ruby 2.1.0-)
ID storage
last_id
imm_tblid_strmark_tbl

ImmStrInterned Symbol“foo”
VALUE: ID2SYM(0x123)

Heap
Frozen String“foo”
VALUE: 0x788“foo” (0x788)“bar” (0x789)“baz” (0x790)

ID

Str

Frozen String“bar”
VALUE: 0x789

null

Frozen String“baz”
VALUE: 0x790

0x123
0x124
0x790

Imm_strshare0x791
Dynamic Symbol“baz”
VALUE: 0x791

ID

VALUE
flags:
HAS_ID,
HAS_FSTR,
HAS_DSYM…

Interned Symbol“baz”
VALUE: 0x791

tochigirubykaigi05 2013/09/21

24

Summary• Schedule: Release at 2013/12/25• Preview1 2013/10• Preview2 2013/10 with feature freeze• Preview3 ?
• Release candidate 2013/12/11• Release 2013/12/25• New features• Performance improvement• https://bugs.ruby-lang.org/projects/rubytrunk/wiki/ReleaseEngineering210
tochigirubykaigi05 2013/09/21

25

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

tochigirubykaigi05 2013/09/21

26