Class: RubyProf::CallTree

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby-prof/call_tree.rb,
ext/ruby_prof/rp_call_tree.c

Overview

The CallTree class is used to track the relationships between methods. It is a helper class used by RubyProf::MethodInfo to keep track of which methods called a given method and which methods a given method called. Each CallTree has a parent and target method. You cannot create a CallTree object directly, they are generated while running a profile.

Instance Method Summary collapse

Constructor Details

#new(method_info) ⇒ Object

Creates a new CallTree instance. Klass should be a reference to a Ruby class and method_name a symbol identifying one of its instance methods.



228
229
230
231
232
233
234
# File 'ext/ruby_prof/rp_call_tree.c', line 228

static VALUE prof_call_tree_initialize(VALUE self, VALUE method_info)
{
  prof_call_tree_t* call_tree_ptr = prof_get_call_tree(self);
  call_tree_ptr->method = prof_get_method(method_info);

  return self;
}

Instance Method Details

#<=>(other) ⇒ Object

Compares two CallTree instances. The comparison is based on the CallTree#parent, CallTree#target, and total time.



36
37
38
39
40
41
42
43
44
45
46
# File 'lib/ruby-prof/call_tree.rb', line 36

def <=>(other)
  if self.target == other.target && self.parent == other.parent
    0
  elsif self.total_time < other.total_time
    -1
  elsif self.total_time > other.total_time
    1
  else
    self.target.full_name <=> other.target.full_name
  end
end

#_dump_dataObject

:nodoc:



388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'ext/ruby_prof/rp_call_tree.c', line 388

static VALUE prof_call_tree_dump(VALUE self)
{
    prof_call_tree_t* call_tree_data = prof_get_call_tree(self);
    VALUE result = rb_hash_new();

    rb_hash_aset(result, ID2SYM(rb_intern("owner")), INT2FIX(call_tree_data->owner));

    rb_hash_aset(result, ID2SYM(rb_intern("measurement")), prof_measurement_wrap(call_tree_data->measurement));

    rb_hash_aset(result, ID2SYM(rb_intern("source_file")), call_tree_data->source_file);
    rb_hash_aset(result, ID2SYM(rb_intern("source_line")), INT2FIX(call_tree_data->source_line));

    rb_hash_aset(result, ID2SYM(rb_intern("parent")), prof_call_tree_parent(self));
    rb_hash_aset(result, ID2SYM(rb_intern("children")), prof_call_tree_children(self));
    rb_hash_aset(result, ID2SYM(rb_intern("target")), prof_call_tree_target(self));

    return result;
}

#_load_data(data) ⇒ Object

:nodoc:



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
# File 'ext/ruby_prof/rp_call_tree.c', line 408

static VALUE prof_call_tree_load(VALUE self, VALUE data)
{
    VALUE target = Qnil;
    VALUE parent = Qnil;
    prof_call_tree_t* call_tree = prof_get_call_tree(self);
    call_tree->object = self;

    call_tree->owner = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("owner"))));

    VALUE measurement = rb_hash_aref(data, ID2SYM(rb_intern("measurement")));
    call_tree->measurement = prof_get_measurement(measurement);

    call_tree->source_file = rb_hash_aref(data, ID2SYM(rb_intern("source_file")));
    call_tree->source_line = FIX2INT(rb_hash_aref(data, ID2SYM(rb_intern("source_line"))));

    parent = rb_hash_aref(data, ID2SYM(rb_intern("parent")));
    if (parent != Qnil)
        call_tree->parent = prof_get_call_tree(parent);

    VALUE callees = rb_hash_aref(data, ID2SYM(rb_intern("children")));
    for (int i = 0; i < rb_array_len(callees); i++)
    {
        VALUE call_tree_object = rb_ary_entry(callees, i);
        prof_call_tree_t* call_tree_data = prof_get_call_tree(call_tree_object);

        st_data_t key = call_tree_data->method ? call_tree_data->method->key : method_key(Qnil, 0);
        call_tree_table_insert(call_tree->children, key, call_tree_data);
    }

    target = rb_hash_aref(data, ID2SYM(rb_intern("target")));
    call_tree->method = prof_get_method(target);

    return data;
}

#add_child(call_tree) ⇒ Object

Adds the specified call_tree as a child. If the method represented by the call tree is already a child than a IndexError is thrown.

The returned value is the added child



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'ext/ruby_prof/rp_call_tree.c', line 268

static VALUE prof_call_tree_add_child_ruby(VALUE self, VALUE child)
{
  prof_call_tree_t* parent_ptr = prof_get_call_tree(self);
  prof_call_tree_t* child_ptr = prof_get_call_tree(child);

  prof_call_tree_t* existing_ptr = call_tree_table_lookup(parent_ptr->children, child_ptr->method->key);
  if (existing_ptr)
  {
    rb_raise(rb_eIndexError, "Child call tree already exists");
  }

  prof_call_tree_add_parent(child_ptr, parent_ptr);

  return child;
}

