bleak_house 4.6 → 5
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.
- data/CHANGELOG +8 -61
- data/{LICENSE → LICENSE_AFL} +0 -0
- data/Manifest +22 -21
- data/README +25 -109
- data/Rakefile +101 -9
- data/init.rb +2 -0
- data/install.rb +7 -0
- data/lib/bleak_house.rb +8 -17
- data/{LICENSE_BSD → lib/bleak_house/LICENSE_BSD} +0 -0
- data/lib/bleak_house/action_controller.rb +16 -0
- data/lib/bleak_house/analyze.rb +135 -0
- data/lib/bleak_house/bleak_house.rb +43 -0
- data/lib/bleak_house/c.rb +184 -0
- data/lib/bleak_house/dispatcher.rb +20 -0
- data/lib/bleak_house/gruff_hacks.rb +62 -0
- data/lib/bleak_house/mem_logger.rb +15 -0
- data/lib/bleak_house/rake_task_redefine_task.rb +25 -0
- data/lib/bleak_house/ruby.rb +46 -0
- data/lib/bleak_house/support_methods.rb +47 -0
- data/patches/gc.c.patch +30 -0
- data/tasks/bleak_house_tasks.rake +14 -0
- data/test/unit/test_bleak_house.rb +31 -41
- metadata +81 -101
- data.tar.gz.sig +0 -0
- data/TODO +0 -10
- data/bin/bleak +0 -13
- data/bleak_house.gemspec +0 -36
- data/ext/build_ruby.rb +0 -114
- data/ext/build_snapshot.rb +0 -5
- data/ext/extconf.rb +0 -26
- data/ext/snapshot.c +0 -151
- data/ext/snapshot.h +0 -59
- data/lib/bleak_house/analyzer.rb +0 -54
- data/lib/bleak_house/hook.rb +0 -24
- data/ruby/ruby-1.8.7-p174.tar.bz2 +0 -0
- data/ruby/ruby-1.8.7.patch +0 -483
- data/test/benchmark/bench.rb +0 -16
- data/test/test_helper.rb +0 -6
- metadata.gz.sig +0 -0
    
        data/ext/build_snapshot.rb
    DELETED
    
    
    
        data/ext/extconf.rb
    DELETED
    
    | @@ -1,26 +0,0 @@ | |
| 1 | 
            -
            require 'fileutils'
         | 
| 2 | 
            -
             | 
| 3 | 
            -
            module BleakHouse
         | 
| 4 | 
            -
             | 
| 5 | 
            -
              LOGDIR = File.expand_path('../../log', __FILE__)
         | 
| 6 | 
            -
              LOGFILE = File.join(LOGDIR, 'bleak_house.log')
         | 
| 7 | 
            -
              
         | 
| 8 | 
            -
              FileUtils.mkdir_p(LOGDIR)
         | 
| 9 | 
            -
              
         | 
| 10 | 
            -
              def self.write_to_log(message)
         | 
| 11 | 
            -
                File.open(LOGFILE, 'a') { |f| f.puts message }
         | 
| 12 | 
            -
              end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
              def self.execute(command)    
         | 
| 15 | 
            -
                unless system(command)
         | 
| 16 | 
            -
                  puts File.open(LOGFILE).read
         | 
| 17 | 
            -
                  exit -1 
         | 
| 18 | 
            -
                end
         | 
| 19 | 
            -
              end
         | 
| 20 | 
            -
            end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
            BleakHouse.write_to_log('-%{ BUILDING RUBY }%-')
         | 
| 23 | 
            -
            BleakHouse.execute("ruby build_ruby.rb >> #{BleakHouse::LOGFILE} 2>&1")
         | 
| 24 | 
            -
             | 
| 25 | 
            -
            BleakHouse.write_to_log('-%{ BUILDING SNAPSHOT }%-')
         | 
| 26 | 
            -
            BleakHouse.execute("ruby-bleak-house build_snapshot.rb >> #{BleakHouse::LOGFILE} 2>&1")
         | 
    
        data/ext/snapshot.c
    DELETED
    
    | @@ -1,151 +0,0 @@ | |
| 1 | 
            -
            #include <time.h>
         | 
| 2 | 
            -
            #include "snapshot.h"
         | 
| 3 | 
            -
             | 
| 4 | 
            -
            static VALUE rb_mB;
         | 
| 5 | 
            -
            static VALUE rb_cC;
         | 
| 6 | 
            -
             | 
| 7 | 
            -
            /* Number of filled <tt>heaps_slots</tt> */
         | 
| 8 | 
            -
            static VALUE heaps_used(VALUE self) {
         | 
| 9 | 
            -
              return INT2FIX(rb_gc_heaps_used());
         | 
| 10 | 
            -
            }
         | 
| 11 | 
            -
             | 
| 12 | 
            -
            /* Number of allocated <tt>heaps_slots</tt> */
         | 
| 13 | 
            -
            static VALUE heaps_length(VALUE self) {
         | 
| 14 | 
            -
              return INT2FIX(rb_gc_heaps_length());
         | 
| 15 | 
            -
            }
         | 
| 16 | 
            -
             | 
| 17 | 
            -
            /* Inner method; call BleakHouse.snapshot instead. */
         | 
