ruby-prof 1.4.3 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/CHANGES +59 -9
 - data/{README.rdoc → README.md} +2 -2
 - data/Rakefile +4 -4
 - data/bin/ruby-prof +100 -87
 - data/ext/ruby_prof/rp_allocation.c +140 -85
 - data/ext/ruby_prof/rp_allocation.h +8 -6
 - data/ext/ruby_prof/rp_call_tree.c +502 -369
 - data/ext/ruby_prof/rp_call_tree.h +47 -43
 - data/ext/ruby_prof/rp_call_trees.c +16 -8
 - data/ext/ruby_prof/rp_measure_allocations.c +10 -13
 - data/ext/ruby_prof/rp_measure_memory.c +8 -4
 - data/ext/ruby_prof/rp_measure_process_time.c +7 -6
 - data/ext/ruby_prof/rp_measurement.c +147 -20
 - data/ext/ruby_prof/rp_measurement.h +4 -1
 - data/ext/ruby_prof/rp_method.c +142 -83
 - data/ext/ruby_prof/rp_method.h +63 -62
 - data/ext/ruby_prof/rp_profile.c +933 -900
 - data/ext/ruby_prof/rp_profile.h +1 -0
 - data/ext/ruby_prof/rp_thread.c +433 -362
 - data/ext/ruby_prof/rp_thread.h +39 -39
 - data/ext/ruby_prof/ruby_prof.c +0 -2
 - data/ext/ruby_prof/ruby_prof.h +8 -0
 - data/ext/ruby_prof/vc/ruby_prof.vcxproj +11 -8
 - data/lib/ruby-prof/assets/call_stack_printer.html.erb +2 -1
 - data/lib/ruby-prof/compatibility.rb +14 -0
 - data/lib/ruby-prof/method_info.rb +8 -1
 - data/lib/ruby-prof/printers/abstract_printer.rb +2 -1
 - data/lib/ruby-prof/printers/call_tree_printer.rb +4 -10
 - data/lib/ruby-prof/printers/graph_html_printer.rb +1 -1
 - data/lib/ruby-prof/printers/multi_printer.rb +17 -17
 - data/lib/ruby-prof/profile.rb +70 -37
 - data/lib/ruby-prof/rack.rb +31 -21
 - data/lib/ruby-prof/version.rb +1 -1
 - data/lib/ruby-prof.rb +1 -1
 - data/ruby-prof.gemspec +2 -3
 - data/test/abstract_printer_test.rb +1 -0
 - data/test/alias_test.rb +97 -106
 - data/test/call_tree_builder.rb +126 -0
 - data/test/call_tree_test.rb +94 -0
 - data/test/call_tree_visitor_test.rb +1 -6
 - data/test/call_trees_test.rb +6 -6
 - data/test/{basic_test.rb → compatibility_test.rb} +8 -2
 - data/test/duplicate_names_test.rb +5 -5
 - data/test/dynamic_method_test.rb +24 -15
 - data/test/enumerable_test.rb +1 -1
 - data/test/exceptions_test.rb +2 -2
 - data/test/exclude_methods_test.rb +3 -8
 - data/test/exclude_threads_test.rb +4 -9
 - data/test/fiber_test.rb +74 -8
 - data/test/gc_test.rb +11 -9
 - data/test/inverse_call_tree_test.rb +33 -34
 - data/test/line_number_test.rb +37 -61
 - data/test/marshal_test.rb +16 -3
 - data/test/measure_allocations.rb +1 -5
 - data/test/measure_allocations_test.rb +642 -357
 - data/test/{measure_memory_trace_test.rb → measure_memory_test.rb} +180 -616
 - data/test/measure_process_time_test.rb +1566 -741
 - data/test/measure_wall_time_test.rb +179 -193
 - data/test/measurement_test.rb +82 -0
 - data/test/merge_test.rb +146 -0
 - data/test/method_info_test.rb +95 -0
 - data/test/multi_printer_test.rb +0 -5
 - data/test/no_method_class_test.rb +1 -1
 - data/test/pause_resume_test.rb +12 -16
 - data/test/printer_call_stack_test.rb +2 -2
 - data/test/printer_call_tree_test.rb +4 -4
 - data/test/printer_flat_test.rb +1 -1
 - data/test/printer_graph_html_test.rb +2 -2
 - data/test/printer_graph_test.rb +2 -2
 - data/test/printers_test.rb +14 -20
 - data/test/printing_recursive_graph_test.rb +2 -2
 - data/test/profile_test.rb +85 -0
 - data/test/recursive_test.rb +374 -155
 - data/test/scheduler.rb +363 -0
 - data/test/singleton_test.rb +1 -1
 - data/test/stack_printer_test.rb +5 -8
 - data/test/start_stop_test.rb +11 -14
 - data/test/test_helper.rb +11 -8
 - data/test/thread_test.rb +106 -15
 - data/test/unique_call_path_test.rb +28 -12
 - data/test/yarv_test.rb +11 -7
 - metadata +17 -29
 - data/ext/ruby_prof/rp_aggregate_call_tree.c +0 -59
 - data/ext/ruby_prof/rp_aggregate_call_tree.h +0 -13
 - data/test/measure_allocations_trace_test.rb +0 -375
 - data/test/temp.rb +0 -20
 
