SlideShare ist ein Scribd-Unternehmen logo
1 von 121
Rubinius
     Use Ruby
Dirkjan Bussink
   d.bussink@gmail.com
2008
Dynamic
  vs.
 Static
x = 10
      x = 'a'

int x    = 10
string x = 'a' => ERROR
Strong
  vs.
Weak
x = 10
y = "20"

x + y

# Javascript
=> 1020

# PHP
=> 30
Ruby
puts "Hello world!"
class MyAwesomeObject

  def initialize
    puts "Running constructor"
  end

  def cool_method(arg1, arg2)
    arg1 + arg2
  end

end
[1, 2, 3, 4].each do |e|
  puts e
end
module Person
  def name
    puts "Every person has name"
  end
end

class Student
  include Person
end

Student.new.name
Rubinius
Virtual Machine
Kernel
2006

Evan Phoenix
 Brian Ford
Virtual Machine
C++
Ruby
0000:   meta_push_0
                    0001:   set_local           0    # i
                    0003:   pop
                    0004:   push_local          0    # i
                    0006:   push_literal        1000
                    0008:   meta_send_op_lt     :<
                    0010:   goto_if_false       23
i = 0
                    0012:   push_local          0    # i
while i < 1000 do   0014:   meta_push_1
  i = i + 1         0015:   meta_send_op_plus   :+
                    0017:   set_local           0    # i
end                 0019:   pop
                    0020:   check_interrupts
                    0021:   goto                4
                    0023:   push_nil
                    0024:   pop
                    0025:   push_true
                    0026:   ret
Fancy
class Person {
  read_write_slots: ['name, 'age, 'city]

    def initialize: @name age: @age city: @city {
    }

    def go_to: city {
      if: (city is_a?: City) then: {
        @city = city
      }
    }

    def to_s {
      "Person: #{@name}, #{@age} years old, living in #{@city}"
    }
}
JavaScript
JavaScript
Python
JavaScript
Python
Brainfuck
Ruby in Ruby
def each
  return to_enum(:each) unless block_given?

 i = @start
 total = i + @total
 tuple = @tuple

  while i < total
    yield tuple.at(i)
    i += 1
  end

  self
end
Ruby for Rubyists
Improve
everything
Compiler
class FixnumLiteral < NumberLiteral
  def initialize(line, value)
    @line = line
    @value = value
  end

  def bytecode(g)
    pos(g)

    g.push @value
  end

  def defined(g)
    g.push_literal "expression"
  end
end
Ruby is slow!
Flexibility
class Array
  def sum
    inject(0) {|total, e| total + e.to_i}
  end
end
class Bignum
  def +(other)
    self - other
  end
end
"The edges of the sword are life and death,
      no one knows which is which"
      Ikkyu Sojun, 15th Century Zen master
Hard, but not
 impossible
Inline caching
p = Person.new
...
p.name
class Person
  def name
    "me"
  end
end
module Named
                 def name
class Person
                   "named"
  def name
                 end
    "me"
               end
  end
               class Person
end
                 include Named
               end
module Named
                 def name        class Person
class Person
                   "named"       end
  def name
                 end
    "me"
               end               def p.name
  end
               class Person        "specific"
end
                 include Named   end
               end
class Person
  attr_accessor :name
end

10000.times do
  p = Person.new
  p.name
end
There are only two hard
problems in Computer Science:
       cache invalidation,
         naming things
     and off-by-one errors
module Naming
  def name
    "me2"
  end
end

class Person
  include Naming
end

10000.times do
  p = Person.new
  p.name
end
module Naming
  def name
    "me2"          class Person
  end                def name
end                    "new_name"
                     end
class Person       end
  include Naming
end                10000.times do
                     p = Person.new
10000.times do       p.name
  p = Person.new   end
  p.name
end
p = OtherObject.new
...
p.name
JIT
“...we finally managed to get our Linux (...) builds to use
  GCC 4.5, ... and profile guided optimization enabled”
                            Mike Hommey - on Firefox 6 performance
def method1
  1 + 1
end

def method2
  2 + 1
end

10000.times do
  method1
end
members of rubinius::VMMethod:
total_args = 0,
call_count = 21,
llvm_function_ = 0x0,
name_ = 0x6306,
static const int default_jit_call_til_compile = 4000;
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $10, -4(%ebp)
leal -4(%ebp), %eax
addl $66, (%eax)
leave
ret
#include <stdio.h>

int func() {
    int i = 0;
    i += 10;
    return i;
}
; ModuleID = '<stdin>'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-
i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-
v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
target triple = "x86_64-apple-darwin10.7"

define i32 @func() nounwind ssp {
entry:
  %retval = alloca i32
  %0 = alloca i32
  %i = alloca i32
  %"alloca point" = bitcast i32 0 to i32
  store i32 0, i32* %i, align 4
  %1 = load i32* %i, align 4
  %2 = add nsw i32 %1, 10
  store i32 %2, i32* %i, align 4
  %3 = load i32* %i, align 4
  store i32 %3, i32* %0, align 4
  %4 = load i32* %0, align 4
  store i32 %4, i32* %retval, align 4
  br label %return

return:                                           ; preds =
%entry
  %retval1 = load i32* %retval
  ret i32 %retval1
}
; ModuleID = '<stdin>'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-
i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-
v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-
n8:16:32:64"
target triple = "x86_64-apple-darwin10.7"

define i32 @func() nounwind readnone ssp {
entry:
  ret i32 10
}
Go JIT!


