From 4d467a08650273f3e20dbc4dc78592a2237362a9 Mon Sep 17 00:00:00 2001 From: matz Date: Mon, 12 Dec 2005 00:36:54 +0000 Subject: * ext/digest/digest.c (rb_digest_base_s_digest): add volatile to protect temporary context object. [ruby-dev:27979] * ext/iconv/iconv.c (Init_iconv): rb_gc_register_address() should be called before actual variable initialization. [ruby-dev:27986] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9673 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 9 +++++ compar.c | 4 +-- enum.c | 2 +- eval.c | 6 ++-- ext/digest/digest.c | 92 ++++++++++++++----------------------------------- ext/digest/digest.h | 10 +++--- ext/etc/etc.c | 4 +-- ext/iconv/iconv.c | 2 +- ext/win32ole/win32ole.c | 4 +-- gc.c | 12 +++++-- io.c | 2 +- main.c | 4 +++ ruby.c | 2 +- signal.c | 4 +++ variable.c | 4 ++- 15 files changed, 73 insertions(+), 88 deletions(-) diff --git a/ChangeLog b/ChangeLog index b050081f5f..155c9d7a43 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Mon Dec 12 00:33:56 2005 Yukihiro Matsumoto + + * ext/digest/digest.c (rb_digest_base_s_digest): add volatile to + protect temporary context object. [ruby-dev:27979] + + * ext/iconv/iconv.c (Init_iconv): rb_gc_register_address() should + be called before actual variable initialization. + [ruby-dev:27986] + Sun Dec 11 22:07:58 2005 Masatoshi SEKI * test/rinda/test_rinda.rb (test_remote_array_and_hash): pseudo remote diff --git a/compar.c b/compar.c index 234a86027d..80c4c70ca6 100644 --- a/compar.c +++ b/compar.c @@ -53,7 +53,7 @@ cmp_eq(VALUE *a) { VALUE c = rb_funcall(a[0], cmp, 1, a[1]); - if (NIL_P(c)) return Qnil; + if (NIL_P(c)) return Qfalse; if (rb_cmpint(c, a[0], a[1]) == 0) return Qtrue; return Qfalse; } @@ -61,7 +61,7 @@ cmp_eq(VALUE *a) static VALUE cmp_failed(void) { - return Qnil; + return Qfalse; } /* diff --git a/enum.c b/enum.c index 2229f49da5..578ea6b4b9 100644 --- a/enum.c +++ b/enum.c @@ -449,7 +449,7 @@ sort_by_cmp(const void *ap, const void *bp, void *data) * values in enum through the given block. * * %w{ apple pear fig }.sort_by {|word| word.length} - #=> ["fig", "pear", "apple"] + #=> ["fig", "pear", "apple"] * * The current implementation of sort_by generates an * array of tuples containing the original collection element and the diff --git a/eval.c b/eval.c index b106919545..7be4861ceb 100644 --- a/eval.c +++ b/eval.c @@ -7760,14 +7760,14 @@ rb_f_autoload_p(VALUE obj, VALUE sym) void Init_load(void) { - rb_load_path = rb_ary_new(); rb_define_readonly_variable("$:", &rb_load_path); rb_define_readonly_variable("$-I", &rb_load_path); rb_define_readonly_variable("$LOAD_PATH", &rb_load_path); + rb_load_path = rb_ary_new(); - rb_features = rb_ary_new(); rb_define_readonly_variable("$\"", &rb_features); rb_define_readonly_variable("$LOADED_FEATURES", &rb_features); + rb_features = rb_ary_new(); rb_define_global_function("load", rb_f_load, -1); rb_define_global_function("require", rb_f_require, 1); @@ -7777,8 +7777,8 @@ Init_load(void) rb_define_global_function("autoload?", rb_f_autoload_p, 1); rb_global_variable(&ruby_wrapper); - ruby_dln_librefs = rb_ary_new(); rb_global_variable(&ruby_dln_librefs); + ruby_dln_librefs = rb_ary_new(); } static void diff --git a/ext/digest/digest.c b/ext/digest/digest.c index 70f986327a..a63d353ddf 100644 --- a/ext/digest/digest.c +++ b/ext/digest/digest.c @@ -41,8 +41,7 @@ static ID id_metadata; */ static algo_t * -get_digest_base_metadata(klass) - VALUE klass; +get_digest_base_metadata(VALUE klass) { VALUE obj; algo_t *algo; @@ -58,10 +57,8 @@ get_digest_base_metadata(klass) return algo; } -static VALUE rb_digest_base_alloc _((VALUE)); static VALUE -rb_digest_base_alloc(klass) - VALUE klass; +rb_digest_base_alloc(VALUE klass) { algo_t *algo; VALUE obj; @@ -83,15 +80,12 @@ rb_digest_base_alloc(klass) } static VALUE -rb_digest_base_s_digest(klass, str) - VALUE klass; - VALUE str; +rb_digest_base_s_digest(VALUE klass, VALUE str) { algo_t *algo; void *pctx; - size_t len; unsigned char *digest; - VALUE obj = rb_digest_base_alloc(klass); + volatile VALUE obj = rb_digest_base_alloc(klass); algo = get_digest_base_metadata(klass); Data_Get_Struct(obj, void, pctx); @@ -99,28 +93,19 @@ rb_digest_base_s_digest(klass, str) StringValue(str); algo->update_func(pctx, RSTRING(str)->ptr, RSTRING(str)->len); - len = algo->digest_len; - - digest = xmalloc(len); - algo->final_func(digest, pctx); - - obj = rb_str_new(digest, len); - - free(digest); + str = rb_str_new(0, algo->digest_len); + algo->final_func(RSTRING(str)->ptr, pctx); - return obj; + return str; } static VALUE -rb_digest_base_s_hexdigest(klass, str) - VALUE klass; - VALUE str; +rb_digest_base_s_hexdigest(VALUE klass, VALUE str) { algo_t *algo; void *pctx; - size_t len; unsigned char *hexdigest; - VALUE obj = rb_digest_base_alloc(klass); + volatile VALUE obj = rb_digest_base_alloc(klass); algo = get_digest_base_metadata(klass); Data_Get_Struct(obj, void, pctx); @@ -128,21 +113,14 @@ rb_digest_base_s_hexdigest(klass, str) StringValue(str); algo->update_func(pctx, RSTRING(str)->ptr, RSTRING(str)->len); - len = algo->digest_len * 2; - - hexdigest = xmalloc(len + 1); /* +1 is for '\0' */ - algo->end_func(pctx, hexdigest); - - obj = rb_str_new(hexdigest, len); + str = rb_str_new(0, algo->digest_len * 2); + algo->end_func(pctx, RSTRING(str)->ptr); - free(hexdigest); - - return obj; + return str; } static VALUE -rb_digest_base_copy(copy, obj) - VALUE copy, obj; +rb_digest_base_copy(VALUE copy, VALUE obj) { algo_t *algo; void *pctx1, *pctx2; @@ -161,8 +139,7 @@ rb_digest_base_copy(copy, obj) } static VALUE -rb_digest_base_update(self, str) - VALUE self, str; +rb_digest_base_update(VALUE self, VALUE str) { algo_t *algo; void *pctx; @@ -177,10 +154,7 @@ rb_digest_base_update(self, str) } static VALUE -rb_digest_base_init(argc, argv, self) - int argc; - VALUE* argv; - VALUE self; +rb_digest_base_init(int argc, VALUE *argv, VALUE self) { VALUE arg; @@ -192,8 +166,7 @@ rb_digest_base_init(argc, argv, self) } static VALUE -rb_digest_base_digest(self) - VALUE self; +rb_digest_base_digest(VALUE self) { algo_t *algo; void *pctx1, *pctx2; @@ -204,58 +177,43 @@ rb_digest_base_digest(self) algo = get_digest_base_metadata(rb_obj_class(self)); Data_Get_Struct(self, void, pctx1); - len = algo->ctx_size; + str = rb_str_new(0, algo->digest_len); + len = algo->ctx_size; pctx2 = xmalloc(len); memcpy(pctx2, pctx1, len); - len = algo->digest_len; - - digest = xmalloc(len); - algo->final_func(digest, pctx2); - - str = rb_str_new(digest, len); - - free(digest); + algo->final_func(RSTRING(str)->ptr, pctx2); free(pctx2); return str; } static VALUE -rb_digest_base_hexdigest(self) - VALUE self; +rb_digest_base_hexdigest(VALUE self) { algo_t *algo; void *pctx1, *pctx2; - unsigned char *hexdigest; size_t len; VALUE str; algo = get_digest_base_metadata(rb_obj_class(self)); Data_Get_Struct(self, void, pctx1); - len = algo->ctx_size; + str = rb_str_new(0, algo->digest_len * 2); + len = algo->ctx_size; pctx2 = xmalloc(len); memcpy(pctx2, pctx1, len); - len = algo->digest_len * 2; - - hexdigest = xmalloc(len + 1); /* +1 is for '\0' */ - algo->end_func(pctx2, hexdigest); - - str = rb_str_new(hexdigest, len); - - free(hexdigest); + algo->end_func(pctx2, RSTRING(str)->ptr); free(pctx2); return str; } static VALUE -rb_digest_base_equal(self, other) - VALUE self, other; +rb_digest_base_equal(VALUE self, VALUE other) { algo_t *algo; VALUE klass; @@ -282,7 +240,7 @@ rb_digest_base_equal(self, other) str1 = rb_digest_base_hexdigest(self); if (RSTRING(str1)->len == RSTRING(str2)->len - && rb_str_cmp(str1, str2) == 0) + && rb_str_cmp(str1, str2) == 0) return Qtrue; return Qfalse; diff --git a/ext/digest/digest.h b/ext/digest/digest.h index 5e846df040..878aaddd02 100644 --- a/ext/digest/digest.h +++ b/ext/digest/digest.h @@ -15,11 +15,11 @@ #include "ruby.h" -typedef void (*hash_init_func_t) _((void *)); -typedef void (*hash_update_func_t) _((void *, unsigned char *, size_t)); -typedef void (*hash_end_func_t) _((void *, unsigned char *)); -typedef void (*hash_final_func_t) _((unsigned char *, void *)); -typedef int (*hash_equal_func_t) _((void *, void *)); +typedef void (*hash_init_func_t)(void *); +typedef void (*hash_update_func_t)(void *, unsigned char *, size_t); +typedef void (*hash_end_func_t)(void *, unsigned char *); +typedef void (*hash_final_func_t)(unsigned char *, void *); +typedef int (*hash_equal_func_t)(void *, void *); typedef struct { size_t digest_len; diff --git a/ext/etc/etc.c b/ext/etc/etc.c index 94196e066a..ac95735549 100644 --- a/ext/etc/etc.c +++ b/ext/etc/etc.c @@ -521,6 +521,7 @@ Init_etc() rb_define_module_function(mEtc, "endgrent", etc_endgrent, 0); rb_define_module_function(mEtc, "getgrent", etc_getgrent, 0); + rb_global_variable(&sPasswd); sPasswd = rb_struct_define("Passwd", "name", "passwd", "uid", "gid", #ifdef HAVE_ST_PW_GECOS @@ -546,14 +547,13 @@ Init_etc() "expire", #endif NULL); - rb_global_variable(&sPasswd); #ifdef HAVE_GETGRENT + rb_global_variable(&sGroup); sGroup = rb_struct_define("Group", "name", #ifdef HAVE_ST_GR_PASSWD "passwd", #endif "gid", "mem", NULL); - rb_global_variable(&sGroup); #endif } diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index a1aa484c68..cebbd912fe 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -1083,8 +1083,8 @@ Init_iconv(void) id_transliterate = rb_intern("transliterate"); id_discard_ilseq = rb_intern("discard_ilseq"); - charset_map = rb_hash_new(); rb_gc_register_address(&charset_map); + charset_map = rb_hash_new(); rb_define_singleton_method(rb_cIconv, "charset_map", charset_map_get, 0); } diff --git a/ext/win32ole/win32ole.c b/ext/win32ole/win32ole.c index 32d92b639e..fde5d2d456 100644 --- a/ext/win32ole/win32ole.c +++ b/ext/win32ole/win32ole.c @@ -6904,8 +6904,8 @@ folevariant_value(self) void Init_win32ole() { - ary_ole_event = rb_ary_new(); rb_global_variable(&ary_ole_event); + ary_ole_event = rb_ary_new(); id_events = rb_intern("events"); com_vtbl.QueryInterface = QueryInterface; @@ -6915,8 +6915,8 @@ Init_win32ole() com_vtbl.GetTypeInfo = GetTypeInfo; com_vtbl.GetIDsOfNames = GetIDsOfNames; com_vtbl.Invoke = Invoke; - com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable()); rb_global_variable(&com_hash); + com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable()); cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject); diff --git a/gc.c b/gc.c index 887551444a..46523dcdc4 100644 --- a/gc.c +++ b/gc.c @@ -106,6 +106,12 @@ rb_memerror(void) rb_exc_raise(nomem_error); } +#ifdef RUBY_GC_DEBUG +int always_gc = 0; +#else +# define always_gc 0 +#endif + void * ruby_xmalloc(size_t size) { @@ -117,7 +123,7 @@ ruby_xmalloc(size_t size) if (size == 0) size = 1; malloc_increase += size; - if (malloc_increase > malloc_limit) { + if (always_gc || malloc_increase > malloc_limit) { garbage_collect(); } RUBY_CRITICAL(mem = malloc(size)); @@ -165,6 +171,7 @@ ruby_xrealloc(void *ptr, size_t size) if (!ptr) return ruby_xmalloc(size); if (size == 0) size = 1; malloc_increase += size; + if (always_gc) garbage_collect(); RUBY_CRITICAL(mem = realloc(ptr, size)); if (!mem) { if (garbage_collect()) { @@ -394,7 +401,7 @@ rb_newobj(void) { VALUE obj; - if (!freelist && !garbage_collect()) + if ((always_gc || !freelist) && !garbage_collect()) rb_memerror(); obj = (VALUE)freelist; @@ -1018,6 +1025,7 @@ gc_sweep(void) unsigned long live = 0; mark_source_filename(ruby_sourcefile); + if (source_filenames) st_foreach(source_filenames, sweep_source_filename, 0); freelist = 0; diff --git a/io.c b/io.c index f8395f144e..dc91b41f74 100644 --- a/io.c +++ b/io.c @@ -5482,9 +5482,9 @@ Init_IO(void) rb_output_fs = Qnil; rb_define_hooked_variable("$,", &rb_output_fs, 0, rb_str_setter); + rb_global_variable(&rb_default_rs); rb_rs = rb_default_rs = rb_str_new2("\n"); rb_output_rs = Qnil; - rb_global_variable(&rb_default_rs); OBJ_FREEZE(rb_default_rs); /* avoid modifying RS_default */ rb_define_hooked_variable("$/", &rb_rs, 0, rb_str_setter); rb_define_hooked_variable("$-0", &rb_rs, 0, rb_str_setter); diff --git a/main.c b/main.c index 16cd6ca2ea..3c1903ab33 100644 --- a/main.c +++ b/main.c @@ -24,6 +24,10 @@ static void objcdummyfunction( void ) { objc_msgSend(); } int main(int argc, char **argv, char **envp) { +#ifdef RUBY_GC_DEBUG + extern int always_gc; + always_gc = getenv("RUBY_ALWAYS_GC") != NULL; +#endif #ifdef _WIN32 NtInitialize(&argc, &argv); #endif diff --git a/ruby.c b/ruby.c index 71d69625ac..353040f89d 100644 --- a/ruby.c +++ b/ruby.c @@ -1159,8 +1159,8 @@ ruby_prog_init(void) rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0); rb_define_hooked_variable("$PROGRAM_NAME", &rb_progname, 0, set_arg0); - rb_argv = rb_ary_new(); rb_define_readonly_variable("$*", &rb_argv); + rb_argv = rb_ary_new(); rb_define_global_const("ARGV", rb_argv); rb_define_readonly_variable("$-a", &do_split); rb_global_variable(&rb_argv0); diff --git a/signal.c b/signal.c index 2bbf9e84b9..9a1044c991 100644 --- a/signal.c +++ b/signal.c @@ -944,10 +944,14 @@ Init_signal(void) #endif #ifdef SIGBUS +# ifndef RUBY_GC_DEBUG install_sighandler(SIGBUS, sigbus); +# endif #endif #ifdef SIGSEGV +# ifndef RUBY_GC_DEBUG install_sighandler(SIGSEGV, sigsegv); +# endif #endif #ifdef SIGPIPE install_sighandler(SIGPIPE, sigpipe); diff --git a/variable.c b/variable.c index 565a1f2b17..c6e54c3d10 100644 --- a/variable.c +++ b/variable.c @@ -424,7 +424,9 @@ mark_global_entry(ID key, struct global_entry *entry) void rb_gc_mark_global_tbl(void) { - st_foreach_safe(rb_global_tbl, mark_global_entry, 0); + if (rb_global_tbl) { + st_foreach(rb_global_tbl, mark_global_entry, 0); + } } static ID -- cgit v1.2.3