| 18 | 
            -
            static VALUE ext_snapshot(VALUE self, VALUE _logfile, VALUE _gc_runs) {
         | 
| 19 | 
            -
              Check_Type(_logfile, T_STRING);
         | 
| 20 | 
            -
              Check_Type(_gc_runs, T_FIXNUM);
         | 
| 21 | 
            -
             | 
| 22 | 
            -
              RVALUE *obj, *obj_end;
         | 
| 23 | 
            -
              st_table_entry *sym;
         | 
| 24 | 
            -
             | 
| 25 | 
            -
              struct heaps_slot * heaps = rb_gc_heap_slots();
         | 
| 26 | 
            -
              struct st_table * sym_tbl = rb_parse_sym_tbl();
         | 
| 27 | 
            -
             | 
| 28 | 
            -
              /* see if the logfile exists already */
         | 
| 29 | 
            -
              FILE *logfile = fopen(StringValueCStr(_logfile), "r");
         | 
| 30 | 
            -
              int is_new;
         | 
| 31 | 
            -
              if (!(is_new = (logfile == NULL)))
         | 
| 32 | 
            -
                fclose(logfile);
         | 
| 33 | 
            -
             | 
| 34 | 
            -
              /* reopen for writing */
         | 
| 35 | 
            -
              if ((logfile = fopen(StringValueCStr(_logfile), "w")) == NULL)
         | 
| 36 | 
            -
                rb_raise(rb_eRuntimeError, "couldn't open snapshot file");
         | 
| 37 | 
            -
             | 
| 38 | 
            -
              int filled_slots = 0;
         | 
| 39 | 
            -
              int free_slots = 0;
         | 
| 40 | 
            -
             | 
| 41 | 
            -
              int i;
         | 
| 42 | 
            -
              char * chr;
         | 
| 43 | 
            -
             | 
| 44 | 
            -
              for (i = 0; i < FIX2INT(_gc_runs); i++) {
         | 
| 45 | 
            -
                /* request GC run */
         | 
| 46 | 
            -
                rb_funcall(rb_mGC, rb_intern("start"), 0);
         | 
| 47 | 
            -
                rb_thread_schedule();
         | 
| 48 | 
            -
              }
         | 
| 49 | 
            -
             | 
| 50 | 
            -
              /* walk the heap */
         | 
| 51 | 
            -
              for (i = 0; i < rb_gc_heaps_used(); i++) {
         | 
| 52 | 
            -
                obj = heaps[i].slot;
         | 
| 53 | 
            -
                obj_end = obj + heaps[i].limit;
         | 
| 54 | 
            -
                for (; obj < obj_end; obj++) {
         | 
| 55 | 
            -
                  if (obj->as.basic.flags) { /* always 0 for freed objects */
         | 
| 56 | 
            -
                    filled_slots ++;
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                    /* write the source file*/
         | 
| 59 | 
            -
                    if (obj->file) {
         | 
| 60 | 
            -
                      chr = obj->file;
         | 
| 61 | 
            -
                      if (*chr != '\0') {
         | 
| 62 | 
            -
                        fprintf(logfile, "%s", obj->file);
         | 
| 63 | 
            -
                      } else {
         | 
| 64 | 
            -
                        fprintf(logfile, "__empty__");
         | 
| 65 | 
            -
                      }
         | 
| 66 | 
            -
                    } else {
         | 
| 67 | 
            -
                      fprintf(logfile, "__null__");
         | 
| 68 | 
            -
                    }
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                    /* write the source line */
         | 
| 71 | 
            -
                    fprintf(logfile, ":");
         | 
| 72 | 
            -
                    if (obj->line) {
         | 
| 73 | 
            -
                      fprintf(logfile, "%i", obj->line);
         | 
| 74 | 
            -
                    } else {
         | 
| 75 | 
            -
                      fprintf(logfile, "__null__");
         | 
| 76 | 
            -
                    }
         | 
| 77 | 
            -
             | 
| 78 | 
            -
                    /* write the class */
         | 
| 79 | 
            -
                    fprintf(logfile, ":");
         | 
| 80 | 
            -
                    switch (TYPE(obj)) {
         | 
| 81 | 
            -
                      case T_NONE:
         | 
| 82 | 
            -
                          fprintf(logfile, "__none__"); break;
         | 
| 83 | 
            -
                      case T_BLKTAG:
         | 
| 84 | 
            -
                          fprintf(logfile, "__blktag__"); break;
         | 
| 85 | 
            -
                      case T_UNDEF:
         | 
| 86 | 
            -
                          fprintf(logfile, "__undef__"); break;
         | 
| 87 | 
            -
                      case T_VARMAP:
         | 
| 88 | 
            -
                          fprintf(logfile, "__varmap__"); break;
         | 
| 89 | 
            -
                      case T_SCOPE:
         | 
| 90 | 
            -
                          fprintf(logfile, "__scope__"); break;
         | 
| 91 | 
            -
                      case T_NODE:
         | 
| 92 | 
            -
                          fprintf(logfile, "__node__"); break;
         | 
| 93 | 
            -
                      default:
         | 
| 94 | 
            -
                        if (!obj->as.basic.klass) {
         | 
| 95 | 
            -
                          fprintf(logfile, "__unknown__");
         | 
| 96 | 
            -
                        } else {
         | 
| 97 | 
            -
                          fprintf(logfile, rb_obj_classname((VALUE)obj));
         | 
| 98 | 
            -
                        }
         | 
| 99 | 
            -
                    }
         | 
| 100 | 
            -
             | 
| 101 | 
            -
                    /* write newline */
         | 
| 102 | 
            -
                    fprintf(logfile, "\n");
         | 
| 103 | 
            -
                  } else {
         | 
| 104 | 
            -
                    free_slots ++;
         | 
| 105 | 
            -
                  }
         | 
| 106 | 
            -
                }
         | 
| 107 | 
            -
              }
         | 
| 108 | 
            -
             | 
| 109 | 
            -
              /* walk the symbol table */
         | 
| 110 | 
            -
              /* hashed = lookup_builtin("Symbol");
         | 
| 111 | 
            -
              for (i = 0; i < sym_tbl->num_bins; i++) {
         | 
| 112 | 
            -
                for (sym = sym_tbl->bins[i]; sym != 0; sym = sym->next) {
         | 
| 113 | 
            -
                  fprintf(logfile, "%i,%lu\n", hashed + 1, sym->record);
         | 
| 114 | 
            -
                }
         | 
| 115 | 
            -
              } */
         | 
| 116 | 
            -
             | 
| 117 | 
            -
              fprintf(logfile, "%i filled\n", filled_slots);
         | 
| 118 | 
            -
              fprintf(logfile, "%i free\n", free_slots);
         | 
| 119 | 
            -
              fclose(logfile);
         | 
| 120 | 
            -
             | 
| 121 | 
            -
              return Qnil;
         | 
| 122 | 
            -
            }
         | 
| 123 | 
            -
             | 
| 124 | 
            -
             | 
| 125 | 
            -
            /*
         | 
| 126 | 
            -
             | 
| 127 | 
            -
            This class performs the actual object logging of BleakHouse. To use it directly, you need to make calls to BleakHouse.snapshot.
         | 
| 128 | 
            -
             | 
| 129 | 
            -
            By default, BleakHouse records a snapshot on exit. You can disable this by setting the environment variable <tt>NO_EXIT_HANDLER</tt> before startup.
         | 
| 130 | 
            -
             | 
| 131 | 
            -
            It is also possible to externally trigger the snapshot at any time by sending <tt>SIGUSR2</tt> to the process.
         | 
| 132 | 
            -
             | 
| 133 | 
            -
            == Example
         | 
| 134 | 
            -
             | 
| 135 | 
            -
            At the start of your app, put:
         | 
| 136 | 
            -
              require 'rubygems'
         | 
| 137 | 
            -
              require 'bleak_house'
         | 
| 138 | 
            -
              $logfile = "/path/to/logfile"
         | 
| 139 | 
            -
             | 
| 140 | 
            -
            Run your app. Once it exits, analyze your data:
         | 
| 141 | 
            -
              bleak /path/to/logfile
         | 
| 142 | 
            -
             | 
| 143 | 
            -
            */
         | 
| 144 | 
            -
            void
         | 
| 145 | 
            -
            Init_snapshot()
         | 
| 146 | 
            -
            {
         | 
| 147 | 
            -
              rb_mB = rb_define_module("BleakHouse");
         | 
| 148 | 
            -
              rb_define_singleton_method(rb_mB, "ext_snapshot", ext_snapshot, 2);
         | 
| 149 | 
            -
              rb_define_singleton_method(rb_mB, "heaps_used", heaps_used, 0);
         | 
| 150 | 
            -
              rb_define_singleton_method(rb_mB, "heaps_length", heaps_length, 0);
         | 
| 151 | 
            -
            }
         | 
    
        data/ext/snapshot.h
    DELETED
    
    | @@ -1,59 +0,0 @@ | |