  RBX                      LLVM
thread(s)                 thread
            Here it is!
members of rubinius::VMMethod:
total_args = 0,
call_count = 21,
llvm_function_ = 0x102c07b30,
name_ = 0x6306,
Code inlining
array = [1] * 1000000

array.each do |element|
  puts "element: #{element}"
end
def method1
  1 + 1
end

def method2
  method1
end

100.times do
  method2
end
def method1    def method1
  1 + 1          1 + 1
end            end

def method2    def method2
  method1        method1
end            end

100.times do   100.times do
  method2        method1
end            end
def method1    def method1
  1 + 1          1 + 1
end            end

def method2    def method2
  method1        method1
end            end

100.times do   100.times do
  method2        method1
end            end
def method1    def method1    def method1
  1 + 1          1 + 1          1 + 1
end            end            end

def method2    def method2    def method2
  method1        method1        method1
end            end            end

100.times do   100.times do   100.times do
  method2        method1        1 + 1
end            end            end
def method1    def method1    def method1
  1 + 1          1 + 1          1 + 1
end            end            end

def method2    def method2    def method2
  method1        method1        method1
end            end            end

100.times do   100.times do   100.times do
  method2        method1        1 + 1
end            end            end
def awesome(x)
  return 0 if x == 0
  x + 1
end

def   use_awesomeness_regular
  a   = awesome(0)
  b   = awesome(1)
  a   + b
end
def use_awesomeness_inlined
  a = begin
    return 0 if 0 == 0
    0 + 1
  end
  b = begin
    return 1 if 1 == 0
    1 + 1
  end
  a + b
end
array = [1] * 1000000

array.each do |element|
  puts "element: #{element}"
end
array = [1] * 1000000

array = [1] * 1000000
                               i = 0
                               size = array.size
array.each do |element|
                               while i < size
  puts "element: #{element}"
                                 puts "element: #{array[i]}"
end
                                 i += 1
                               end
array = [1] * 1000000

array = [1] * 1000000
                                    i = 0
array.each do |element|
  puts "element: #{element}"
                               ==   size = array.size
                                    while i < size
                                      puts "element: #{array[i]}"
end
                                      i += 1
                                    end
array = [1] * 100

array.each do |element|
  puts "element: #{element}"
  b = 2
end

puts b
array = [1] * 100

array = [1] * 100
                               i = 0
                               size = array.size
array.each do |element|
                               while i < size
  puts "element: #{element}"
                                 puts "element: #{array[i]}"
  b = 2
                                 b = 2
end
                                 i += 1
                               end
puts b
                               puts b
array = [1] * 100

array = [1] * 100
                                    i = 0
                                    size = array.size
array.each do |element|
                                    while i < size
  puts "element: #{element}"
  b = 2                        !=     puts "element: #{array[i]}"
                                      b = 2
end
                                      i += 1
                                    end
puts b
                                    puts b
Control flow issues
Control flow issues
Scoping issues
Control flow issues
Scoping issues
Too big piece of code
Garbage
Collection
Mark
Sweep
Generational
 Garbage
 Collection
Young
Mature
Large
Young
Semi Space
 collector
Mature
 Immix
Large
Mark - sweep
Creating less
  garbage
class Address
  attr_reader :street
  attr_reader :number
  attr_reader :city
end
class Address
             attr_reader :street
             attr_reader :number
             attr_reader :city
           end


Address.instance_variable_get("@seen_ivars")
=> [:@street, :@number, :@city]
a          =   Address.new
   a.street   =   "Street"
   a.number   =   "1"
   a.city     =   "Enschede"




Rubinius.memory_size(a) => 56