| 
         @@ -2,32 +2,11 @@ 
     | 
|
| 
       2 
2 
     | 
    
         
             
               Please see the LICENSE file for copyright and distribution information */
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            #include "rp_allocation.h"
         
     | 
| 
      
 5 
     | 
    
         
            +
            #include "rp_method.h"
         
     | 
| 
       5 
6 
     | 
    
         | 
| 
       6 
7 
     | 
    
         
             
            VALUE cRpAllocation;
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
            {
         
     | 
| 
       10 
     | 
    
         
            -
                prof_allocation_t* result = NULL;
         
     | 
| 
       11 
     | 
    
         
            -
                st_data_t value;
         
     | 
| 
       12 
     | 
    
         
            -
                if (rb_st_lookup(table, key, &value))
         
     | 
| 
       13 
     | 
    
         
            -
                {
         
     | 
| 
       14 
     | 
    
         
            -
                    result = (prof_allocation_t*)value;
         
     | 
| 
       15 
     | 
    
         
            -
                }
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
                return result;
         
     | 
| 
       18 
     | 
    
         
            -
            }
         
     | 
| 
       19 
     | 
    
         
            -
             
     | 
| 
       20 
     | 
    
         
            -
            void allocations_table_insert(st_table* table, st_data_t key, prof_allocation_t* allocation)
         
     | 
| 
       21 
     | 
    
         
            -
            {
         
     | 
| 
       22 
     | 
    
         
            -
                rb_st_insert(table, (st_data_t)key, (st_data_t)allocation);
         
     | 
| 
       23 
     | 
    
         
            -
            }
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
            st_data_t allocations_key(VALUE klass, int source_line)
         
     | 
| 
       26 
     | 
    
         
            -
            {
         
     | 
| 
       27 
     | 
    
         
            -
                return (klass << 4) + source_line;
         
     | 
| 
       28 
     | 
    
         
            -
            }
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            /* ======   prof_allocation_t  ====== */
         
     | 
| 
      
 9 
     | 
    
         
            +
            // ------ prof_allocation_t ------
         
     | 
| 
       31 
10 
     | 
    
         
             
            prof_allocation_t* prof_allocation_create(void)
         
     | 
| 
       32 
11 
     | 
    
         
             
            {
         
     | 
| 
       33 
12 
     | 
    
         
             
                prof_allocation_t* result = ALLOC(prof_allocation_t);
         
     | 
| 
         @@ -43,48 +22,17 @@ prof_allocation_t* prof_allocation_create(void) 
     | 
|
| 
       43 
22 
     | 
    
         
             
                return result;
         
     | 
| 
       44 
23 
     | 
    
         
             
            }
         
     | 
| 
       45 
24 
     | 
    
         | 
| 
       46 
     | 
    
         
            -
            prof_allocation_t*  
     | 
| 
      
 25 
     | 
    
         
            +
            prof_allocation_t* prof_allocation_get(VALUE self)
         
     | 
| 
       47 