| 1 | 
            -
            #include "ruby.h"
         | 
| 2 | 
            -
            #include "env.h"
         | 
| 3 | 
            -
            #include "node.h"
         | 
| 4 | 
            -
            #include "st.h"
         | 
| 5 | 
            -
            #include "re.h"
         | 
| 6 | 
            -
            #include "util.h"
         | 
| 7 | 
            -
            #include "intern.h"
         | 
| 8 | 
            -
            #include "string.h"
         | 
| 9 | 
            -
             | 
| 10 | 
            -
            typedef struct RVALUE {
         | 
| 11 | 
            -
                union {
         | 
| 12 | 
            -
                    struct {
         | 
| 13 | 
            -
                        unsigned long flags; /* always 0 for freed obj */
         | 
| 14 | 
            -
                        struct RVALUE *next;
         | 
| 15 | 
            -
                    } free;
         | 
| 16 | 
            -
                    struct RBasic  basic;
         | 
| 17 | 
            -
                    struct RObject object;
         | 
| 18 | 
            -
                    struct RClass  klass;
         | 
| 19 | 
            -
                    struct RFloat  flonum;
         | 
| 20 | 
            -
                    struct RString string;
         | 
| 21 | 
            -
                    struct RArray  array;
         | 
| 22 | 
            -
                    struct RRegexp regexp;
         | 
| 23 | 
            -
                    struct RHash   hash;
         | 
| 24 | 
            -
                    struct RData   data;
         | 
| 25 | 
            -
                    struct RStruct rstruct;
         | 
| 26 | 
            -
                    struct RBignum bignum;
         | 
| 27 | 
            -
                    struct RFile   file;
         | 
| 28 | 
            -
                    struct RNode   node;
         | 
| 29 | 
            -
                    struct RMatch  match;
         | 
| 30 | 
            -
                    struct RVarmap varmap;
         | 
| 31 | 
            -
                    struct SCOPE   scope;
         | 
| 32 | 
            -
                } as;
         | 
| 33 | 
            -
                char *file;
         | 
| 34 | 
            -
                int   line;
         | 
| 35 | 
            -
            } RVALUE;
         | 
| 36 | 
            -
             | 
| 37 | 
            -
            struct heaps_slot {
         | 
| 38 | 
            -
                void *membase;
         | 
| 39 | 
            -
                RVALUE *slot;
         | 
| 40 | 
            -
                int limit;
         | 
| 41 | 
            -
            };
         | 
| 42 | 
            -
             | 
| 43 | 
            -
            typedef struct st_table_entry st_table_entry;
         | 
| 44 | 
            -
             | 
| 45 | 
            -
            struct st_table_entry {
         | 
| 46 | 
            -
                unsigned int hash;
         | 
| 47 | 
            -
                st_data_t key;
         | 
| 48 | 
            -
                st_data_t record;
         | 
| 49 | 
            -
                st_table_entry *next;
         | 
| 50 | 
            -
            };
         | 
| 51 | 
            -
             | 
| 52 | 
            -
            struct st_table * rb_parse_sym_tbl();
         | 
| 53 | 
            -
            struct heaps_slot * rb_gc_heap_slots();
         | 
| 54 | 
            -
            int rb_gc_heaps_used();
         | 
| 55 | 
            -
            int rb_gc_heaps_length();
         | 
| 56 | 
            -
             | 
| 57 | 
            -
            char * inspect(VALUE);
         | 
| 58 | 
            -
            char * handle_exception(VALUE);
         | 
| 59 | 
            -
            int lookup_builtin(char *);
         | 
    
        data/lib/bleak_house/analyzer.rb
    DELETED
    
    | @@ -1,54 +0,0 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            module BleakHouse
         | 
| 3 | 
            -
              module Analyzer
         | 
| 4 | 
            -
             | 
| 5 | 
            -
                # Analyze a compatible <tt>bleak.dump</tt>. Accepts one or more filename and the number of lines to display.
         | 
| 6 | 
            -
                def self.run(*args)
         | 
| 7 | 
            -
                  lines = args.last[/^\d+$/] ? args.pop.to_i : 20
         | 
| 8 | 
            -
             | 
| 9 | 
            -
                  raise "Can't diff more than 2 files" if args.size > 2
         | 
| 10 | 
            -
             | 
| 11 | 
            -
                  outputs = args.map do |file|
         | 
| 12 | 
            -
                    filled, free = `tail -n 2 #{file}`.split("\n")
         | 
| 13 | 
            -
                    unless filled =~ /filled/ and free =~ /free/
         | 
| 14 | 
            -
                      raise "#{file} is incomplete or corrupted"
         | 
| 15 | 
            -
                    end
         | 
| 16 | 
            -
             | 
| 17 | 
            -
                    length = `wc #{file}`.to_i - 2
         | 
| 18 | 
            -
                    cmd = ENV['NO_TRACE'] ? "awk -F: '{print $3}' " + file : "cat #{file}"
         | 
| 19 | 
            -
                    cmd += " | sort | uniq -c | sort -nr | head -#{lines}"
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                    ["#{length} total objects", "#{filled} heap slots", "#{free} heap slots"] + `#{cmd}`.split("\n")
         | 
| 22 | 
            -
                  end
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                  if outputs.size == 1
         | 
| 25 | 
            -
                    # Just output the data
         | 
| 26 | 
            -
                    puts "Displaying top #{lines} most common line/class pairs"
         | 
| 27 | 
            -
                    puts outputs.first
         | 
| 28 | 
            -
                  else
         | 
| 29 | 
            -
                    puts "Displaying change in top #{lines} most common line/class pairs"
         | 
| 30 | 
            -
                    puts diff(outputs)
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                def self.diff(outputs)
         | 
| 36 | 
            -
                  # Calculate the diff
         | 
| 37 | 
            -
                  diff = Hash.new(0)
         | 
| 38 | 
            -
                  # Iterate each item
         | 
| 39 | 
            -
                  outputs.each_with_index do |output, index|
         | 
| 40 | 
            -
                    output[3..-1].each do |line|
         | 
| 41 | 
            -
                      c, key = line.split(" ", 2)
         | 
| 42 | 
            -
                      index.zero? ? diff[key] -= c.to_i : diff[key] += c.to_i
         | 
| 43 | 
            -
                    end
         | 
| 44 | 
            -
                  end
         | 
| 45 | 
            -
                  # Format the lines in descending order
         | 
| 46 | 
            -
                  diff.sort_by do |key, value|
         | 
| 47 | 
            -
                    -value
         | 
| 48 | 
            -
                  end.map do |key, value|
         | 
| 49 | 
            -
                    "#{value.to_s.rjust(6)} #{key}"
         | 
| 50 | 
            -
                  end
         | 
| 51 | 
            -
                end
         | 
| 52 | 
            -
             | 
| 53 | 
            -
              end
         | 
| 54 | 
            -
            end
         | 
    
        data/lib/bleak_house/hook.rb
    DELETED
    
    | @@ -1,24 +0,0 @@ | |
| 1 | 
            -
             | 
| 2 | 
            -
            module BleakHouse
         | 
