limit): Write You a Barrier - Automatic Insertion of Write Barriers • Original Title: Write You a Barrier for Great Good - Automatic Checking and Insertion of Write Barriers in Ruby C Extensions 3
program, Intelligence and Information Course, Graduate School of Science and Engineering, Aoyama Gakuin University (青山学院大学大学院理工学研究科知能情報コース M1) Favorites : Fishing, traveling, taking a photos, ... The tool was developed for the senior thesis Martin J. Dürst Department of Integrated Information Technology, College of Science and Engineering, Aoyama Gakuin University (青山学院大学理工学部情報テクノロジー学科教授) 4
code • Uses static analysis based on type information • Write barrier is a feature of garbage collection (GC) of MRI • wb_check is still experimental • Code is at https://github.com/joetake/wb_check • Please provide comments 7
{ … VALUE target_ary = ary_ensure_room_for_push(ary, 1); RARRAY_PTR_USE(ary, ptr, { RB_OBJ_WRITE(target_ary, &ptr[idx], item); … } } Implementation of Array’s '<<' method in ruby/array.c # method that push object ‘item’ to array object ‘ary’ # get a new space at the end of the array # write new reference # and call write barrier
MRI via the C API 20 #include "ruby.h" #include "extconf.h" VALUE rb_hello() { VALUE hello = rb_str_new2("hello, from C"); return hello; } void Init_hello() { VALUE module = rb_define_module("Greeting"); rb_define_method(module, "hello", rb_hello, 0); } require './hello' include Greeting puts hello() # hello, from C C Ruby
21 VALUE number = INT2NUM(3) # Fixnum 3 VALUE string = rb_str_new2("RubyKaigi") # String 'RubyKaigi' VALUE data type • Reference to RVALUE data (Object’s data) • Immediate value (nil, true, 'small' numbers,...) TYPE(obj) T_NIL, T_ARRAY, T_OBJECT, … VALUE data type knows what type the object is
care about write barriers Write barriers are required only in specific cases → T_DATA (Typed Data) 22 C Extension Code Ruby Object via C API Use write barrier if needed
be used T_DATA objects holds VALUE field inside C Structure When insertion of write barrier have reasonable merit • object may be long-lived • object may be numerous • object may have many references to other objects
grammar •Access the syntax tree with ruby-tree-sitter binding 32 C99 grammar: https://github.com/tree-sitter/tree-sitter-c Ruby binding: https://github.com/Faveod/ruby-tree-sitter
to another Object made 36 #define TypedData_Get_Struct(obj,type,data_type,sval) ¥ ((sval) = RBIMPL_CAST((type *)rb_check_typeddata((obj), (data_type)))) ruby/include/ruby/internal/core/rtypeddata.h line: 515 1. Locate pointer to Structure that T_DATA object have When VALUE type field in structure contained in T_DATA object is changed 2. Locate where VALUE type field is changed • Assignements • Function calls / macros
Variables • Field of structures 38 class CVar def initialize(...) @type = type @name = name @pointer_count = pointer_count @parenthesis_count = parenthesis_count @is_typeddata = false @parent_obj = nil end
variables can be accessed from inner blocks 3. Inner variables take precedence over outer variables 4. After exiting a block, the variables inside the block can’t be accessed anymore 39 def analyze_block(node, function_signature, _vars_in_local) vars_in_local = _vars_in_local.clone ... node.each_named do |child| case child.type when :declaration ... vars.each {|var| vars_in_local[var.name] = var} ... when :if_statement, ... analyze_block(child, function_signature, vars_in_local) ... # Do shallow copy of outer block’s map when new block starts # Pass variable list when new block is found # Overwrite if names are identical
Analyze function call Analyze function call Analyze function call class Context attr_accessor ... def initialize(marked_parameter_index) @marked_argument_index = marked_p... @current_function_params = Array.new @changed_parameter_index = Array.new end end
', ' . ') • A[:is_typeddata] == true • operator == '->' || operator == '.' && A[:is_pointer_access] If B is a structure if that structure has a VALUE type field, a Write Barrier is needed If B isn’t a structure if B is VALUE type field, a Write Barrier is needed 44 *a.B