26 
     | 
    
         
             
            {
         
     | 
| 
       48 
27 
     | 
    
         
             
                /* Can't use Data_Get_Struct because that triggers the event hook
         
     | 
| 
       49 
28 
     | 
    
         
             
                   ending up in endless recursion. */
         
     | 
| 
       50 
29 
     | 
    
         
             
                prof_allocation_t* result = RTYPEDDATA_DATA(self);
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
       52 
30 
     | 
    
         
             
                if (!result)
         
     | 
| 
       53 
31 
     | 
    
         
             
                    rb_raise(rb_eRuntimeError, "This RubyProf::Allocation instance has already been freed, likely because its profile has been freed.");
         
     | 
| 
       54 
32 
     | 
    
         | 
| 
       55 
33 
     | 
    
         
             
                return result;
         
     | 
| 
       56 
34 
     | 
    
         
             
            }
         
     | 
| 
       57 
35 
     | 
    
         | 
| 
       58 
     | 
    
         
            -
            prof_allocation_t* prof_allocate_increment(prof_method_t* method, rb_trace_arg_t* trace_arg)
         
     | 
| 
       59 
     | 
    
         
            -
            {
         
     | 
| 
       60 
     | 
    
         
            -
                VALUE object = rb_tracearg_object(trace_arg);
         
     | 
| 
       61 
     | 
    
         
            -
                if (BUILTIN_TYPE(object) == T_IMEMO)
         
     | 
| 
       62 
     | 
    
         
            -
                    return NULL;
         
     | 
| 
       63 
     | 
    
         
            -
             
     | 
| 
       64 
     | 
    
         
            -
                VALUE klass = rb_obj_class(object);
         
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
       66 
     | 
    
         
            -
                int source_line = FIX2INT(rb_tracearg_lineno(trace_arg));
         
     | 
| 
       67 
     | 
    
         
            -
                st_data_t key = allocations_key(klass, source_line);
         
     | 
| 
       68 
     | 
    
         
            -
             
     | 
| 
       69 
     | 
    
         
            -
                prof_allocation_t* allocation = allocations_table_lookup(method->allocations_table, key);
         
     | 
| 
       70 
     | 
    
         
            -
                if (!allocation)
         
     | 
| 
       71 
     | 
    
         
            -
                {
         
     | 
| 
       72 
     | 
    
         
            -
                    allocation = prof_allocation_create();
         
     | 
| 
       73 
     | 
    
         
            -
                    allocation->source_line = source_line;
         
     | 
| 
       74 
     | 
    
         
            -
                    allocation->source_file = rb_tracearg_path(trace_arg);
         
     | 
| 
       75 
     | 
    
         
            -
                    allocation->klass_flags = 0;
         
     | 
| 
       76 
     | 
    
         
            -
                    allocation->klass = resolve_klass(klass, &allocation->klass_flags);
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
       78 
     | 
    
         
            -
                    allocation->key = key;
         
     | 
| 
       79 
     | 
    
         
            -
                    allocations_table_insert(method->allocations_table, key, allocation);
         
     | 
| 
       80 
     | 
    
         
            -
                }
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
       82 
     | 
    
         
            -
                allocation->count++;
         
     | 
| 
       83 
     | 
    
         
            -
                allocation->memory += rb_obj_memsize_of(object);
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
       85 
     | 
    
         
            -
                return allocation;
         
     | 
| 
       86 
     | 
    
         
            -
            }
         
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
       88 
36 
     | 
    
         
             
            static void prof_allocation_ruby_gc_free(void* data)
         
     | 
| 
       89 
37 
     | 
    
         
             
            {
         
     | 
| 
       90 
38 
     | 
    
         
             
                if (data)
         
     | 
| 
         @@ -118,30 +66,39 @@ void prof_allocation_mark(void* data) 
     | 
|
| 
       118 
66 
     | 
    
         | 
| 
       119 
67 
     | 
    
         
             
                prof_allocation_t* allocation = (prof_allocation_t*)data;
         
     | 
| 
       120 
68 
     | 
    
         
             
                if (allocation->object != Qnil)
         
     | 
| 
       121 
     | 
    
         
            -
                     
     | 
| 
      
 69 
     | 
    
         
            +
                    rb_gc_mark_movable(allocation->object);
         
     | 
| 
       122 
70 
     | 
    
         | 
| 
       123 
71 
     | 
    
         
             
                if (allocation->klass != Qnil)
         
     | 
| 
       124 
     | 
    
         
            -
                     
     | 
| 
      
 72 
     | 
    
         
            +
                    rb_gc_mark_movable(allocation->klass);
         
     | 
| 
       125 
73 
     | 
    
         | 
| 
       126 
74 
     | 
    
         
             
                if (allocation->klass_name != Qnil)
         
     | 
| 
       127 
     | 
    
         
            -
                     
     | 
| 
      
 75 
     | 
    
         
            +
                    rb_gc_mark_movable(allocation->klass_name);
         
     | 
| 
       128 
76 
     | 
    
         | 
| 
       129 
77 
     | 
    
         
             
                if (allocation->source_file != Qnil)
         
     | 
| 
       130 
78 
     | 
    
         
             
                    rb_gc_mark(allocation->source_file);
         
     | 
| 
       131 
79 
     | 
    
         
             
            }
         
     | 
