Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kompilator Ruby – C

Kompilator Ruby – C

Slides from a presentation delivered on 2.2.2011 at the Warsaw Ruby Users Group meetup.

http://wrug.eu/2011/01/31/2011-02-spotkanie-lutowe/

Jan Stępień

February 02, 2011
Tweet

More Decks by Jan Stępień

Other Decks in Programming

Transcript

  1. Schemat działania Wczytanie kodu Parsowanie Translacja Generowanie kodu C Kompilacja

    Linkowanie Kod Ruby AST Ruby AST C Kod C Plik obiektowy
  2. Narzędzia Translator napisany w Ruby Biblioteka standardowa w C Parser:

    ruby parser Garbage collector: BDWGC Struktury danych: GLib
  3. Proste wyrażenia b = 0 a = if b a

    = 1 b = 2 end Object *b; b = (Fixnum_new (0)); Object *a; Object *var1; if (boolean_value (b)) { a = (Fixnum_new (1)); b = (Fixnum_new (2)); var1 = b; } a = var1;
  4. Tłumaczenie klas class A def set(a) @a = a end

    def get @a end end typedef struct { Object meta; Object *a; } A; Object * A_set_Fixnum(Object *self, Object *a) { (((A *) self)->a) = a; return ((A *) self)->a; } Object * A_get(Object *self) { return ((A *) self)->a; }
  5. Pola przy dziedziczeniu typedef struct { uint32 type; } Object;

    typedef struct { Object parent; Object* leg_count; } Animal; typedef struct { Object parent; Object* leg_count; Object* horns_length; } Cow;
  6. Metody Tłumaczenie dopiero w momencie wywołania Każda metoda to funkcja

    w C Jeśli znamy typy przekazanych argumentów to tworzymy osobną funkcję
  7. Metody dict_elem classes_dictionary[] = { {-1, &Object_method_find, &vs_Object}, {0, NULL,

    &vs_M_Object}, {0, NULL, &vs_Class}, {0, &Fixnum_method_find, &vs_Fixnum}, {0, &Float_method_find, &vs_Float}, /* ... */ }
  8. Metody Znamy wszystkie nazwy metod Perfekcyjny hash bez kolizji Cache

    metod Nadpisanie metody to po prostu zmiana wskaźnika na funkcję
  9. Bloki typedef Object* (*block_t)(Object*, ...); static Object* block1(Object* self,Object* ocena)

    { Object* _var2[1]= {ocena}; Object* _var1; _var1=(call_method((ocena->type),"to__s",classes_dictionary,_var2)); Object* _var3; _var3=(String__PLUS_((String_new("Wypiszmy: ")),_var1)); Object* _var4; _var4=(Object_puts(self,_var3)); return _var4; }; int main() { /* ... */ push_block((((block_t)block1))); Object* _var5; _var5=(Fixnum_upto((Fixnum_new(2)),(Fixnum_new(5)))); pop_block(); return 0; }
  10. Optymalizacja arytmetyki puts((4 + 5.4) / 2) Object* _var1; _var1

    = Fixnum__PLUS_(Fixnum_new(4), Float_new(5.4))); Object* _var2; _var2 = Float__DIV_(_var1, Fixnum_new(2)); Object_puts(self, _var2); Object_puts(self, Float_new((4 + 5.4) / 2));
  11. Biblioteka standardowa class Fixnum defined_in_stdlib def /(arg) defined_as :Fixnum__DIV_ Fixnum.returned_if

    Fixnum Float.returned_if Float end def to_s defined_as :Fixnum_to__s returns String end # I tak dalej... end
  12. Wyniki Test Poprawa ackermann.rb 3,91 arrays.rb 4,46 arithmetic.rb 5,20 heapsort.rb

    1,30 matrix.rb 0,67 quicksort.rb 0,96 strings.rb 0,33 Ruby 1.9.2, GNU/Linux 2.6.35, i686, Intel Core 2 Duo T6570 @ 2,10GHz, 2GB RAM
  13. matrix.rb – mnożenie macierzy main 0 (0.0%) of 86 (100.0%)

    M_Object_mmult_Fixnum_Fixnum_Array_Array 9 (10.5%) of 82 (95.3%) 82 _init 7 (8.1%) 4 call_method 17 (19.8%) of 56 (65.1%) 56 Array__INDEX_ 11 (12.8%) 3 Fixnum_new 3 (3.5%) of 11 (12.8%) 11 1 Fixnum__MUL_ 5 (5.8%) of 12 (14.0%) 12 8 __strcmp_ssse3 7 (8.1%) 7 1 Fixnum__PLUS_ 1 (1.2%) of 6 (7.0%) 6 Array_method_find 2 (2.3%) 2 Fixnum_method_find 2 (2.3%) 2 xmalloc_atomic 3 (3.5%) of 19 (22.1%) Garbage collector 18.6% 16 7 8 4 1
  14. quicksort.rb – rekurencja i tablice main 0 (0.0%) of 266

    (100.0%) M_Object_qsort_Array 21 (7.9%) of 262 (98.5%) 262 Fixnum_new 10 (3.8%) of 126 (47.4%) boolean_value 8 (3.0%) 1 3226 53 call_method 20 (7.5%) of 80 (30.1%) 80 Array_length 1 (0.4%) of 74 (27.8%) 52 Array_push 2 (0.8%) of 36 (13.5%) 27 Array__INDEX_ 10 (3.8%) 7 7 xmalloc_atomic 4 (1.5%) of 116 (43.6%) 115 Garbage 54.8% collector 112 22 9 3 Float__LT_ 6 (2.3%) of 8 (3.0%) 8 Array_method_find 6 (2.3%) of 7 (2.6%) 7 72
  15. strings.rb – bardzo długie stringi String__PLUS_ 0 (0.0%) of 1232

    (98.2%) *__GI_strncpy 801 (63.8%) 801 String_new 0 (0.0%) of 400 (31.9%) 393 __strlen_sse2 38 (3.0%) 38 xmalloc_atomic 0 (0.0%) of 304 (24.2%) 295 g_string_append_len 0 (0.0%) of 99 (7.9%) 99 GC_malloc_atomic 0 (0.0%) of 304 (24.2%) GC_generic_malloc 0 (0.0%) of 298 (23.7%) 294 304 290 main 1 (0.1%) of 261 (20.8%) 242 Garbage 23.7% collector __memcpy_ssse3 99 (7.9%) g_slice_alloc (inline) 0 (0.0%) of 99 (7.9%) g_string_append_len (inline) 0 (0.0%) of 99 (7.9%) 99 99 99 99 198
  16. Dalszy rozwój Brakujące elementy Ruby: lambdy, moduły, wątki, wyjątki, biblioteka

    standardowa... Optymalizacja przetwarzanego kodu Wykorzystanie rozwiązań z YARV Optymalizacja wyszukiwania metod Dalsza praca nad statycznym rozpoznawaniem typów RubySpec, self-hosting