ssoroka-bleak_house 4.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/snapshot.c ADDED
@@ -0,0 +1,150 @@
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
+ /* Walk the live, instrumented objects on the heap and write them to <tt>_logfile</tt>. */
18
+ static VALUE snapshot(VALUE self, VALUE _logfile) {
19
+ Check_Type(_logfile, T_STRING);
20
+
21
+ RVALUE *obj, *obj_end;
22
+ st_table_entry *sym;
23
+
24
+ struct heaps_slot * heaps = rb_gc_heap_slots();
25
+ struct st_table * sym_tbl = rb_parse_sym_tbl();
26
+
27
+ /* see if the logfile exists already */
28
+ FILE *logfile = fopen(StringValueCStr(_logfile), "r");
29
+ int is_new;
30
+ if (!(is_new = (logfile == NULL)))
31
+ fclose(logfile);
32
+
33
+ /* reopen for writing */
34
+ if ((logfile = fopen(StringValueCStr(_logfile), "w")) == NULL)
35
+ rb_raise(rb_eRuntimeError, "couldn't open snapshot file");
36
+
37
+ int filled_slots = 0;
38
+ int free_slots = 0;
39
+
40
+ int i;
41
+ char * chr;
42
+
43
+ for (i = 0; i < 3; i++) {
44
+ /* request GC run */
45
+ rb_funcall(rb_mGC, rb_intern("start"), 0);
46
+ rb_thread_schedule();
47
+ }
48
+
49
+ /* walk the heap */
50
+ for (i = 0; i < rb_gc_heaps_used(); i++) {
51
+ obj = heaps[i].slot;
52
+ obj_end = obj + heaps[i].limit;
53
+ for (; obj < obj_end; obj++) {
54
+ if (obj->as.basic.flags) { /* always 0 for freed objects */
55
+ filled_slots ++;
56
+
57
+ /* write the source file*/
58
+ if (obj->file) {
59
+ chr = obj->file;
60
+ if (*chr != '\0') {
61
+ fprintf(logfile, "%s", obj->file);
62
+ } else {
63
+ fprintf(logfile, "__empty__");
64
+ }
65
+ } else {
66
+ fprintf(logfile, "__null__");
67
+ }
68
+
69
+ /* write the source line */
70
+ fprintf(logfile, ":");
71
+ if (obj->line) {
72
+ fprintf(logfile, "%i", obj->line);
73
+ } else {
74
+ fprintf(logfile, "__null__");
75
+ }
76
+
77
+ /* write the class */
78
+ fprintf(logfile, ":");
79
+ switch (TYPE(obj)) {
80
+ case T_NONE:
81
+ fprintf(logfile, "__none__"); break;
82
+ case T_BLKTAG:
83
+ fprintf(logfile, "__blktag__"); break;
84
+ case T_UNDEF:
85
+ fprintf(logfile, "__undef__"); break;
86
+ case T_VARMAP:
87
+ fprintf(logfile, "__varmap__"); break;
88
+ case T_SCOPE:
89
+ fprintf(logfile, "__scope__"); break;
90
+ case T_NODE:
91
+ fprintf(logfile, "__node__"); break;
92
+ default:
93
+ if (!obj->as.basic.klass) {
94
+ fprintf(logfile, "__unknown__");
95
+ } else {
96
+ fprintf(logfile, rb_obj_classname((VALUE)obj));
97
+ }
98
+ }
99
+
100
+ /* write newline */
101
+ fprintf(logfile, "\n");
102
+ } else {
103
+ free_slots ++;
104
+ }
105
+ }
106
+ }
107
+
108
+ /* walk the symbol table */
109
+ /* hashed = lookup_builtin("Symbol");
110
+ for (i = 0; i < sym_tbl->num_bins; i++) {
111
+ for (sym = sym_tbl->bins[i]; sym != 0; sym = sym->next) {
112
+ fprintf(logfile, "%i,%lu\n", hashed + 1, sym->record);
113
+ }
114
+ } */
115
+
116
+ fprintf(logfile, "%i filled\n", filled_slots);
117
+ fprintf(logfile, "%i free\n", free_slots);
118
+ fclose(logfile);
119
+
120
+ return Qnil;
121
+ }
122
+
123
+
124
+ /*
125
+
126
+ This class performs the actual object logging of BleakHouse. To use it directly, you need to make calls to BleakHouse.snapshot.
127
+
128
+ By default, BleakHouse records a snapshot on exit. You can disable this by setting the environment variable <tt>NO_EXIT_HANDLER</tt> before startup.
129
+
130
+ It is also possible to externally trigger the snapshot at any time by sending <tt>SIGUSR2</tt> to the process.
131
+
132
+ == Example
133
+
134
+ At the start of your app, put:
135
+ require 'rubygems'
136
+ require 'bleak_house'
137
+ $logfile = "/path/to/logfile"
138
+
139
+ Run your app. Once it exits, analyze your data:
140
+ bleak /path/to/logfile
141
+
142
+ */
143
+ void
144
+ Init_snapshot()
145
+ {
146
+ rb_mB = rb_define_module("BleakHouse");
147
+ rb_define_singleton_method(rb_mB, "snapshot", snapshot, 1);
148
+ rb_define_singleton_method(rb_mB, "heaps_used", heaps_used, 0);
149
+ rb_define_singleton_method(rb_mB, "heaps_length", heaps_length, 0);
150
+ }
data/ext/snapshot.h ADDED
@@ -0,0 +1,59 @@
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 *);
@@ -0,0 +1,54 @@
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
@@ -0,0 +1,25 @@
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.#{Process.pid}.#{@count}.dump"
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
+ BleakHouse.hook
23
+ end
24
+
25
+
@@ -0,0 +1,7 @@
1
+
2
+ unless RUBY_PATCHLEVEL > 900
3
+ raise "This build of Ruby has not been successfully patched for BleakHouse."
4
+ end
5
+
6
+ require 'snapshot'
7
+ require 'bleak_house/hook'
@@ -0,0 +1,242 @@
1
+ Index: configure
2
+ ===================================================================
3
+ --- configure (revision 6446)
4
+ +++ configure (working copy)
5
+ @@ -720,6 +720,7 @@
6
+ ARCHFILE
7
+ RDOCTARGET
8
+ XCFLAGS
9
+ +VALGRIND_CFLAGS
10
+ XLDFLAGS
11
+ LIBRUBY_LDSHARED
12
+ LIBRUBY_DLDFLAGS
13
+ @@ -1356,6 +1357,7 @@
14
+ --enable-pthread use pthread library.
15
+ --disable-fastthread do not use the fastthread mutex
16
+ --enable-setreuid use setreuid()/setregid() according to need even if obsolete.
17
+ + --enable-valgrind use valgrind support
18
+ --disable-rpath embed run path into extension libraries.
19
+ --enable-shared build a shared library for Ruby.
20
+ --enable-install-doc build and install rdoc indexes during install
21
+ @@ -12988,13 +12990,11 @@
22
+ cat confdefs.h >>conftest.$ac_ext
23
+ cat >>conftest.$ac_ext <<_ACEOF
24
+ /* end confdefs.h. */
25
+ -#include <sys/types.h> /* for off_t */
26
+ - #include <stdio.h>
27
+ +#include <stdio.h>
28
+ int
29
+ main ()
30
+ {
31
+ -int (*fp) (FILE *, off_t, int) = fseeko;
32
+ - return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
33
+ +return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
34
+ ;
35
+ return 0;
36
+ }
37
+ @@ -13034,13 +13034,11 @@
38
+ cat >>conftest.$ac_ext <<_ACEOF
39
+ /* end confdefs.h. */
40
+ #define _LARGEFILE_SOURCE 1
41
+ -#include <sys/types.h> /* for off_t */
42
+ - #include <stdio.h>
43
+ +#include <stdio.h>
44
+ int
45
+ main ()
46
+ {
47
+ -int (*fp) (FILE *, off_t, int) = fseeko;
48
+ - return fseeko (stdin, 0, 0) && fp (stdin, 0, 0);
49
+ +return fseeko (stdin, 0, 0) && (fseeko) (stdin, 0, 0);
50
+ ;
51
+ return 0;
52
+ }
53
+ @@ -15768,6 +15766,172 @@
54
+ fi
55
+ fi
56
+
57
+ +# Check whether --enable-valgrind was given.
58
+ +if test "${enable_valgrind+set}" = set; then
59
+ + enableval=$enable_valgrind; want_valgrind=$enableval
60
+ +else
61
+ + want_valgrind=auto
62
+ +fi
63
+ +
64
+ +
65
+ +if test x"$want_valgrind" != xno; then
66
+ +
67
+ +for ac_header in valgrind/memcheck.h
68
+ +do
69
+ +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
70
+ +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
71
+ + { echo "$as_me:$LINENO: checking for $ac_header" >&5
72
+ +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
73
+ +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
74
+ + echo $ECHO_N "(cached) $ECHO_C" >&6
75
+ +fi
76
+ +ac_res=`eval echo '${'$as_ac_Header'}'`
77
+ + { echo "$as_me:$LINENO: result: $ac_res" >&5
78
+ +echo "${ECHO_T}$ac_res" >&6; }
79
+ +else
80
+ + # Is the header compilable?
81
+ +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
82
+ +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
83
+ +cat >conftest.$ac_ext <<_ACEOF
84
+ +/* confdefs.h. */
85
+ +_ACEOF
86
+ +cat confdefs.h >>conftest.$ac_ext
87
+ +cat >>conftest.$ac_ext <<_ACEOF
88
+ +/* end confdefs.h. */
89
+ +$ac_includes_default
90
+ +#include <$ac_header>
91
+ +_ACEOF
92
+ +rm -f conftest.$ac_objext
93
+ +if { (ac_try="$ac_compile"
94
+ +case "(($ac_try" in
95
+ + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
96
+ + *) ac_try_echo=$ac_try;;
97
+ +esac
98
+ +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
99
+ + (eval "$ac_compile") 2>conftest.er1
100
+ + ac_status=$?
101
+ + grep -v '^ *+' conftest.er1 >conftest.err
102
+ + rm -f conftest.er1
103
+ + cat conftest.err >&5
104
+ + echo "$as_me:$LINENO: \$? = $ac_status" >&5
105
+ + (exit $ac_status); } && {
106
+ + test -z "$ac_c_werror_flag" ||
107
+ + test ! -s conftest.err
108
+ + } && test -s conftest.$ac_objext; then
109
+ + ac_header_compiler=yes
110
+ +else
111
+ + echo "$as_me: failed program was:" >&5
112
+ +sed 's/^/| /' conftest.$ac_ext >&5
113
+ +
114
+ + ac_header_compiler=no
115
+ +fi
116
+ +
117
+ +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
118
+ +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
119
+ +echo "${ECHO_T}$ac_header_compiler" >&6; }
120
+ +
121
+ +# Is the header present?
122
+ +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
123
+ +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
124
+ +cat >conftest.$ac_ext <<_ACEOF
125
+ +/* confdefs.h. */
126
+ +_ACEOF
127
+ +cat confdefs.h >>conftest.$ac_ext
128
+ +cat >>conftest.$ac_ext <<_ACEOF
129
+ +/* end confdefs.h. */
130
+ +#include <$ac_header>
131
+ +_ACEOF
132
+ +if { (ac_try="$ac_cpp conftest.$ac_ext"
133
+ +case "(($ac_try" in
134
+ + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
135
+ + *) ac_try_echo=$ac_try;;
136
+ +esac
137
+ +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
138
+ + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
139
+ + ac_status=$?
140
+ + grep -v '^ *+' conftest.er1 >conftest.err
141
+ + rm -f conftest.er1
142
+ + cat conftest.err >&5
143
+ + echo "$as_me:$LINENO: \$? = $ac_status" >&5
144
+ + (exit $ac_status); } >/dev/null && {
145
+ + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
146
+ + test ! -s conftest.err
147
+ + }; then
148
+ + ac_header_preproc=yes
149
+ +else
150
+ + echo "$as_me: failed program was:" >&5
151
+ +sed 's/^/| /' conftest.$ac_ext >&5
152
+ +
153
+ + ac_header_preproc=no
154
+ +fi
155
+ +
156
+ +rm -f conftest.err conftest.$ac_ext
157
+ +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
158
+ +echo "${ECHO_T}$ac_header_preproc" >&6; }
159
+ +
160
+ +# So? What about this header?
161
+ +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
162
+ + yes:no: )
163
+ + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
164
+ +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
165
+ + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
166
+ +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
167
+ + ac_header_preproc=yes
168
+ + ;;
169
+ + no:yes:* )
170
+ + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
171
+ +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
172
+ + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
173
+ +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
174
+ + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
175
+ +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
176
+ + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
177
+ +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
178
+ + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
179
+ +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
180
+ + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
181
+ +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
182
+ +
183
+ + ;;
184
+ +esac
185
+ +{ echo "$as_me:$LINENO: checking for $ac_header" >&5
186
+ +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
187
+ +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
188
+ + echo $ECHO_N "(cached) $ECHO_C" >&6
189
+ +else
190
+ + eval "$as_ac_Header=\$ac_header_preproc"
191
+ +fi
192
+ +ac_res=`eval echo '${'$as_ac_Header'}'`
193
+ + { echo "$as_me:$LINENO: result: $ac_res" >&5
194
+ +echo "${ECHO_T}$ac_res" >&6; }
195
+ +
196
+ +fi
197
+ +if test `eval echo '${'$as_ac_Header'}'` = yes; then
198
+ + cat >>confdefs.h <<_ACEOF
199
+ +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
200
+ +_ACEOF
201
+ + have_valgrind=yes
202
+ +else
203
+ + have_valgrind=no
204
+ +fi
205
+ +
206
+ +done
207
+ +
208
+ + if test x"$have_valgrind" = xyes; then
209
+ + cat >>confdefs.h <<\_ACEOF
210
+ +#define HAVE_VALGRIND 1
211
+ +_ACEOF
212
+ +
213
+ + VALGRIND_CFLAGS="";
214
+ + elif test x"$want_valgrind" = xyes -a x"$have_valgrind" = xno; then
215
+ + { { echo "$as_me:$LINENO: error: valgrind support requested but valgrind not found" >&5
216
+ +echo "$as_me: error: valgrind support requested but valgrind not found" >&2;}
217
+ + { (exit 1); exit 1; }; }
218
+ + else
219
+ + VALGRIND_CFLAGS="";
220
+ + fi
221
+ +fi
222
+ +
223
+ DEFAULT_KCODE="KCODE_NONE"
224
+
225
+
226
+ @@ -17854,6 +18018,7 @@
227
+ ARCHFILE!$ARCHFILE$ac_delim
228
+ RDOCTARGET!$RDOCTARGET$ac_delim
229
+ XCFLAGS!$XCFLAGS$ac_delim
230
+ +VALGRIND_CFLAGS!$VALGRIND_CFLAGS$ac_delim
231
+ XLDFLAGS!$XLDFLAGS$ac_delim
232
+ LIBRUBY_LDSHARED!$LIBRUBY_LDSHARED$ac_delim
233
+ LIBRUBY_DLDFLAGS!$LIBRUBY_DLDFLAGS$ac_delim
234
+ @@ -17887,7 +18052,7 @@
235
+ LTLIBOBJS!$LTLIBOBJS$ac_delim
236
+ _ACEOF
237
+
238
+ - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 42; then
239
+ + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 43; then
240
+ break
241
+ elif $ac_last_try; then
242
+ { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
data/ruby/gc.patch ADDED
@@ -0,0 +1,119 @@
1
+ Index: parse.y
2
+ ===================================================================
3
+ --- parse.y (revision 6446)
4
+ +++ parse.y (working copy)
5
+ @@ -6168,6 +6168,11 @@
6
+ * :wait2, :$>]
7
+ */
8
+
9
+ +struct st_table *
10
+ +rb_parse_sym_tbl() {
11
+ + return sym_tbl;
12
+ +}
13
+ +
14
+ VALUE
15
+ rb_sym_all_symbols()
16
+ {
17
+ Index: parse.c
18
+ ===================================================================
19
+ --- parse.c (revision 6446)
20
+ +++ parse.c (working copy)
21
+ @@ -11157,6 +11157,11 @@
22
+ * :wait2, :$>]
23
+ */
24
+
25
+ +struct st_table *
26
+ +rb_parse_sym_tbl() {
27
+ + return sym_tbl;
28
+ +}
29
+ +
30
+ VALUE
31
+ rb_sym_all_symbols()
32
+ {
33
+ Index: gc.c
34
+ ===================================================================
35
+ --- gc.c (revision 6446)
36
+ +++ gc.c (working copy)
37
+ @@ -260,8 +260,6 @@
38
+ }
39
+ }
40
+
41
+ -#undef GC_DEBUG
42
+ -
43
+ void
44
+ rb_global_variable(var)
45
+ VALUE *var;
46
+ @@ -296,10 +294,8 @@
47
+ struct RVarmap varmap;
48
+ struct SCOPE scope;
49
+ } as;
50
+ -#ifdef GC_DEBUG
51
+ char *file;
52
+ int line;
53
+ -#endif
54
+ } RVALUE;
55
+
56
+ #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__)
57
+ @@ -318,6 +314,22 @@
58
+ static int heaps_length = 0;
59
+ static int heaps_used = 0;
60
+
61
+ +struct heaps_slot *
62
+ +rb_gc_heap_slots()
63
+ +{
64
+ + return heaps;
65
+ +}
66
+ +
67
+ +int
68
+ +rb_gc_heaps_used() {
69
+ + return heaps_used;
70
+ +}
71
+ +
72
+ +int
73
+ +rb_gc_heaps_length() {
74
+ + return heaps_length;
75
+ +}
76
+ +
77
+ #define HEAP_MIN_SLOTS 10000
78
+ static int heap_slots = HEAP_MIN_SLOTS;
79
+
80
+ @@ -396,9 +408,11 @@
81
+ freelist = freelist->as.free.next;
82
+ MEMZERO((void*)obj, RVALUE, 1);
83
+ -#ifdef GC_DEBUG
84
+ - RANY(obj)->file = ruby_sourcefile;
85
+ - RANY(obj)->line = ruby_sourceline;
86
+ -#endif
87
+ +
88
+ + if (ruby_current_node && ruby_current_node->nd_file) {
89
+ + RANY(obj)->file = ruby_current_node->nd_file;
90
+ + RANY(obj)->line = nd_line(ruby_current_node);
91
+ + }
92
+ +
93
+ return obj;
94
+ }
95
+
96
+ @@ -732,7 +747,10 @@
97
+ if (rb_special_const_p(ptr)) return; /* special const not marked */
98
+ if (obj->as.basic.flags == 0) return; /* free cell */
99
+ if (obj->as.basic.flags & FL_MARK) return; /* already marked */
100
+ +
101
+ obj->as.basic.flags |= FL_MARK;
102
+ + /* mark our new reference point for sourcefile objects */
103
+ + mark_source_filename(RANY(obj)->file);
104
+
105
+ if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) {
106
+ if (!mark_stack_overflow) {
107
+ Index: version.h
108
+ ===================================================================
109
+ --- version.h (revision 6439)
110
+ +++ version.h (working copy)
111
+ @@ -2,7 +2,7 @@
112
+ #define RUBY_RELEASE_DATE "2008-06-20"
113
+ #define RUBY_VERSION_CODE 186
114
+ #define RUBY_RELEASE_CODE 20080620
115
+ -#define RUBY_PATCHLEVEL 230
116
+ +#define RUBY_PATCHLEVEL 902
117
+
118
+ #define RUBY_VERSION_MAJOR 1
119
+ #define RUBY_VERSION_MINOR 8
Binary file