| 
       132 
80 
     | 
    
         | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
      
 81 
     | 
    
         
            +
            void prof_allocation_compact(void* data)
         
     | 
| 
       134 
82 
     | 
    
         
             
            {
         
     | 
| 
       135 
     | 
    
         
            -
                 
     | 
| 
       136 
     | 
    
         
            -
                 
     | 
| 
       137 
     | 
    
         
            -
                 
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
     | 
    
         
            -
             
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
       141 
     | 
    
         
            -
             
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
             
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
      
 83 
     | 
    
         
            +
                prof_allocation_t* allocation = (prof_allocation_t*)data;
         
     | 
| 
      
 84 
     | 
    
         
            +
                allocation->object = rb_gc_location(allocation->object);
         
     | 
| 
      
 85 
     | 
    
         
            +
                allocation->klass = rb_gc_location(allocation->klass);
         
     | 
| 
      
 86 
     | 
    
         
            +
                allocation->klass_name = rb_gc_location(allocation->klass_name);
         
     | 
| 
      
 87 
     | 
    
         
            +
            }
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            static const rb_data_type_t allocation_type =
         
     | 
| 
      
 90 
     | 
    
         
            +
                    {
         
     | 
| 
      
 91 
     | 
    
         
            +
                            .wrap_struct_name = "Allocation",
         
     | 
| 
      
 92 
     | 
    
         
            +
                            .function =
         
     | 
| 
      
 93 
     | 
    
         
            +
                                    {
         
     | 
| 
      
 94 
     | 
    
         
            +
                                            .dmark = prof_allocation_mark,
         
     | 
| 
      
 95 
     | 
    
         
            +
                                            .dfree = prof_allocation_ruby_gc_free,
         
     | 
| 
      
 96 
     | 
    
         
            +
                                            .dsize = prof_allocation_size,
         
     | 
| 
      
 97 
     | 
    
         
            +
                                            .dcompact = prof_allocation_compact
         
     | 
| 
      
 98 
     | 
    
         
            +
                                    },
         
     | 
| 
      
 99 
     | 
    
         
            +
                            .data = NULL,
         
     | 
| 
      
 100 
     | 
    
         
            +
                            .flags = RUBY_TYPED_FREE_IMMEDIATELY
         
     | 
| 
      
 101 
     | 
    
         
            +
                    };
         
     | 
| 
       145 
102 
     | 
    
         | 
| 
       146 
103 
     | 
    
         
             
            VALUE prof_allocation_wrap(prof_allocation_t* allocation)
         
     | 
| 
       147 
104 
     | 
    
         
             
            {
         
     | 
| 
         @@ -152,24 +109,122 @@ VALUE prof_allocation_wrap(prof_allocation_t* allocation) 
     | 
|
| 
       152 
109 
     | 
    
         
             
                return allocation->object;
         
     | 
| 
       153 
110 
     | 
    
         
             
            }
         
     | 
| 
       154 
111 
     | 
    
         | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
      
 112 
     | 
    
         
            +
            /* ======   Allocation Table  ====== */
         
     | 
| 
      
 113 
     | 
    
         
            +
            st_table* prof_allocations_create()
         
     | 
| 
       156 
114 
     | 
    
         
             
            {
         
     | 
| 
       157 
     | 
    
         
            -
                 
     | 
| 
       158 
     | 
    
         
            -
                allocation->object = prof_allocation_wrap(allocation);
         
     | 
| 
       159 
     | 
    
         
            -
                return allocation->object;
         
     | 
| 
      
 115 
     | 
    
         
            +
                return rb_st_init_numtable();
         
     | 
| 
       160 
116 
     | 
    
         
             
            }
         
     | 