| 3 | 
            -
              # The body of the exit handler and <tt>SIGUSR2</tt> trap. It writes a snapshot to a dumpfile named after the current Process.pid.
         | 
| 4 | 
            -
              def self.hook
         | 
| 5 | 
            -
                @count ||= 0
         | 
| 6 | 
            -
                filename = "/tmp/bleak.%s.%03i.dump" % [Process.pid,@count]
         | 
| 7 | 
            -
                STDERR.puts "** BleakHouse: working..."
         | 
| 8 | 
            -
                BleakHouse.snapshot(filename)
         | 
| 9 | 
            -
                STDERR.puts "** BleakHouse: complete\n** Bleakhouse: Run 'bleak #{filename}' to analyze."
         | 
| 10 | 
            -
                @count += 1
         | 
| 11 | 
            -
              end
         | 
| 12 | 
            -
            end
         | 
| 13 | 
            -
             | 
| 14 | 
            -
            unless ENV['NO_EXIT_HANDLER']
         | 
| 15 | 
            -
              Kernel.at_exit do
         | 
| 16 | 
            -
                BleakHouse.hook
         | 
| 17 | 
            -
              end
         | 
| 18 | 
            -
              STDERR.puts "** Bleakhouse: installed"
         | 
| 19 | 
            -
            end
         | 
| 20 | 
            -
             | 
| 21 | 
            -
            Kernel.trap("USR2") do
         | 
| 22 | 
            -
              STDERR.puts "** BleakHouse: we get signal."
         | 
| 23 | 
            -
              BleakHouse.hook
         | 
| 24 | 
            -
            end
         | 
| Binary file | 
    
        data/ruby/ruby-1.8.7.patch
    DELETED
    
    | @@ -1,483 +0,0 @@ | |
| 1 | 
            -
            diff --git a/Makefile.in b/Makefile.in
         | 
| 2 | 
            -
            index a37bcf6..52f723c 100644
         | 
| 3 | 
            -
            --- a/Makefile.in
         | 
| 4 | 
            -
            +++ b/Makefile.in
         | 
| 5 | 
            -
            @@ -34,7 +34,7 @@ RIDATADIR = $(DESTDIR)$(datadir)/ri/$(MAJOR).$(MINOR)/system
         | 
| 6 | 
            -
             
         | 
| 7 | 
            -
             empty =
         | 
| 8 | 
            -
             OUTFLAG = @OUTFLAG@$(empty)
         | 
| 9 | 
            -
            -CFLAGS = @CFLAGS@ @XCFLAGS@ @ARCH_FLAG@
         | 
| 10 | 
            -
            +CFLAGS = @CFLAGS@ @XCFLAGS@ @ARCH_FLAG@ @VALGRIND_CFLAGS@
         | 
| 11 | 
            -
             cflags = @cflags@
         | 
| 12 | 
            -
             optflags = @optflags@
         | 
| 13 | 
            -
             debugflags = @debugflags@
         | 
| 14 | 
            -
            diff --git a/configure b/configure
         | 
| 15 | 
            -
            index faf2b45..16287ca 100755
         | 
| 16 | 
            -
            --- a/configure
         | 
| 17 | 
            -
            +++ b/configure
         | 
| 18 | 
            -
            @@ -724,6 +724,7 @@ cflags
         | 
| 19 | 
            -
             optflags
         | 
| 20 | 
            -
             debugflags
         | 
| 21 | 
            -
             XCFLAGS
         | 
| 22 | 
            -
            +VALGRIND_CFLAGS
         | 
| 23 | 
            -
             XLDFLAGS
         | 
| 24 | 
            -
             LIBRUBY_LDSHARED
         | 
| 25 | 
            -
             LIBRUBY_DLDFLAGS
         | 
| 26 | 
            -
            @@ -1353,6 +1354,7 @@ Optional Features:
         | 
| 27 | 
            -
               --enable-setreuid       use setreuid()/setregid() according to need even if obsolete.
         | 
| 28 | 
            -
               --disable-rpath         embed run path into extension libraries.
         | 
| 29 | 
            -
               --enable-shared         build a shared library for Ruby.
         | 
| 30 | 
            -
            +  --enable-valgrind       Use valgrind support
         | 
| 31 | 
            -
               --enable-install-doc    build and install rdoc indexes during install
         | 
| 32 | 
            -
             
         | 
| 33 | 
            -
             Optional Packages:
         | 
| 34 | 
            -
            @@ -13012,12 +13014,11 @@ cat confdefs.h >>conftest.$ac_ext
         | 
| 35 | 
            -
             cat >>conftest.$ac_ext <<_ACEOF
         | 
| 36 | 
            -
             /* end confdefs.h.  */
         | 
| 37 | 
            -
             #include <sys/types.h> /* for off_t */
         | 
| 38 | 
            -
            -     #include <stdio.h>
         | 
| 39 | 
            -
            +#include <stdio.h>
         | 
| 40 | 
            -
             int
         | 
| 41 | 
            -
             main ()
         | 
| 42 | 
            -
             {
         | 
| 43 | 
            -
            -int (*fp) (FILE *, off_t, int) = fseeko;
         | 
| 44 | 
            -
            -     return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
         | 
| 45 | 
            -
            +return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
         | 
| 46 | 
            -
               ;
         | 
| 47 | 
            -
               return 0;
         | 
| 48 | 
            -
             }
         | 
| 49 | 
            -
            @@ -16462,6 +16463,173 @@ done
         | 
| 50 | 
            -
                 fi
         | 
| 51 | 
            -
             fi
         | 
| 52 | 
            -
             
         | 
| 53 | 
            -
            +# Check whether --enable-valgrind was given.
         | 
| 54 | 
            -
            +if test "${enable_valgrind+set}" = set; then
         | 
| 55 | 
            -
            +  enableval=$enable_valgrind; want_valgrind=$enableval
         | 
| 56 | 
            -
            +else
         | 
| 57 | 
            -
            +  want_valgrind=auto
         | 
| 58 | 
            -
            +fi
         | 
| 59 | 
            -
            +
         | 
| 60 | 
            -
            +
         | 
| 61 | 
            -
            +if test x"$want_valgrind" != xno; then
         | 
| 62 | 
            -
            +
         | 
| 63 | 
            -
            +for ac_header in valgrind/memcheck.h
         | 
| 64 | 
            -
            +do
         | 
| 65 | 
            -
            +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
         | 
| 66 | 
            -
            +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
         | 