#calledObject

The number of times the parent method called the target method



10
11
12
# File 'lib/ruby-prof/call_tree.rb', line 10

def called
  self.measurement.called
end

#calleesArray

Returns an array of call info objects that this method called (ie, children).

Returns:

  • (Array)


253
254
255
256
257
258
259
# File 'ext/ruby_prof/rp_call_tree.c', line 253

static VALUE prof_call_tree_children(VALUE self)
{
    prof_call_tree_t* call_tree = prof_get_call_tree(self);
    VALUE result = rb_ary_new();
    rb_st_foreach(call_tree->children, prof_call_tree_collect_children, result);
    return result;
}

#children_timeObject

The time spent in child methods resulting from the parent method calling the target method



30
31
32
# File 'lib/ruby-prof/call_tree.rb', line 30

def children_time
  self.total_time - self.self_time - self.wait_time
end

#depthInteger

returns the depth of this call info in the call graph

Returns:

  • (Integer)


308
309
310
311
312
313
# File 'ext/ruby_prof/rp_call_tree.c', line 308

static VALUE prof_call_tree_depth(VALUE self)
{
    prof_call_tree_t* call_tree_data = prof_get_call_tree(self);
    uint32_t depth = prof_call_figure_depth(call_tree_data);
    return rb_int_new(depth);
}

#inspectObject



53
54
55
# File 'lib/ruby-prof/call_tree.rb', line 53

def inspect
  self.to_s
end

#line_noInteger

returns the line number of the method

Returns:

  • (Integer)


330
331
332
333
334
# File 'ext/ruby_prof/rp_call_tree.c', line 330

static VALUE prof_call_tree_line(VALUE self)
{
    prof_call_tree_t* result = prof_get_call_tree(self);
    return INT2FIX(result->source_line);
}

#calledMeasurement

Returns the measurement associated with this call_tree.

Returns:



298
299
300
301
302
# File 'ext/ruby_prof/rp_call_tree.c', line 298

static VALUE prof_call_tree_measurement(VALUE self)
{
    prof_call_tree_t* call_tree = prof_get_call_tree(self);
    return prof_measurement_wrap(call_tree->measurement);
}

#merge!(other) ⇒ Object



379
380
381
382
383
384
385
# File 'ext/ruby_prof/rp_call_tree.c', line 379

VALUE prof_call_tree_merge(VALUE self, VALUE other)
{
  prof_call_tree_t* source = prof_get_call_tree(self);
  prof_call_tree_t* destination = prof_get_call_tree(other);
  prof_call_tree_merge_internal(source, destination);
  return other;
}

#parentObject

Returns the CallTree parent call_tree object (the method that called this method).



240
241
242
243
244
245
246
247
# File 'ext/ruby_prof/rp_call_tree.c', line 240

static VALUE prof_call_tree_parent(VALUE self)
{
    prof_call_tree_t* call_tree = prof_get_call_tree(self);
    if (call_tree->parent)
        return prof_call_tree_wrap(call_tree->parent);
    else
        return Qnil;
}

#self_timeObject

The self time (of the parent) resulting from the parent method calling the target method



20
21
22
# File 'lib/ruby-prof/call_tree.rb', line 20

def self_time
  self.measurement.self_time
end

#source_fileString

return the source file of the method

Returns:

  • (String)


320
321
322
323
324
# File 'ext/ruby_prof/rp_call_tree.c', line 320

static VALUE prof_call_tree_source_file(VALUE self)
{
    prof_call_tree_t* result = prof_get_call_tree(self);
    return result->source_file;
}

#calledMethodInfo

Returns the target method.

Returns:



288
289
290
291
292
# File 'ext/ruby_prof/rp_call_tree.c', line 288

static VALUE prof_call_tree_target(VALUE self)
{
    prof_call_tree_t* call_tree = prof_get_call_tree(self);
    return prof_method_wrap(call_tree->method);
}

#to_sObject

:nodoc:



49
50
51
# File 'lib/ruby-prof/call_tree.rb', line 49

def to_s
  "<#{self.class.name} - #{self.target.full_name}>"
end

#total_timeObject

The total time resulting from the parent method calling the target method



15
16
17
# File 'lib/ruby-prof/call_tree.rb', line 15

def total_time
  self.measurement.total_time
end

#wait_timeObject

The wait time (of the parent) resulting from the parent method calling the target method



25
26
27
# File 'lib/ruby-prof/call_tree.rb', line 25

def wait_time
  self.measurement.wait_time
end