| 
       161 
117 
     | 
    
         | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
      
 118 
     | 
    
         
            +
            static int allocations_table_free_iterator(st_data_t key, st_data_t value, st_data_t dummy)
         
     | 
| 
       163 
119 
     | 
    
         
             
            {
         
     | 
| 
       164 
     | 
    
         
            -
                 
     | 
| 
       165 
     | 
    
         
            -
             
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
             
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
      
 120 
     | 
    
         
            +
                prof_allocation_free((prof_allocation_t*)value);
         
     | 
| 
      
 121 
     | 
    
         
            +
                return ST_CONTINUE;
         
     | 
| 
      
 122 
     | 
    
         
            +
            }
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            st_data_t allocations_key(VALUE klass, int source_line)
         
     | 
| 
      
 125 
     | 
    
         
            +
            {
         
     | 
| 
      
 126 
     | 
    
         
            +
                return (klass << 4) + source_line;
         
     | 
| 
      
 127 
     | 
    
         
            +
            }
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
            static int prof_allocations_collect(st_data_t key, st_data_t value, st_data_t result)
         
     | 
| 
      
 130 
     | 
    
         
            +
            {
         
     | 
| 
      
 131 
     | 
    
         
            +
                prof_allocation_t* allocation = (prof_allocation_t*)value;
         
     | 
| 
      
 132 
     | 
    
         
            +
                VALUE arr = (VALUE)result;
         
     | 
| 
      
 133 
     | 
    
         
            +
                rb_ary_push(arr, prof_allocation_wrap(allocation));
         
     | 
| 
      
 134 
     | 
    
         
            +
                return ST_CONTINUE;
         
     | 
| 
      
 135 
     | 
    
         
            +
            }
         
     | 
| 
      
 136 
     | 
    
         
            +
             
     | 
| 
      
 137 
     | 
    
         
            +
            static int prof_allocations_mark_each(st_data_t key, st_data_t value, st_data_t data)
         
     | 
| 
      
 138 
     | 
    
         
            +
            {
         
     | 
| 
      
 139 
     | 
    
         
            +
                prof_allocation_t* allocation = (prof_allocation_t*)value;
         
     | 
| 
      
 140 
     | 
    
         
            +
                prof_allocation_mark(allocation);
         
     | 
| 
      
 141 
     | 
    
         
            +
                return ST_CONTINUE;
         
     | 
| 
      
 142 
     | 
    
         
            +
            }
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
            void prof_allocations_mark(st_table* allocations_table)
         
     | 
| 
      
 145 
     | 
    
         
            +
            {
         
     | 
| 
      
 146 
     | 
    
         
            +
                rb_st_foreach(allocations_table, prof_allocations_mark_each, 0);
         
     | 
| 
      
 147 
     | 
    
         
            +
            }
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
            void prof_allocations_free(st_table* table)
         
     | 
| 
      
 150 
     | 
    
         
            +
            {
         
     | 
| 
      
 151 
     | 
    
         
            +
                rb_st_foreach(table, allocations_table_free_iterator, 0);
         
     | 
| 
      
 152 
     | 
    
         
            +
                rb_st_free_table(table);
         
     | 
| 
      
 153 
     | 
    
         
            +
            }
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            prof_allocation_t* allocations_table_lookup(st_table* table, st_data_t key)
         
     | 
| 
      
 156 
     | 
    
         
            +
            {
         
     | 
| 
      
 157 
     | 
    
         
            +
                prof_allocation_t* result = NULL;
         
     | 
| 
      
 158 
     | 
    
         
            +
                st_data_t value;
         
     | 
| 
      
 159 
     | 
    
         
            +
                if (rb_st_lookup(table, key, &value))
         
     | 
| 
      
 160 
     | 
    
         
            +
                {
         
     | 
| 
      
 161 
     | 
    
         
            +
                    result = (prof_allocation_t*)value;
         
     | 
| 
      
 162 
     | 
    
         
            +
                }
         
     | 
| 
       169 
163 
     | 
    
         | 
| 
       170 
164 
     | 
    
         
             
                return result;
         
     | 
| 
       171 
165 
     | 
    
         
             
            }
         
     | 
| 
       172 
166 
     | 
    
         | 
| 
      
 167 
     | 
    
         
            +
            void allocations_table_insert(st_table* table, st_data_t key, prof_allocation_t* allocation)
         
     | 
