show_bug.rb

Script to reproduce the bug - Brian Durand, 12/18/2010 01:57 AM

Download (1.71 KB)

 
1
require 'weakref'
2

    
3
def test_weak_references(klass, iterations)
4
  puts "Testing if object id's can be reused by #{klass}..."
5
  i = 0
6
  n = 0
7
  id_to_ref = {}
8
  failures = 0
9
  iterations = 100000 if iterations <= 0
10
  
11
  iterations.times do
12
    i += 1
13
    obj = Object.new
14

    
15
    if id_to_ref.key?(obj.object_id)
16
      n += 1
17
      ref = id_to_ref[obj.object_id]
18
      if ref.weakref_alive?
19
        STDOUT.write('x')
20
        STDOUT.flush
21
        failures += 1
22
      end
23
    end
24

    
25
    ref = klass.new(obj)
26
    id_to_ref[obj.object_id] = ref
27
    raise "#{klass} did not return the correct object!" unless (klass.name == "WeakReference" ? ref.object : ref.__getobj__) == obj
28
    if i % 5000 == 0
29
      STDOUT.write('.')
30
      STDOUT.flush
31
    end
32
  end
33
  STDOUT.write("\n")
34
  
35
  collected = n
36
  id_to_ref.values.each do |ref|
37
    collected += 1 if ref.weakref_alive?
38
  end
39
  puts "#{collected} instances out of #{iterations} (#{((collected.to_f / iterations) * 100).round}%) objects refererenced by #{klass} were reclaimed by the garbage collector"
40
  
41
  if failures == 0
42
    puts "SUCCESS: even with #{n} object id's being reused in #{iterations} iterations"
43
  else
44
    puts "FAILURE: #{failures} instances of object ids being incorrectly referenced in #{iterations} iterations"
45
  end
46
end
47

    
48
if $0 == __FILE__
49
  iterations = ARGV.first.to_i
50
  if defined?(WeakReference)
51
    # Compatibilty hack to make WeakReference duck type like a WeakRef for the test.
52
    module WeakRefCompatibility
53
      def __getobj__
54
        object
55
      end
56
      
57
      def weakref_alive?
58
        object != nil
59
      end
60
    end
61
    WeakReference.send(:include, WeakRefCompatibility)
62
    test_weak_references WeakReference, iterations
63
  end
64
  test_weak_references WeakRef, iterations
65
end