| 67 | 
            -
            +  { echo "$as_me:$LINENO: checking for $ac_header" >&5
         | 
| 68 | 
            -
            +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
         | 
| 69 | 
            -
            +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
         | 
| 70 | 
            -
            +  echo $ECHO_N "(cached) $ECHO_C" >&6
         | 
| 71 | 
            -
            +fi
         | 
| 72 | 
            -
            +ac_res=`eval echo '${'$as_ac_Header'}'`
         | 
| 73 | 
            -
            +	       { echo "$as_me:$LINENO: result: $ac_res" >&5
         | 
| 74 | 
            -
            +echo "${ECHO_T}$ac_res" >&6; }
         | 
| 75 | 
            -
            +else
         | 
| 76 | 
            -
            +  # Is the header compilable?
         | 
| 77 | 
            -
            +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
         | 
| 78 | 
            -
            +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
         | 
| 79 | 
            -
            +cat >conftest.$ac_ext <<_ACEOF
         | 
| 80 | 
            -
            +/* confdefs.h.  */
         | 
| 81 | 
            -
            +_ACEOF
         | 
| 82 | 
            -
            +cat confdefs.h >>conftest.$ac_ext
         | 
| 83 | 
            -
            +cat >>conftest.$ac_ext <<_ACEOF
         | 
| 84 | 
            -
            +/* end confdefs.h.  */
         | 
| 85 | 
            -
            +$ac_includes_default
         | 
| 86 | 
            -
            +#include <$ac_header>
         | 
| 87 | 
            -
            +_ACEOF
         | 
| 88 | 
            -
            +rm -f conftest.$ac_objext
         | 
| 89 | 
            -
            +if { (ac_try="$ac_compile"
         | 
| 90 | 
            -
            +case "(($ac_try" in
         | 
| 91 | 
            -
            +  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
         | 
| 92 | 
            -
            +  *) ac_try_echo=$ac_try;;
         | 
| 93 | 
            -
            +esac
         | 
| 94 | 
            -
            +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         | 
| 95 | 
            -
            +  (eval "$ac_compile") 2>conftest.er1
         | 
| 96 | 
            -
            +  ac_status=$?
         | 
| 97 | 
            -
            +  grep -v '^ *+' conftest.er1 >conftest.err
         | 
| 98 | 
            -
            +  rm -f conftest.er1
         | 
| 99 | 
            -
            +  cat conftest.err >&5
         | 
| 100 | 
            -
            +  echo "$as_me:$LINENO: \$? = $ac_status" >&5
         | 
| 101 | 
            -
            +  (exit $ac_status); } && {
         | 
| 102 | 
            -
            +	 test -z "$ac_c_werror_flag" ||
         | 
| 103 | 
            -
            +	 test ! -s conftest.err
         | 
| 104 | 
            -
            +       } && test -s conftest.$ac_objext; then
         | 
| 105 | 
            -
            +  ac_header_compiler=yes
         | 
| 106 | 
            -
            +else
         | 
| 107 | 
            -
            +  echo "$as_me: failed program was:" >&5
         | 
| 108 | 
            -
            +sed 's/^/| /' conftest.$ac_ext >&5
         | 
| 109 | 
            -
            +
         | 
| 110 | 
            -
            +	ac_header_compiler=no
         | 
| 111 | 
            -
            +fi
         | 
| 112 | 
            -
            +
         | 
| 113 | 
            -
            +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
         | 
| 114 | 
            -
            +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
         | 
| 115 | 
            -
            +echo "${ECHO_T}$ac_header_compiler" >&6; }
         | 
| 116 | 
            -
            +
         | 
| 117 | 
            -
            +# Is the header present?
         | 
| 118 | 
            -
            +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
         | 
| 119 | 
            -
            +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
         | 
| 120 | 
            -
            +cat >conftest.$ac_ext <<_ACEOF
         | 
| 121 | 
            -
            +/* confdefs.h.  */
         | 
| 122 | 
            -
            +_ACEOF
         | 
| 123 | 
            -
            +cat confdefs.h >>conftest.$ac_ext
         | 
| 124 | 
            -
            +cat >>conftest.$ac_ext <<_ACEOF
         | 
| 125 | 
            -
            +/* end confdefs.h.  */
         | 
| 126 | 
            -
            +#include <$ac_header>
         | 
| 127 | 
            -
            +_ACEOF
         | 
| 128 | 
            -
            +if { (ac_try="$ac_cpp conftest.$ac_ext"
         | 
| 129 | 
            -
            +case "(($ac_try" in
         | 
| 130 | 
            -
            +  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
         | 
| 131 | 
            -
            +  *) ac_try_echo=$ac_try;;
         | 
| 132 | 
            -
            +esac
         | 
| 133 | 
            -
            +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         | 
| 134 | 
            -
            +  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
         | 
| 135 | 
            -
            +  ac_status=$?
         | 
| 136 | 
            -
            +  grep -v '^ *+' conftest.er1 >conftest.err
         | 
| 137 | 
            -
            +  rm -f conftest.er1
         | 
| 138 | 
            -
            +  cat conftest.err >&5
         | 
| 139 | 
            -
            +  echo "$as_me:$LINENO: \$? = $ac_status" >&5
         | 
| 140 | 
            -
            +  (exit $ac_status); } >/dev/null && {
         | 
| 141 | 
            -
            +	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
         | 
| 142 | 
            -
            +	 test ! -s conftest.err
         | 
| 143 | 
            -
            +       }; then
         | 
| 144 | 
            -
            +  ac_header_preproc=yes
         | 
| 145 | 
            -
            +else
         | 
| 146 | 
            -
            +  echo "$as_me: failed program was:" >&5
         | 
| 147 | 
            -
            +sed 's/^/| /' conftest.$ac_ext >&5
         | 
| 148 | 
            -
            +
         | 
| 149 | 
            -
            +  ac_header_preproc=no
         | 
| 150 | 
            -
            +fi
         | 
| 151 | 
            -
            +
         | 
| 152 | 
            -
            +rm -f conftest.err conftest.$ac_ext
         | 
| 153 | 
            -
            +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
         | 
| 154 | 
            -
            +echo "${ECHO_T}$ac_header_preproc" >&6; }
         | 
| 155 | 
            -
            +
         | 
| 156 | 
            -
            +# So?  What about this header?
         | 
| 157 | 
            -
            +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
         | 
| 158 | 
            -
            +  yes:no: )
         | 
| 159 | 
            -
            +    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
         | 
| 160 | 
            -
            +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
         | 
| 161 | 
            -
            +    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
         | 
| 162 | 
            -
            +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
         | 
| 163 | 
            -
            +    ac_header_preproc=yes
         | 
| 164 | 
            -
            +    ;;
         | 
| 165 | 
            -
            +  no:yes:* )
         | 
| 166 | 
            -
            +    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
         | 
| 167 | 
            -
            +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
         | 
| 168 | 
            -
            +    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
         | 
| 169 | 
            -
            +echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
         | 
| 170 | 
            -
            +    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
         | 
| 171 | 
            -
            +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
         | 
| 172 | 
            -
            +    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
         | 
| 173 | 
            -
            +echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
         | 
| 174 | 
            -
            +    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
         | 
| 175 | 
            -
            +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
         | 
| 176 | 
            -
            +    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
         | 
| 177 | 
            -
            +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
         | 
| 178 | 
            -
            +
         | 
| 179 | 
            -
            +    ;;
         | 
| 180 | 
            -
            +esac
         | 