| 
      
 168 
     | 
    
         
            +
            {
         
     | 
| 
      
 169 
     | 
    
         
            +
                rb_st_insert(table, (st_data_t)key, (st_data_t)allocation);
         
     | 
| 
      
 170 
     | 
    
         
            +
            }
         
     | 
| 
      
 171 
     | 
    
         
            +
             
     | 
| 
      
 172 
     | 
    
         
            +
            prof_allocation_t* prof_allocate_increment(st_table* allocations_table, rb_trace_arg_t* trace_arg)
         
     | 
| 
      
 173 
     | 
    
         
            +
            {
         
     | 
| 
      
 174 
     | 
    
         
            +
                VALUE object = rb_tracearg_object(trace_arg);
         
     | 
| 
      
 175 
     | 
    
         
            +
                if (BUILTIN_TYPE(object) == T_IMEMO)
         
     | 
| 
      
 176 
     | 
    
         
            +
                    return NULL;
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
                VALUE klass = rb_obj_class(object);
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
                int source_line = FIX2INT(rb_tracearg_lineno(trace_arg));
         
     | 
| 
      
 181 
     | 
    
         
            +
                st_data_t key = allocations_key(klass, source_line);
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                prof_allocation_t* allocation = allocations_table_lookup(allocations_table, key);
         
     | 
| 
      
 184 
     | 
    
         
            +
                if (!allocation)
         
     | 
| 
      
 185 
     | 
    
         
            +
                {
         
     | 
| 
      
 186 
     | 
    
         
            +
                    allocation = prof_allocation_create();
         
     | 
| 
      
 187 
     | 
    
         
            +
                    allocation->source_line = source_line;
         
     | 
| 
      
 188 
     | 
    
         
            +
                    allocation->source_file = rb_tracearg_path(trace_arg);
         
     | 
| 
      
 189 
     | 
    
         
            +
                    allocation->klass_flags = 0;
         
     | 
| 
      
 190 
     | 
    
         
            +
                    allocation->klass = resolve_klass(klass, &allocation->klass_flags);
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
                    allocation->key = key;
         
     | 
| 
      
 193 
     | 
    
         
            +
                    allocations_table_insert(allocations_table, key, allocation);
         
     | 
| 
      
 194 
     | 
    
         
            +
                }
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
                allocation->count++;
         
     | 
| 
      
 197 
     | 
    
         
            +
                allocation->memory += rb_obj_memsize_of(object);
         
     | 
| 
      
 198 
     | 
    
         
            +
             
     | 
| 
      
 199 
     | 
    
         
            +
                return allocation;
         
     | 
| 
      
 200 
     | 
    
         
            +
            }
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
            // Returns an array of allocations
         
     | 
| 
      
 203 
     | 
    
         
            +
            VALUE prof_allocations_wrap(st_table* allocations_table)
         
     | 
| 
      
 204 
     | 
    
         
            +
            {
         
     | 
| 
      
 205 
     | 
    
         
            +
                VALUE result = rb_ary_new();
         
     | 
| 
      
 206 
     | 
    
         
            +
                rb_st_foreach(allocations_table, prof_allocations_collect, result);
         
     | 
| 
      
 207 
     | 
    
         
            +
                return result;
         
     | 
| 
      
 208 
     | 
    
         
            +
            }
         
     | 
| 
      
 209 
     | 
    
         
            +
             
     | 
| 
      
 210 
     | 
    
         
            +
            void prof_allocations_unwrap(st_table* allocations_table, VALUE allocations)
         
     | 
| 
      
 211 
     | 
    
         
            +
            {
         
     | 
| 
      
 212 
     | 
    
         
            +
                for (int i = 0; i < rb_array_len(allocations); i++)
         
     | 
| 
      
 213 
     | 
    
         
            +
                {
         
     | 
| 
      
 214 
     | 
    
         
            +
                    VALUE allocation = rb_ary_entry(allocations, i);
         
     | 
| 
      
 215 
     | 
    
         
            +
                    prof_allocation_t* allocation_data = prof_allocation_get(allocation);
         
     | 
| 
      
 216 
     | 
    
         
            +
                    rb_st_insert(allocations_table, allocation_data->key, (st_data_t)allocation_data);
         
     | 
| 
      
 217 
     | 
    
         
            +
                }
         
     | 
| 
      
 218 
     | 
    
         
            +
            }
         
     | 