           VS
Rubinius.memory_size(a) => 160
What else?
http://rubini.us/

https://github.com/evanphx/rubinius
1 patch == commit access
Questions?

Weitere ähnliche Inhalte

Was ist angesagt?

Kotlin on Android: Delegate with pleasure
Kotlin on Android: Delegate with pleasureKotlin on Android: Delegate with pleasure
Kotlin on Android: Delegate with pleasureDmytro Zaitsev
 
Object Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in PythonObject Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in PythonTendayi Mawushe
 
Indexing thousands of writes per second with redis
Indexing thousands of writes per second with redisIndexing thousands of writes per second with redis
Indexing thousands of writes per second with redispauldix
 
Hidden Gems in Swift
Hidden Gems in SwiftHidden Gems in Swift
Hidden Gems in SwiftNetguru
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v RubyJano Suchal
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aidDavid Hoyt
 
JS Fest 2019. Max Koretskiy. A sneak peek into super optimized code in JS fra...
JS Fest 2019. Max Koretskiy. A sneak peek into super optimized code in JS fra...JS Fest 2019. Max Koretskiy. A sneak peek into super optimized code in JS fra...
JS Fest 2019. Max Koretskiy. A sneak peek into super optimized code in JS fra...JSFestUA
 
JSUG - Effective Java Puzzlers by Christoph Pickl
JSUG - Effective Java Puzzlers by Christoph PicklJSUG - Effective Java Puzzlers by Christoph Pickl
JSUG - Effective Java Puzzlers by Christoph PicklChristoph Pickl
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadiesAlicia Pérez
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worldsChristopher Spring
 
EventMachine for RubyFuZa 2012
EventMachine for RubyFuZa   2012EventMachine for RubyFuZa   2012
EventMachine for RubyFuZa 2012Christopher Spring
 
LINQ Internals - STLDODN
LINQ Internals - STLDODNLINQ Internals - STLDODN
LINQ Internals - STLDODNKeith Dahlby
 

Was ist angesagt? (19)

Kotlin on Android: Delegate with pleasure
Kotlin on Android: Delegate with pleasureKotlin on Android: Delegate with pleasure
Kotlin on Android: Delegate with pleasure
 
Object Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in PythonObject Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in Python
 
Indexing thousands of writes per second with redis
Indexing thousands of writes per second with redisIndexing thousands of writes per second with redis
Indexing thousands of writes per second with redis
 
Go &lt;-> Ruby
Go &lt;-> RubyGo &lt;-> Ruby
Go &lt;-> Ruby
 
Python Part 1
Python Part 1Python Part 1
Python Part 1
 
Python Puzzlers
Python PuzzlersPython Puzzlers
Python Puzzlers
 
Hidden Gems in Swift
Hidden Gems in SwiftHidden Gems in Swift
Hidden Gems in Swift
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
Drinking the free kool-aid
Drinking the free kool-aidDrinking the free kool-aid
Drinking the free kool-aid
 
Python: Basic Inheritance
Python: Basic InheritancePython: Basic Inheritance
Python: Basic Inheritance
 
Python Part 2
Python Part 2Python Part 2
Python Part 2
 
JS Fest 2019. Max Koretskiy. A sneak peek into super optimized code in JS fra...
JS Fest 2019. Max Koretskiy. A sneak peek into super optimized code in JS fra...JS Fest 2019. Max Koretskiy. A sneak peek into super optimized code in JS fra...
JS Fest 2019. Max Koretskiy. A sneak peek into super optimized code in JS fra...
 
JSUG - Effective Java Puzzlers by Christoph Pickl
JSUG - Effective Java Puzzlers by Christoph PicklJSUG - Effective Java Puzzlers by Christoph Pickl
JSUG - Effective Java Puzzlers by Christoph Pickl
 
Steady with ruby
Steady with rubySteady with ruby
Steady with ruby
 
Beautiful python - PyLadies
Beautiful python - PyLadiesBeautiful python - PyLadies
Beautiful python - PyLadies
 
jRuby: The best of both worlds
jRuby: The best of both worldsjRuby: The best of both worlds
jRuby: The best of both worlds
 
EventMachine for RubyFuZa 2012
EventMachine for RubyFuZa   2012EventMachine for RubyFuZa   2012
EventMachine for RubyFuZa 2012
 
LINQ Internals - STLDODN
LINQ Internals - STLDODNLINQ Internals - STLDODN
LINQ Internals - STLDODN
 
Values
ValuesValues
Values
 

Ähnlich wie Lecture on Rubinius for Compiler Construction at University of Twente

Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with GroovyArturo Herrero
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 
Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Evgeny Borisov
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick touraztack
 
Groovy grails types, operators, objects
Groovy grails types, operators, objectsGroovy grails types, operators, objects
Groovy grails types, operators, objectsHusain Dalal
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional SwiftJason Larsen
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosEdgar Suarez
 
Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Wen-Tien Chang
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsBaruch Sadogursky
 
Please help this code is supposed to evaluate current node state and i.pdf
Please help this code is supposed to evaluate current node state and i.pdfPlease help this code is supposed to evaluate current node state and i.pdf
Please help this code is supposed to evaluate current node state and i.pdfclimatecontrolsv
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to PythonUC San Diego
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming LanguageDuda Dornelles
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesTchelinux
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyVysakh Sreenivasan
 

Ähnlich wie Lecture on Rubinius for Compiler Construction at University of Twente (20)

Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
 
Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
Groovy grails types, operators, objects
Groovy grails types, operators, objectsGroovy grails types, operators, objects
Groovy grails types, operators, objects
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional Swift
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
An introduction to Ruby
An introduction to RubyAn introduction to Ruby
An introduction to Ruby
 
Ruby Intro {spection}
Ruby Intro {spection}Ruby Intro {spection}
Ruby Intro {spection}
 
Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽
 
The Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 SeasonsThe Groovy Puzzlers – The Complete 01 and 02 Seasons
The Groovy Puzzlers – The Complete 01 and 02 Seasons
 
Please help this code is supposed to evaluate current node state and i.pdf
Please help this code is supposed to evaluate current node state and i.pdfPlease help this code is supposed to evaluate current node state and i.pdf
Please help this code is supposed to evaluate current node state and i.pdf
 
Introduction to Python
Introduction to PythonIntroduction to Python
Introduction to Python
 
Ruby Programming Language
Ruby Programming LanguageRuby Programming Language
Ruby Programming Language
 
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares DornellesA linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
A linguagem de programação Ruby - Robson "Duda" Sejan Soares Dornelles
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced Ruby
 

Kürzlich hochgeladen

DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 

Kürzlich hochgeladen (20)

DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 

Lecture on Rubinius for Compiler Construction at University of Twente