| 181 | 
            -
            +{ echo "$as_me:$LINENO: checking for $ac_header" >&5
         | 
| 182 | 
            -
            +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
         | 
| 183 | 
            -
            +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
         | 
| 184 | 
            -
            +  echo $ECHO_N "(cached) $ECHO_C" >&6
         | 
| 185 | 
            -
            +else
         | 
| 186 | 
            -
            +  eval "$as_ac_Header=\$ac_header_preproc"
         | 
| 187 | 
            -
            +fi
         | 
| 188 | 
            -
            +ac_res=`eval echo '${'$as_ac_Header'}'`
         | 
| 189 | 
            -
            +	       { echo "$as_me:$LINENO: result: $ac_res" >&5
         | 
| 190 | 
            -
            +echo "${ECHO_T}$ac_res" >&6; }
         | 
| 191 | 
            -
            +
         | 
| 192 | 
            -
            +fi
         | 
| 193 | 
            -
            +if test `eval echo '${'$as_ac_Header'}'` = yes; then
         | 
| 194 | 
            -
            +  cat >>confdefs.h <<_ACEOF
         | 
| 195 | 
            -
            +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
         | 
| 196 | 
            -
            +_ACEOF
         | 
| 197 | 
            -
            + have_valgrind=yes
         | 
| 198 | 
            -
            +else
         | 
| 199 | 
            -
            +  have_valgrind=no
         | 
| 200 | 
            -
            +fi
         | 
| 201 | 
            -
            +
         | 
| 202 | 
            -
            +done
         | 
| 203 | 
            -
            +
         | 
| 204 | 
            -
            +	if test x"$have_valgrind" = xyes; then
         | 
| 205 | 
            -
            +		cat >>confdefs.h <<\_ACEOF
         | 
| 206 | 
            -
            +#define HAVE_VALGRIND 1
         | 
| 207 | 
            -
            +_ACEOF
         | 
| 208 | 
            -
            +
         | 
| 209 | 
            -
            +		VALGRIND_CFLAGS="";
         | 
| 210 | 
            -
            +	elif test x"$want_valgrind" = xyes -a x"$have_valgrind" = xno; then
         | 
| 211 | 
            -
            +		{ { echo "$as_me:$LINENO: error: valgrind support requested but valgrind not found" >&5
         | 
| 212 | 
            -
            +echo "$as_me: error: valgrind support requested but valgrind not found" >&2;}
         | 
| 213 | 
            -
            +   { (exit 1); exit 1; }; }
         | 
| 214 | 
            -
            +	else
         | 
| 215 | 
            -
            +	  VALGRIND_CFLAGS="";
         | 
| 216 | 
            -
            +	fi
         | 
| 217 | 
            -
            +fi
         | 
| 218 | 
            -
            +
         | 
| 219 | 
            -
            +
         | 
| 220 | 
            -
             DEFAULT_KCODE="KCODE_NONE"
         | 
| 221 | 
            -
             
         | 
| 222 | 
            -
             
         | 
| 223 | 
            -
            @@ -18588,6 +18756,7 @@ cflags!$cflags$ac_delim
         | 
| 224 | 
            -
             optflags!$optflags$ac_delim
         | 
| 225 | 
            -
             debugflags!$debugflags$ac_delim
         | 
| 226 | 
            -
             XCFLAGS!$XCFLAGS$ac_delim
         | 
| 227 | 
            -
            +VALGRIND_CFLAGS!$VALGRIND_CFLAGS$ac_delim
         | 
| 228 | 
            -
             XLDFLAGS!$XLDFLAGS$ac_delim
         | 
| 229 | 
            -
             LIBRUBY_LDSHARED!$LIBRUBY_LDSHARED$ac_delim
         | 
| 230 | 
            -
             LIBRUBY_DLDFLAGS!$LIBRUBY_DLDFLAGS$ac_delim
         | 
| 231 | 
            -
            @@ -18622,7 +18791,7 @@ MANTYPE!$MANTYPE$ac_delim
         | 
| 232 | 
            -
             LTLIBOBJS!$LTLIBOBJS$ac_delim
         | 
| 233 | 
            -
             _ACEOF
         | 
| 234 | 
            -
             
         | 
| 235 | 
            -
            -  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 47; then
         | 
| 236 | 
            -
            +  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 48; then
         | 
| 237 | 
            -
                 break
         | 
| 238 | 
            -
               elif $ac_last_try; then
         | 
| 239 | 
            -
                 { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
         | 
| 240 | 
            -
            diff --git a/configure.in b/configure.in
         | 
| 241 | 
            -
            index fe63c0c..e0cdcdd 100644
         | 
| 242 | 
            -
            --- a/configure.in
         | 
| 243 | 
            -
            +++ b/configure.in
         | 
| 244 | 
            -
            @@ -1043,6 +1043,23 @@ if test x"$ac_cv_header_ucontext_h" = xyes; then
         | 
| 245 | 
            -
                 fi
         | 
| 246 | 
            -
             fi
         | 
| 247 | 
            -
             
         | 
| 248 | 
            -
            +AC_ARG_ENABLE(valgrind,
         | 
| 249 | 
            -
            +       [  --enable-valgrind       use valgrind support],
         | 
| 250 | 
            -
            +       [want_valgrind=$enableval], [want_valgrind=auto])
         | 
| 251 | 
            -
            +
         | 
| 252 | 
            -
            +if test x"$want_valgrind" != xno; then
         | 
| 253 | 
            -
            +  AC_CHECK_HEADERS(valgrind/memcheck.h, have_valgrind=yes, have_valgrind=no)
         | 
| 254 | 
            -
            +	if test x"$have_valgrind" = xyes; then
         | 
| 255 | 
            -
            +		AC_DEFINE(HAVE_VALGRIND)
         | 
| 256 | 
            -
            +		VALGRIND_CFLAGS="";
         | 
| 257 | 
            -
            +	elif test x"$want_valgrind" = xyes -a x"$have_valgrind" = xno; then
         | 
| 258 | 
            -
            +		AC_MSG_ERROR(valgrind support requested but valgrind not found)
         | 
| 259 | 
            -
            +	else
         | 
| 260 | 
            -
            +	  VALGRIND_CFLAGS="";
         | 
| 261 | 
            -
            +	fi
         | 
| 262 | 
            -
            +fi
         | 
| 263 | 
            -
            +
         | 
| 264 | 
            -
            +
         | 
| 265 | 
            -
             dnl default value for $KANJI
         | 
| 266 | 
            -
             DEFAULT_KCODE="KCODE_NONE"
         | 
| 267 | 
            -
             
         | 
| 268 | 
            -
            @@ -1663,6 +1680,7 @@ AC_SUBST(cflags, ['${optflags} ${debugflags}'])dnl
         | 
| 269 | 
            -
             AC_SUBST(optflags)dnl
         | 
| 270 | 
            -
             AC_SUBST(debugflags)dnl
         | 
| 271 | 
            -
             AC_SUBST(XCFLAGS)dnl
         | 
| 272 | 
            -
            +AC_SUBST(VALGRIND_CFLAGS)dnl
         | 
| 273 | 
            -
             AC_SUBST(XLDFLAGS)dnl
         | 
| 274 | 
            -
             AC_SUBST(LIBRUBY_LDSHARED)
         | 
| 275 | 
            -
             AC_SUBST(LIBRUBY_DLDFLAGS)
         | 
| 276 | 
            -
            diff --git a/eval.c b/eval.c
         | 
| 277 | 
            -
            index 11264f7..09ec7a6 100644
         | 
| 278 | 
            -
            --- a/eval.c
         | 
| 279 | 
            -
            +++ b/eval.c
         | 
| 280 | 
            -
            @@ -28,6 +28,12 @@
         | 
| 281 | 
            -
             #define EXIT_FAILURE 1
         | 
| 282 | 
            -
             #endif
         | 
| 283 | 
            -
             
         | 
| 284 | 
            -
            +#ifdef HAVE_VALGRIND
         | 
| 285 | 
            -
            +#include <valgrind/memcheck.h>
         | 
| 286 | 
            -
            +#else
         | 
| 287 | 
            -
            +#define VALGRIND_MAKE_MEM_DEFINED(p, n) /* empty */
         | 
| 288 | 
            -
            +#endif
         | 
| 289 | 
            -
            +
         | 
| 290 | 
            -
             #include <stdio.h>
         | 
| 291 | 
            -
             
         | 
| 292 | 
            -
             #include "st.h"
         | 
| 293 | 
            -
            @@ -1149,7 +1149,7 @@ static VALUE trace_func = 0;
         | 
| 294 | 
            -
             static int tracing = 0;
         | 
| 295 | 
            -
             static void call_trace_func _((rb_event_t,NODE*,VALUE,ID,VALUE));
         | 
| 296 | 
            -
             
         | 
| 297 | 
            -
            -#if 0
         | 
| 298 | 
            -
            +#if 1
         | 
| 299 | 
            -
             #define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \
         | 
| 300 | 
            -
             			      ruby_sourceline = nd_line(ruby_current_node))
         | 
| 301 | 
            -
             #else
         | 
| 302 | 
            -
            @@ -5290,6 +5296,9 @@ assign(self, lhs, val, pcall)
         | 
| 303 | 
            -
                 int pcall;
         | 
| 304 | 
            -
             {
         | 
| 305 | 
            -
                 ruby_current_node = lhs;
         | 
| 306 | 
            -
            +
         | 
| 307 | 
            -
            +    VALGRIND_MAKE_MEM_DEFINED(&val, sizeof(val));
         | 
| 308 | 
            -
            +
         | 
| 309 | 
            -
                 if (val == Qundef) {
         | 
| 310 | 
            -
             	rb_warning("assigning void value");
         | 
| 311 | 
            -
             	val = Qnil;
         | 
| 312 | 
            -
            diff --git a/gc.c b/gc.c
         | 
| 313 | 
            -
            index 45facf0..933b76e 100644
         | 
| 314 | 
            -
            --- a/gc.c
         | 
| 315 | 
            -
            +++ b/gc.c
         | 
| 316 | 
            -
            @@ -30,6 +30,12 @@
         | 
| 317 | 
            -
             #include <sys/resource.h>
         | 
| 318 | 
            -
             #endif
         | 
| 319 | 
            -
             
         | 
| 320 | 
            -
            +#ifdef HAVE_VALGRIND
         | 
| 321 | 
            -
            +#include <valgrind/memcheck.h>
         | 
| 322 | 
            -
            +#else
         | 
| 323 | 
            -
            +#define VALGRIND_MAKE_MEM_DEFINED(p, n) /* empty */
         | 
| 324 | 
            -
            +#endif
         | 
| 325 | 
            -
            +
         | 
| 326 | 
            -
             #if defined _WIN32 || defined __CYGWIN__
         | 
| 327 | 
            -
             #include <windows.h>
         | 
| 328 | 
            -
             #endif
         | 
| 329 | 
            -
            @@ -138,6 +144,9 @@ ruby_xmalloc(size)
         | 
| 330 | 
            -
             {
         | 
| 331 | 
            -
                 void *mem;
         | 
| 332 | 
            -
             
         | 
| 333 | 
            -
            +    VALGRIND_MAKE_MEM_DEFINED(&malloc_increase, sizeof(malloc_increase));
         | 
| 334 | 
            -
            +    VALGRIND_MAKE_MEM_DEFINED(&malloc_limit, sizeof(malloc_limit));
         | 
| 335 | 
            -
            +
         | 
| 336 | 
            -
                 if (size < 0) {
         | 
| 337 | 
            -
             	rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
         | 
| 338 | 
            -
                 }
         | 
| 339 | 
            -
            @@ -297,8 +306,6 @@ rb_gc_unregister_address(addr)
         | 
| 340 | 
            -
                 }
         | 
| 341 | 
            -
             }
         | 
| 342 | 
            -
             
         | 
| 343 | 
            -
            -#undef GC_DEBUG
         | 
| 344 | 
            -
            -
         | 
| 345 | 
            -
             void
         | 
| 346 | 
            -
             rb_global_variable(var)
         | 
| 347 | 
            -
                 VALUE *var;
         | 
| 348 | 
            -
            @@ -333,10 +340,8 @@ typedef struct RVALUE {
         | 
| 349 | 
            -
             	struct RVarmap varmap;
         | 
| 350 | 
            -
             	struct SCOPE   scope;
         | 
| 351 | 
            -
                 } as;
         | 
| 352 | 
            -
            -#ifdef GC_DEBUG
         | 
| 353 | 
            -
                 char *file;
         | 
| 354 | 
            -
                 int   line;
         | 
| 355 | 
            -
            -#endif
         | 
| 356 | 
            -
             } RVALUE;
         | 
| 357 | 
            -
             
         | 
| 358 | 
            -
             #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__)
         | 
| 359 | 
            -
            @@ -355,6 +360,22 @@ static struct heaps_slot {
         | 
| 360 | 
            -
             static int heaps_length = 0;
         | 
| 361 | 
            -
             static int heaps_used   = 0;
         | 
| 362 | 
            -
             
         | 
| 363 | 
            -
            +struct heaps_slot *
         | 
| 364 | 
            -
            +rb_gc_heap_slots()
         | 
| 365 | 
            -
            +{
         | 
| 366 | 
            -
            +    return heaps;
         | 
| 367 | 
            -
            +}
         | 
| 368 | 
            -
            +
         | 
| 369 | 
            -
            +int
         | 
| 370 | 
            -
            +rb_gc_heaps_used() {
         | 
| 371 | 
            -
            +    return heaps_used;
         | 
| 372 | 
            -
            +}
         | 
| 373 | 
            -
            +
         | 
| 374 | 
            -
            +int
         | 
| 375 | 
            -
            +rb_gc_heaps_length() {
         | 
| 376 | 
            -
            +    return heaps_length;
         | 
| 377 | 
            -
            +}
         | 
| 378 | 
            -
            +
         | 
| 379 | 
            -
             #define HEAP_MIN_SLOTS 10000
         | 
| 380 | 
            -
             static int heap_slots = HEAP_MIN_SLOTS;
         | 
| 381 | 
            -
             
         | 
| 382 | 
            -
            @@ -438,10 +438,8 @@ rb_newobj()
         | 
| 383 | 
            -
                 obj = (VALUE)freelist;
         | 
| 384 | 
            -
                 freelist = freelist->as.free.next;
         | 
| 385 | 
            -
                 MEMZERO((void*)obj, RVALUE, 1);
         | 
| 386 | 
            -
            -#ifdef GC_DEBUG
         | 
| 387 | 
            -
                 RANY(obj)->file = ruby_sourcefile;
         | 
| 388 | 
            -
                 RANY(obj)->line = ruby_sourceline;
         | 
| 389 | 
            -
            -#endif
         | 
| 390 | 
            -
                 return obj;
         | 
| 391 | 
            -
             }
         | 
| 392 | 
            -
             | 
| 393 | 
            -
            @@ -678,6 +704,9 @@ mark_locations_array(x, n)
         | 
| 394 | 
            -
                 register long n;
         | 
| 395 | 
            -
             {
         | 
| 396 | 
            -
                 VALUE v;
         | 
| 397 | 
            -
            +
         | 
| 398 | 
            -
            +    VALGRIND_MAKE_MEM_DEFINED(x, sizeof(*x) * n);
         | 
| 399 | 
            -
            +
         | 
| 400 | 
            -
                 while (n--) {
         | 
| 401 | 
            -
                     v = *x;
         | 
| 402 | 
            -
             	if (is_pointer_to_heap((void *)v)) {
         | 
| 403 | 
            -
            @@ -768,12 +797,18 @@ gc_mark(ptr, lev)
         | 
| 404 | 
            -
             {
         | 
| 405 | 
            -
                 register RVALUE *obj;
         | 
| 406 | 
            -
             
         | 
| 407 | 
            -
            +    VALGRIND_MAKE_MEM_DEFINED(&ptr, sizeof(ptr));
         | 
| 408 | 
            -
                 obj = RANY(ptr);
         | 
| 409 | 
            -
            +    VALGRIND_MAKE_MEM_DEFINED(obj, sizeof(*obj));
         | 
| 410 | 
            -
            +
         | 
| 411 | 
            -
                 if (rb_special_const_p(ptr)) return; /* special const not marked */
         | 
| 412 | 
            -
                 if (obj->as.basic.flags == 0) return;       /* free cell */
         | 
| 413 | 
            -
                 if (obj->as.basic.flags & FL_MARK) return;  /* already marked */
         | 
| 414 | 
            -
                 obj->as.basic.flags |= FL_MARK;
         | 
| 415 | 
            -
             
         | 
| 416 | 
            -
            +    /* mark our new reference point for sourcefile objects */
         | 
| 417 | 
            -
            +    mark_source_filename(RANY(obj)->file);
         | 
| 418 | 
            -
            +
         | 
| 419 | 
            -
                 if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) {
         | 
| 420 | 
            -
             	if (!mark_stack_overflow) {
         | 
| 421 | 
            -
             	    if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {
         | 
| 422 | 
            -
            @@ -1077,6 +1078,10 @@ gc_mark(ptr, lev)
         | 
| 423 | 
            -
                 if (obj->as.basic.flags == 0) return;       /* free cell */
         | 
| 424 | 
            -
                 if (obj->as.basic.flags & FL_MARK) return;  /* already marked */
         | 
| 425 | 
            -
                 obj->as.basic.flags |= FL_MARK;
         | 
| 426 | 
            -
            +
         | 
| 427 | 
            -
            +    /* mark our new reference point for sourcefile objects */
         | 
| 428 | 
            -
            +    mark_source_filename(RANY(obj)->file);
         | 
| 429 | 
            -
            +
         | 
| 430 | 
            -
             
         | 
| 431 | 
            -
                 if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) {
         | 
| 432 | 
            -
             	if (!mark_stack_overflow) {
         | 
| 433 | 
            -
            @@ -1115,6 +1120,10 @@ gc_mark_children(ptr, lev)
         | 
| 434 | 
            -
                 if (obj->as.basic.flags == 0) return;       /* free cell */
         | 
| 435 | 
            -
                 if (obj->as.basic.flags & FL_MARK) return;  /* already marked */
         | 
| 436 | 
            -
                 obj->as.basic.flags |= FL_MARK;
         | 
| 437 | 
            -
            +
         | 
| 438 | 
            -
            +    /* mark our new reference point for sourcefile objects */
         | 
| 439 | 
            -
            +    mark_source_filename(RANY(obj)->file);
         | 
| 440 | 
            -
            +
         | 
| 441 | 
            -
             
         | 
| 442 | 
            -
               marking:
         | 
| 443 | 
            -
                 if (FL_TEST(obj, FL_EXIVAR)) {
         | 
| 444 | 
            -
            diff --git a/parse.c b/parse.c
         | 
| 445 | 
            -
            index 6b3d80d..b320cf2 100644
         | 
| 446 | 
            -
            --- a/parse.c
         | 
| 447 | 
            -
            +++ b/parse.c
         | 
| 448 | 
            -
            @@ -11403,6 +11403,11 @@ symbols_i(key, value, ary)
         | 
| 449 | 
            -
              *                                     :wait2, :$>]
         | 
| 450 | 
            -
              */
         | 
| 451 | 
            -
             
         | 
| 452 | 
            -
            +struct st_table *
         | 
| 453 | 
            -
            +rb_parse_sym_tbl() {
         | 
| 454 | 
            -
            +  return sym_tbl;
         | 
| 455 | 
            -
            +}
         | 
| 456 | 
            -
            +
         | 
| 457 | 
            -
             VALUE
         | 
| 458 | 
            -
             rb_sym_all_symbols()
         | 
| 459 | 
            -
             {
         | 
| 460 | 
            -
            diff --git a/parse.y b/parse.y
         | 
| 461 | 
            -
            index ab0b83c..3ce1dfb 100644
         | 
| 462 | 
            -
            --- a/parse.y
         | 
| 463 | 
            -
            +++ b/parse.y
         | 
| 464 | 
            -
            @@ -6263,6 +6263,11 @@ symbols_i(key, value, ary)
         | 
| 465 | 
            -
              *                                     :wait2, :$>]
         | 
| 466 | 
            -
              */
         | 
| 467 | 
            -
             
         | 
| 468 | 
            -
            +struct st_table *
         | 
| 469 | 
            -
            +rb_parse_sym_tbl() {
         | 
| 470 | 
            -
            +  return sym_tbl;
         | 
| 471 | 
            -
            +}
         | 
| 472 | 
            -
            +
         | 
| 473 | 
            -
             VALUE
         | 
| 474 | 
            -
             rb_sym_all_symbols()
         | 
| 475 | 
            -
             {
         | 
| 476 | 
            -
            diff --git a/version.h b/version.h
         | 
| 477 | 
            -
            index 70fc28a..76aa188 100644
         | 
| 478 | 
            -
            --- a/version.h
         | 
| 479 | 
            -
            +++ b/version.h
         | 
| 480 | 
            -
            @@ -5,2 +5,2 @@
         | 
| 481 | 
            -
            -#define RUBY_PATCHLEVEL 174
         | 
| 482 | 
            -
            +#define RUBY_PATCHLEVEL 905
         | 
| 483 | 
            -
             |