| 
      
 219 
     | 
    
         
            +
             
     | 
| 
      
 220 
     | 
    
         
            +
            /* ======   prof_allocation_t  ====== */
         
     | 
| 
      
 221 
     | 
    
         
            +
            static VALUE prof_allocation_allocate(VALUE klass)
         
     | 
| 
      
 222 
     | 
    
         
            +
            {
         
     | 
| 
      
 223 
     | 
    
         
            +
                prof_allocation_t* allocation = prof_allocation_create();
         
     | 
| 
      
 224 
     | 
    
         
            +
                allocation->object = prof_allocation_wrap(allocation);
         
     | 
| 
      
 225 
     | 
    
         
            +
                return allocation->object;
         
     | 
| 
      
 226 
     | 
    
         
            +
            }
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
       173 
228 
     | 
    
         
             
            /* call-seq:
         
     | 
| 
       174 
229 
     | 
    
         
             
               klass -> Class
         
     | 
| 
       175 
230 
     | 
    
         | 
| 
         @@ -238,17 +293,17 @@ static VALUE prof_allocation_memory(VALUE self) 
     | 
|
| 
       238 
293 
     | 
    
         
             
            /* :nodoc: */
         
     | 
| 
       239 
294 
     | 
    
         
             
            static VALUE prof_allocation_dump(VALUE self)
         
     | 
| 
       240 
295 
     | 
    
         
             
            {
         
     | 
| 
       241 
     | 
    
         
            -
                prof_allocation_t* allocation =  
     | 
| 
      
 296 
     | 
    
         
            +
                prof_allocation_t* allocation = prof_allocation_get(self);
         
     | 
| 
       242 
297 
     | 
    
         | 
| 
       243 
298 
     | 
    
         
             
                VALUE result = rb_hash_new();
         
     | 
| 
       244 
299 
     | 
    
         | 
| 
       245 
     | 
    
         
            -
                rb_hash_aset(result, ID2SYM(rb_intern("key")),  
     | 
| 
      
 300 
     | 
    
         
            +
                rb_hash_aset(result, ID2SYM(rb_intern("key")), ULL2NUM(allocation->key));
         
     | 
| 
       246 
301 
     | 
    
         
             
                rb_hash_aset(result, ID2SYM(rb_intern("klass_name")), prof_allocation_klass_name(self));
         
     | 
| 
       247 
302 
     | 
    
         
             
                rb_hash_aset(result, ID2SYM(rb_intern("klass_flags")), INT2FIX(allocation->klass_flags));
         
     | 
| 
       248 
303 
     | 
    
         
             
                rb_hash_aset(result, ID2SYM(rb_intern("source_file")), allocation->source_file);
         
     | 
| 
       249 
304 
     | 
    
         
             
                rb_hash_aset(result, ID2SYM(rb_intern("source_line")), INT2FIX(allocation->source_line));
         
     | 
| 
       250 
305 
     | 
    
         
             
                rb_hash_aset(result, ID2SYM(rb_intern("count")), INT2FIX(allocation->count));
         
     | 
| 
       251 
     | 
    
         
            -
                rb_hash_aset(result, ID2SYM(rb_intern("memory")),  
     | 
| 
      
 306 
     | 
    
         
            +
                rb_hash_aset(result, ID2SYM(rb_intern("memory")), ULL2NUM(allocation->memory));
         
     | 
| 
       252 
307 
     | 
    
         | 
| 
       253 
308 
     | 
    
         
             
                return result;
         
     | 
| 
       254 
309 
     | 
    
         
             
            }
         
     | 
| 
         @@ -256,16 +311,16 @@ static VALUE prof_allocation_dump(VALUE self) 
     | 
|
| 
       256 
311 
     | 
    
         
             
            /* :nodoc: */
         
     | 
| 
       257 
312 
     | 
    
         
             
            static VALUE prof_allocation_load(VALUE self, VALUE data)
         
     | 
| 
       258 
313 
     | 
    
         
             
            {
         
     | 
| 
       259 
     | 
    
         
            -
                prof_allocation_t* allocation =  
     | 
| 
      
 314 
     | 
    
         
            +
                prof_allocation_t* allocation = prof_allocation_get(self);
         
     | 
| 
       260 
315 
     | 
    
         
             
                allocation->object = self;
         
     | 
| 
       261 
316 
     | 
    
         | 
| 
       262 
     | 
    
         
            -
                allocation->key =  
     | 
| 
      
 317 
     | 
    
         
            +
                allocation->key = RB_NUM2ULL(rb_hash_aref(data, ID2SYM(rb_intern("key"))));
         
     | 
| 
       263 
318 
     | 
    
         
             
                allocation->klass_name = rb_hash_aref(data, ID2SYM(rb_intern("klass_name")));
         
     | 
| 
       264 
319 
     | 
    
         
             
                allocation->klass_flags = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("klass_flags"))));
         
     | 