  • 1. Rubinius Use Ruby
  • 2. Dirkjan Bussink d.bussink@gmail.com
  • 3.
  • 5. Dynamic vs. Static
  • 6. x = 10 x = 'a' int x = 10 string x = 'a' => ERROR
  • 8. x = 10 y = "20" x + y # Javascript => 1020 # PHP => 30
  • 11. class MyAwesomeObject def initialize puts "Running constructor" end def cool_method(arg1, arg2) arg1 + arg2 end end
  • 12. [1, 2, 3, 4].each do |e| puts e end
  • 13. module Person def name puts "Every person has name" end end class Student include Person end Student.new.name
  • 19. C++
  • 20. Ruby
  • 21. 0000: meta_push_0 0001: set_local 0 # i 0003: pop 0004: push_local 0 # i 0006: push_literal 1000 0008: meta_send_op_lt :< 0010: goto_if_false 23 i = 0 0012: push_local 0 # i while i < 1000 do 0014: meta_push_1 i = i + 1 0015: meta_send_op_plus :+ 0017: set_local 0 # i end 0019: pop 0020: check_interrupts 0021: goto 4 0023: push_nil 0024: pop 0025: push_true 0026: ret
  • 22. Fancy class Person { read_write_slots: ['name, 'age, 'city] def initialize: @name age: @age city: @city { } def go_to: city { if: (city is_a?: City) then: { @city = city } } def to_s { "Person: #{@name}, #{@age} years old, living in #{@city}" } }
  • 23.
  • 27.
  • 29. def each return to_enum(:each) unless block_given? i = @start total = i + @total tuple = @tuple while i < total yield tuple.at(i) i += 1 end self end
  • 33. class FixnumLiteral < NumberLiteral def initialize(line, value) @line = line @value = value end def bytecode(g) pos(g) g.push @value end def defined(g) g.push_literal "expression" end end
  • 36. class Array def sum inject(0) {|total, e| total + e.to_i} end end
  • 37. class Bignum def +(other) self - other end end
  • 38. "The edges of the sword are life and death, no one knows which is which" Ikkyu Sojun, 15th Century Zen master
  • 39. Hard, but not impossible
  • 42.
  • 43. class Person def name "me" end end
  • 44. module Named def name class Person "named" def name end "me" end end class Person end include Named end
  • 45. module Named def name class Person class Person "named" end def name end "me" end def p.name end class Person "specific" end include Named end end
  • 46. class Person attr_accessor :name end 10000.times do p = Person.new p.name end
  • 47. There are only two hard problems in Computer Science: cache invalidation, naming things and off-by-one errors
  • 48.
  • 49. module Naming def name "me2" end end class Person include Naming end 10000.times do p = Person.new p.name end
  • 50. module Naming def name "me2" class Person end def name end "new_name" end class Person end include Naming end 10000.times do p = Person.new 10000.times do p.name p = Person.new end p.name end
  • 52. JIT
  • 53. “...we finally managed to get our Linux (...) builds to use GCC 4.5, ... and profile guided optimization enabled” Mike Hommey - on Firefox 6 performance
  • 54. def method1 1 + 1 end def method2 2 + 1 end 10000.times do method1 end
  • 55. members of rubinius::VMMethod: total_args = 0, call_count = 21, llvm_function_ = 0x0, name_ = 0x6306,
  • 56. static const int default_jit_call_til_compile = 4000;
  • 57. pushl %ebp movl %esp, %ebp subl $4, %esp movl $10, -4(%ebp) leal -4(%ebp), %eax addl $66, (%eax) leave ret
  • 58.
  • 59. #include <stdio.h> int func() { int i = 0; i += 10; return i; }
  • 60. ; ModuleID = '<stdin>' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16- i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64- v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64" target triple = "x86_64-apple-darwin10.7" define i32 @func() nounwind ssp { entry: %retval = alloca i32 %0 = alloca i32 %i = alloca i32 %"alloca point" = bitcast i32 0 to i32 store i32 0, i32* %i, align 4 %1 = load i32* %i, align 4 %2 = add nsw i32 %1, 10 store i32 %2, i32* %i, align 4 %3 = load i32* %i, align 4 store i32 %3, i32* %0, align 4 %4 = load i32* %0, align 4 store i32 %4, i32* %retval, align 4 br label %return return: ; preds = %entry %retval1 = load i32* %retval ret i32 %retval1 }
  • 61. ; ModuleID = '<stdin>' target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8- i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64- v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128- n8:16:32:64" target triple = "x86_64-apple-darwin10.7" define i32 @func() nounwind readnone ssp { entry: ret i32 10 }
  • 62. Go JIT! RBX LLVM thread(s) thread Here it is!
  • 63. members of rubinius::VMMethod: total_args = 0, call_count = 21, llvm_function_ = 0x102c07b30, name_ = 0x6306,
  • 65. array = [1] * 1000000 array.each do |element| puts "element: #{element}" end
  • 66.
  • 67. def method1 1 + 1 end def method2 method1 end 100.times do method2 end
  • 68. def method1 def method1 1 + 1 1 + 1 end end def method2 def method2 method1 method1 end end 100.times do 100.times do method2 method1 end end
  • 69. def method1 def method1 1 + 1 1 + 1 end end def method2 def method2 method1 method1 end end 100.times do 100.times do method2 method1 end end
  • 70. def method1 def method1 def method1 1 + 1 1 + 1 1 + 1 end end end def method2 def method2 def method2 method1 method1 method1 end end end 100.times do 100.times do 100.times do method2 method1 1 + 1 end end end
  • 71. def method1 def method1 def method1 1 + 1 1 + 1 1 + 1 end end end def method2 def method2 def method2 method1 method1 method1 end end end 100.times do 100.times do 100.times do method2 method1 1 + 1 end end end
  • 72.
  • 73. def awesome(x) return 0 if x == 0 x + 1 end def use_awesomeness_regular a = awesome(0) b = awesome(1) a + b end
  • 74. def use_awesomeness_inlined a = begin return 0 if 0 == 0 0 + 1 end b = begin return 1 if 1 == 0 1 + 1 end a + b end
  • 75.
  • 76. array = [1] * 1000000 array.each do |element| puts "element: #{element}" end
  • 77. array = [1] * 1000000 array = [1] * 1000000 i = 0 size = array.size array.each do |element| while i < size puts "element: #{element}" puts "element: #{array[i]}" end i += 1 end
  • 78. array = [1] * 1000000 array = [1] * 1000000 i = 0 array.each do |element| puts "element: #{element}" == size = array.size while i < size puts "element: #{array[i]}" end i += 1 end
  • 79.
  • 80. array = [1] * 100 array.each do |element| puts "element: #{element}" b = 2 end puts b
  • 81. array = [1] * 100 array = [1] * 100 i = 0 size = array.size array.each do |element| while i < size puts "element: #{element}" puts "element: #{array[i]}" b = 2 b = 2 end i += 1 end puts b puts b
  • 82. array = [1] * 100 array = [1] * 100 i = 0 size = array.size array.each do |element| while i < size puts "element: #{element}" b = 2 != puts "element: #{array[i]}" b = 2 end i += 1 end puts b puts b
  • 83.
  • 86. Control flow issues Scoping issues Too big piece of code
  • 88.
  • 90.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 109.
  • 110.
  • 111.
  • 112.
  • 114. Creating less garbage
  • 115. class Address attr_reader :street attr_reader :number attr_reader :city end
  • 116. class Address attr_reader :street attr_reader :number attr_reader :city end Address.instance_variable_get("@seen_ivars") => [:@street, :@number, :@city]
  • 117. a = Address.new a.street = "Street" a.number = "1" a.city = "Enschede" Rubinius.memory_size(a) => 56 VS Rubinius.memory_size(a) => 160
  • 120. 1 patch == commit access

Hinweis der Redaktion

  1. \n
  2. \n
  3. \n
  4. Regular contributor since the early beginnings of 2008\n
  5. First I want to explain two concepts\nThe first concept is about dynamic versus static languages.\n\n- Dynamic languages\nTypes checking is done at runtime\n- Static languages\nTypes are checked during compile time\n\n \n
  6. The first is what happens in a dynamic language. Types are not fixed and you can use different types if you want\nThe second is a static language. Once a certain type is defined, the type can&amp;#x2019;t be changed. \n
  7. Another difference is how types are enforced.\nThis is often confused with static and dynamic languages, seeing the dynamic language as weakly typed. This however is often not true.\n\n-Strong typing\nThis enforces specific rules and behavior on what happens when you run certain operations on differently typed objects\n-Weak typing\nImplicit type conversion when different types are used\n\n
  8. \n
  9. So what is Ruby?\n\nRuby is a dynamically strongly typed language. So you don&amp;#x2019;t specify types when writing ruby code, but during runtime it&amp;#x2019;s types are not just changed automatically.\n\nIt has primarily been influenced by Perl, Smalltalk and Lisp. The primary design philosophy is that a language should be productive and fun to use. \n
  10. So how does it look?\nThe classic Hello world! example\n
  11. This is how basic class definition and method definition look like\n
  12. Block syntax. They are lambda like constructs. It&amp;#x2019;s like passing a piece of code as a special argument to a method. \n
  13. Modules. They allow for code being mixed into other classes. It&amp;#x2019;s a bit like multiple inheritance. This is made possible because of the dynamic nature of Ruby\n
  14. Rubinius includes everything needed to run Ruby code\n
  15. That means it includes a bytecode Virtual Machine, primarily designed for running Ruby code.\n
  16. But it also includes all core classes etc. you expect in Ruby, like String, Hash and Array. In other languages t&amp;#x2019;s often called the standard library, but that has a different meaning in Ruby, so hence this name. \n
  17. It was started in 2006, thought up by Evan Phoenix during his honeymoon. He and Brian Ford are payed full time to work on Rubinius.\n
  18. So what does the virtual machine entail? \n
  19. The first and initial version was written in Ruby. After this proof of concept, a first version of the virtual machine was written C. In 2008 the choice was made to rewrite it in C++, because that is a better fit with the architecture of the VM. \n
  20. The bytecode instruction set includes the necessary instructions for running Ruby code efficiently. This doesn&amp;#x2019;t mean other languages can&amp;#x2019;t be written on top of Rubinius.\n
  21. So what does the bytecode look like?\nThe comments at the end show how the variable names are mapped to slots\n
  22. One example is Fancy. It has a few different aspect compare to ruby, like named parameters\n
  23. There&amp;#x2019;s a bunch of other languages people created, mostly as an experiment and not very mature\n
  24. There&amp;#x2019;s a bunch of other languages people created, mostly as an experiment and not very mature\n
  25. There&amp;#x2019;s a bunch of other languages people created, mostly as an experiment and not very mature\n
  26. So how do we make it fast? There&amp;#x2019;s quite a few techniques for that which will be discussed later in the lecture\n
  27. The kernel code is written in Ruby as much as possible. This means that classes like String, Hash and Array are written in Ruby itself\n
  28. This is how Array#each looks like. It uses a Tuple, which is a fixed size array like structure that Array is built upon. Hash is written in Ruby too\n
  29. Having more in Ruby also means that it&amp;#x2019;s easier for people to help out with. You don&amp;#x2019;t need to know C / C++ in order to contribute to Rubinius\n
  30. \n
  31. \n
  32. It parses into an AST and then outputs bytecode by walking the AST. Each node knows how to emit bytecode, such as this example for Fixnum literals. It stores the line number and the given value for the literal.\n
  33. People often claim that Ruby, or dynamic languages in general are slow. \n
  34. \n
  35. Add a method useful for you on a core type. Not always the best solution, but it&amp;#x2019;s a very flexible way to handle things. \n
  36. You can also do very nasty things.\n
  37. \n
  38. \n
  39. So in order to improve performance of a dynamic language, there are various techniques. One of the most basic ones that gives an easy improvement is inline caching.\n
  40. So we have this little piece of code. First, we create a Person, then we do some other stuff and then we call the method name on it. p.name here is know as a call site.\n
  41. So where can this method be?\n- There&amp;#x2019;s the simple case of it being a method defined for all instances of the class\n-It can also be in a module included into the class\n-Another option is defining a method on the metaclass of the object. This means it&amp;#x2019;s only available for this specific instance of the Person.\n
  42. So where can this method be?\n- There&amp;#x2019;s the simple case of it being a method defined for all instances of the class\n-It can also be in a module included into the class\n-Another option is defining a method on the metaclass of the object. This means it&amp;#x2019;s only available for this specific instance of the Person.\n
  43. So where can this method be?\n- There&amp;#x2019;s the simple case of it being a method defined for all instances of the class\n-It can also be in a module included into the class\n-Another option is defining a method on the metaclass of the object. This means it&amp;#x2019;s only available for this specific instance of the Person.\n
  44. So consider this extended example with complete code. If you look at the code, you see that when running this, p.name ends up in the same method every time you execute the code. So even though Ruby is very dynamic, most of the code looks like it&amp;#x2019;s static anyway. \n\nSo the expensive computation can perhaps be stored and reused so it&amp;#x2019;s not needed each time. The caching of this method dispatch result is called inline caching.\n
  45. \n
  46. So, here we need to be sure to invalidate our cache, otherwise it would run the wrong method\n
  47. So, here we need to be sure to invalidate our cache, otherwise it would run the wrong method\n
  48. So, now the question is, is this lookup changed too? The problem is that we want to keep the caches simple. So there&amp;#x2019;s a cache entry at each call site that stores for a specific type, the method it dispatched to and module that method is defined. This makes the cache entries small so there&amp;#x2019;s isn&amp;#x2019;t a lot of memory overhead.\n\n\nSo we don&amp;#x2019;t want to store the complete chain. Which means that we only have OtherObject as a type stored here. It also means that we need to invalidate the cache because we don&amp;#x2019;t know whether OtherObject includes Naming or not. \n\nTherefore invalidating caches is a brute force measure that removes all caches with the same name, so in this case &amp;#x201C;name&amp;#x201D;.\n
  49. Just In Time compilation means that code is compiled to native code during execution of your programs. \n
  50. This quote shows that using runtime information, you can optimize code a lot better than just only ahead of time. \n\nSo we need to track this runtime information so we know what we can compile into native code. \n
  51. So here we have a bunch of code that is executed quite often. We don&amp;#x2019;t know ahead of time that we don&amp;#x2019;t actually need the method2 method, but we do during runtime. So we can use this information at runtime.\n
  52. Each VMMethod object keeps track of various things\nYou can see how often a method is called\nThe llvm_function_ pointer points at jitted code for this method\nThere&amp;#x2019;s a name for the method of course\nAnd a whole bunch of other stuff removed here\n
  53. So right now, a method is going to be compiled after it has been executed 4000 times. \n
  54. The initial version used hand crafted assembly to output the code for it. This was cumbersome and would need a lot of work to optimize it to a decently performing level. \n
  55. That&amp;#x2019;s why the LLVM compiler infrastructure was chosen. It already did a huge amount of legwork in generating good native code for various platforms. \n
  56. \n
  57. This is what the LLVM bytecode looks like without any optimizations. This is actually kind of like how with Rubinius code is translated. There is a C++ API for creating this bytecode. \n
  58. This is what the LLVM optimizer makes out of it. It can reason about so in the end the value 10 can be returned directly. LLVM can run similar passes over code generated through the C++ API. \n
  59. So how is this implemented? The code compilation actually happens in a background thread. The virtual machine requests that a certain method is jitted, which is then given to the LLVM thread. The LLVM thread then goes to work and creates the LLVM bytecode. After this is compiled, it sets the llvm_function_ pointer seen earlier. \n\nThis means that the VM just runs along nicely without being interrupted by the compilation of code. \n
  60. \n
  61. No overhead is faster than no overhead. We already saw that inline caches can greatly improve method dispatching, but there&amp;#x2019;s certainly room for even more optimizations. One of these is code inlining, which means that method dispatch overhead is completely removed. \n\n\n
  62. Ruby has another place that can benefit greatly from code inline, which is the usage of blocks. A block is a construct which has it&amp;#x2019;s own scope and can also be captured explicitly. This means that it does add overhead and looking at removing that overhead is very interesting. \n
  63. So we start here with a simple piece of code. What inlining does, is moving the actual code of the method into the method that the method is called from. So this means that instead of dispatching a method, it executes the code of that method directly. \n
  64. So we start here with a simple piece of code. What inlining does, is moving the actual code of the method into the method that the method is called from. So this means that instead of dispatching a method, it executes the code of that method directly. \n
  65. So we start here with a simple piece of code. What inlining does, is moving the actual code of the method into the method that the method is called from. So this means that instead of dispatching a method, it executes the code of that method directly. \n
  66. So we start here with a simple piece of code. What inlining does, is moving the actual code of the method into the method that the method is called from. So this means that instead of dispatching a method, it executes the code of that method directly. \n
  67. So we start here with a simple piece of code. What inlining does, is moving the actual code of the method into the method that the method is called from. So this means that instead of dispatching a method, it executes the code of that method directly. \n
  68. So inline has some great potential, but there are quite a few caveats. \n
  69. We take a look at this example. Here is the same method called with a different parameter, which we could perhaps inline. So we take a naive attempt in the next slide.\n
  70. Here we manually inlined the two calls to awesome() and injected the code in this place. The begin / end block is used so we have the correct scope of the inlined code.\n\nBut if we look at this, this code behaves differently! Let me show this by running it. What you can see here is that the control flow is different because of the return. While the return first meant that it would return from the method, with the inlining this method is no longer present. So when inlining, control flow is something that needs considering. \n
  71. This is a very simple example of how block code inlining should work. The left version is a much prettier and nicer version and that is how Ruby code should look.\n\nThe example on the right is equivalent, but it has the block used in the version on the left removed. This is what you can call block inlining in Rubinius. \n
  72. This is a very simple example of how block code inlining should work. The left version is a much prettier and nicer version and that is how Ruby code should look.\n\nThe example on the right is equivalent, but it has the block used in the version on the left removed. This is what you can call block inlining in Rubinius. \n
  73. This is a very simple example of how block code inlining should work. The left version is a much prettier and nicer version and that is how Ruby code should look.\n\nThe example on the right is equivalent, but it has the block used in the version on the left removed. This is what you can call block inlining in Rubinius. \n
  74. But beware with scoping issues. Who thinks he knows what happens here?\n
  75. But beware with scoping issues. Who thinks he knows what happens here?\n
  76. But beware with scoping issues. Who thinks he knows what happens here?\n
  77. So there are few reasons why code isn&amp;#x2019;t inlined. These properties can be determined by analyzing the bytecode for a method. If these issues come forth from it, the code isn&amp;#x2019;t inlined. What can be inlined is something that is improved over time. More code can be written to support more complex structures for inlining. \n
  78. So there are few reasons why code isn&amp;#x2019;t inlined. These properties can be determined by analyzing the bytecode for a method. If these issues come forth from it, the code isn&amp;#x2019;t inlined. What can be inlined is something that is improved over time. More code can be written to support more complex structures for inlining. \n
  79. So there are few reasons why code isn&amp;#x2019;t inlined. These properties can be determined by analyzing the bytecode for a method. If these issues come forth from it, the code isn&amp;#x2019;t inlined. What can be inlined is something that is improved over time. More code can be written to support more complex structures for inlining. \n
  80. \n
  81. People are really happy that others clean up their garbage. No need to worry about it anymore. Using automatic memory management has various advantages, such as not having to worry about object ownership, double free bugs and possible memory leaks. \n\nRuby also uses automatic memory management and needs garbage collection.\n
  82. A simple naive way of doing garbage collection is to start at the root of the object graph and go from there. Going through each object, marking the objects as you go along. After this marking phase, you go through all objects again. Everything that doesn&amp;#x2019;t have a mark set, is freed as it is apparently not reachable anymore. \n
  83. So how can we make this faster? We can look at the properties of different objects. Young objects are often only around for a very short time. So we want to have a mechanism to suit this properly. \n
  84. \n
  85. \n
  86. \n
  87. \n
  88. \n
  89. \n
  90. \n
  91. \n
  92. \n
  93. \n
  94. \n
  95. \n
  96. \n
  97. \n
  98. \n
  99. \n
  100. \n
  101. Immix uses different block of memory. It allocates objects in a block, so it has contiguous allocation for objects. This means it doesn&amp;#x2019;t need a free list for allocation. On the other hand, this technique can limit memory fragmentation.\n
  102. Immix uses different block of memory. It allocates objects in a block, so it has contiguous allocation for objects. This means it doesn&amp;#x2019;t need a free list for allocation. On the other hand, this technique can limit memory fragmentation.\n
  103. Immix uses different block of memory. It allocates objects in a block, so it has contiguous allocation for objects. This means it doesn&amp;#x2019;t need a free list for allocation. On the other hand, this technique can limit memory fragmentation.\n
  104. Very large objects are directly allocated in a special area. This is because you don&amp;#x2019;t want to copy them, since copying is an expensive operation and they also don&amp;#x2019;t fit in the immix blocks. \n\nThis special area doesn&amp;#x2019;t copy objects, but just uses a very simple mark and sweep algorithm.\n
  105. \n
  106. This is kind of how an object looks like in memory. By default there&amp;#x2019;s an instance variable table, because you can add and remove instance variables on the fly in Ruby. There&amp;#x2019;s no definitive way to know which instance variable we need up front.\n\nBut we can make a very nice educated guess on how it would look like. We use the compiler to track all the variables we see. So if we compile the class given here, we can track all instance variables we encounter. \n
  107. Here we see the effect on memory usage. With the instance variable table, it uses 160 bytes for each object of type Address, but with the packing it only uses 56 bytes!\n
  108. \n
  109. So if you want to know more, please look it up here. You can also of course ask me additional questions. \n
  110. If you think it&amp;#x2019;s interesting and want to contribute, just one patch accepted means commit access. \n
  111. \n