| 
       265 
320 
     | 
    
         
             
                allocation->source_file = rb_hash_aref(data, ID2SYM(rb_intern("source_file")));
         
     | 
| 
       266 
321 
     | 
    
         
             
                allocation->source_line = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("source_line"))));
         
     | 
| 
       267 
322 
     | 
    
         
             
                allocation->count = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("count"))));
         
     | 
| 
       268 
     | 
    
         
            -
                allocation->memory =  
     | 
| 
      
 323 
     | 
    
         
            +
                allocation->memory = NUM2ULONG(rb_hash_aref(data, ID2SYM(rb_intern("memory"))));
         
     | 
| 
       269 
324 
     | 
    
         | 
| 
       270 
325 
     | 
    
         
             
                return data;
         
     | 
| 
       271 
326 
     | 
    
         
             
            }
         
     | 
| 
         @@ -5,7 +5,6 @@ 
     | 
|
| 
       5 
5 
     | 
    
         
             
            #define _RP_ALLOCATION_
         
     | 
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            #include "ruby_prof.h"
         
     | 
| 
       8 
     | 
    
         
            -
            #include "rp_method.h"
         
     | 
| 
       9 
8 
     | 
    
         | 
| 
       10 
9 
     | 
    
         
             
            typedef struct prof_allocation_t
         
     | 
| 
       11 
10 
     | 
    
         
             
            {
         
     | 
| 
         @@ -20,12 +19,15 @@ typedef struct prof_allocation_t 
     | 
|
| 
       20 
19 
     | 
    
         
             
                VALUE object;                     /* Cache to wrapped object */
         
     | 
| 
       21 
20 
     | 
    
         
             
            } prof_allocation_t;
         
     | 
| 
       22 
21 
     | 
    
         | 
| 
      
 22 
     | 
    
         
            +
            // Allocation (prof_allocation_t*)
         
     | 
| 
       23 
23 
     | 
    
         
             
            void rp_init_allocation(void);
         
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
            void prof_allocation_mark(void* data);
         
     | 
| 
       26 
     | 
    
         
            -
            VALUE prof_allocation_wrap(prof_allocation_t* allocation);
         
     | 
| 
       27 
     | 
    
         
            -
            prof_allocation_t* prof_allocation_get(VALUE self);
         
     | 
| 
       28 
     | 
    
         
            -
            prof_allocation_t* prof_allocate_increment(prof_method_t* method, rb_trace_arg_t* trace_arg);
         
     | 
| 
      
 24 
     | 
    
         
            +
            prof_allocation_t* prof_allocate_increment(st_table* allocations_table, rb_trace_arg_t* trace_arg);
         
     | 
| 
       29 
25 
     | 
    
         | 
| 
      
 26 
     | 
    
         
            +
            // Allocations (st_table*)
         
     | 
| 
      
 27 
     | 
    
         
            +
            st_table* prof_allocations_create(void);
         
     | 
| 
      
 28 
     | 
    
         
            +
            VALUE prof_allocations_wrap(st_table* allocations_table);
         
     | 
| 
      
 29 
     | 
    
         
            +
            void prof_allocations_unwrap(st_table* allocations_table, VALUE allocations);
         
     | 
| 
      
 30 
     | 
    
         
            +
            void prof_allocations_mark(st_table* allocations_table);
         
     | 
| 
      
 31 
     | 
    
         
            +
            void prof_allocations_free(st_table* table);
         
     | 
| 
       30 
32 
     | 
    
         | 
| 
       31 
33 
     | 
    
         
             
            #endif //_RP_ALLOCATION_
         
     |