ruby-changes:6320
From: nobu <ko1@a...>
Date: Thu, 3 Jul 2008 07:19:37 +0900 (JST)
Subject: [ruby-changes:6320] Ruby:r17836 (mvm): * merged from trunk r17785:17835.
nobu 2008-07-03 07:18:15 +0900 (Thu, 03 Jul 2008) New Revision: 17836 Modified files: branches/mvm/.merged-trunk-revision branches/mvm/ChangeLog branches/mvm/Makefile.in branches/mvm/eval.c branches/mvm/ext/bigdecimal/bigdecimal.c branches/mvm/ext/json/ext/generator/generator.c branches/mvm/ext/win32ole/win32ole.c branches/mvm/gc.c branches/mvm/include/ruby/intern.h branches/mvm/missing/tgamma.c branches/mvm/proc.c branches/mvm/rational.c branches/mvm/regint.h branches/mvm/sprintf.c branches/mvm/test/ruby/test_settracefunc.rb branches/mvm/test/win32ole/test_win32ole_event.rb branches/mvm/version.h Log: * merged from trunk r17785:17835. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=17836 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/version.h?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/test/ruby/test_settracefunc.rb?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/ext/win32ole/win32ole.c?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/ChangeLog?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/ext/json/ext/generator/generator.c?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/sprintf.c?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/gc.c?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/ext/bigdecimal/bigdecimal.c?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/test/win32ole/test_win32ole_event.rb?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/rational.c?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/regint.h?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/missing/tgamma.c?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/include/ruby/intern.h?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/eval.c?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/Makefile.in?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/proc.c?r1=17836&r2=17835&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/.merged-trunk-revision?r1=17836&r2=17835&diff_format=u Index: mvm/include/ruby/intern.h =================================================================== --- mvm/include/ruby/intern.h (revision 17835) +++ mvm/include/ruby/intern.h (revision 17836) @@ -329,6 +329,7 @@ NORETURN(void rb_memerror(void)); int ruby_stack_check(void); int ruby_stack_length(VALUE**); +int rb_during_gc(void); void rb_gc_mark_locations(VALUE*, VALUE*); void rb_mark_tbl(struct st_table*); void rb_mark_set(struct st_table*); Index: mvm/ChangeLog =================================================================== --- mvm/ChangeLog (revision 17835) +++ mvm/ChangeLog (revision 17836) @@ -1,3 +1,60 @@ +Thu Jul 3 07:06:02 2008 Nobuyoshi Nakada <nobu@r...> + + * Makefile.in (SET_LC_MESSAGES): LC_MESSAGES must be C. + +Thu Jul 3 07:02:55 2008 Nobuyoshi Nakada <nobu@r...> + + * eval.c (Init_eval), gc.c (Init_GC), proc.c (Init_Proc): freeze + messages of preallocated special exceptions also. + +Thu Jul 3 04:39:30 2008 Nobuyoshi Nakada <nobu@r...> + + * gc.c (rb_during_gc): VALUE cache is irrelevant. + +Thu Jul 3 01:44:01 2008 Yusuke Endoh <mame@t...> + + * regint.h (GET_ALIGNMENT_PAD_SIZE, ALIGNMENT_RIGHT): cast pointer to + uintptr_t instead of unsigned int. + +Thu Jul 3 01:23:13 2008 Yusuke Endoh <mame@t...> + + * sprintf.c: include ieeefp.h to refer isinf. + + * ext/bigdecimal/bigdecimal.c: ditto. + + * ext/json/ext/generator/generator.c: ditto. + + * rational.c: ditto. + +Thu Jul 3 01:01:57 2008 Yusuke Endoh <mame@t...> + + * missing/tgamma.c (tgamma): remove unused variable. + +Thu Jul 3 00:18:00 2008 Masaki Suketa <masaki.suketa@n...> + + * ext/win32ole/win32ole.c: avoid creating Ruby object during + GC. thanks to arton <artonx AT yahoo.co.jp>. [ruby-dev:35313] + + * test/win32ole/test_win32ole_event.rb: ditto. + +Thu Jul 3 00:09:31 2008 Masaki Suketa <masaki.suketa@n...> + + * gc.c: add rb_during_gc(). based on a patch from arton <artonx AT + yahoo.co.jp> at [ruby-dev:35313]. + + * include/ruby/intern.h: ditto. + +Wed Jul 2 09:49:10 2008 Narihiro Nakamura <authorNari@g...> + + * gc.c (gc_lazy_sweep) : use lazy sweep algorithm for response performance gain. + (garbage_collect_force) : mark and lazysweep invoke, after erasing all mark. + (GC_NOT_LAZY_SWEEP) : not lazy sweep flag. for debug. + +Wed Jul 2 03:42:44 2008 Yusuke Endoh <mame@t...> + + * test/ruby/test_settracefunc.rb: fix expected traces for + RubyVM::FrozenCore's event and r17744. + Wed Jul 2 03:10:41 2008 Koichi Sasada <ko1@a...> * compile.h, insns.def: reduce insn operand of "trace". Index: mvm/proc.c =================================================================== --- mvm/proc.c (revision 17835) +++ mvm/proc.c (revision 17836) @@ -1760,7 +1760,8 @@ rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0); rb_eSysStackError = rb_define_class("SystemStackError", rb_eException); - sysstack_error = rb_exc_new2(rb_eSysStackError, "stack level too deep"); + sysstack_error = rb_exc_new3(rb_eSysStackError, + rb_obj_freeze(rb_str_new2("stack level too deep"))); OBJ_TAINT(sysstack_error); OBJ_FREEZE(sysstack_error); Index: mvm/sprintf.c =================================================================== --- mvm/sprintf.c (revision 17835) +++ mvm/sprintf.c (revision 17836) @@ -17,6 +17,10 @@ #include <math.h> #include <stdarg.h> +#ifdef HAVE_IEEEFP_H +#include <ieeefp.h> +#endif + #define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */ #define BITSPERDIG (SIZEOF_BDIGITS*CHAR_BIT) #define EXTENDSIGN(n, l) (((~0 << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0 << (n))) Index: mvm/eval.c =================================================================== --- mvm/eval.c (revision 17835) +++ mvm/eval.c (revision 17836) @@ -1223,7 +1223,8 @@ rb_define_virtual_variable("$SAFE", safe_getter, safe_setter); - exception_error = rb_exc_new2(rb_eFatal, "exception reentered"); + exception_error = rb_exc_new2(rb_eFatal, + rb_obj_freeze(rb_str_new2("exception reentered"))); rb_ivar_set(exception_error, idThrowState, INT2FIX(TAG_FATAL)); OBJ_TAINT(exception_error); OBJ_FREEZE(exception_error); Index: mvm/gc.c =================================================================== --- mvm/gc.c (revision 17835) +++ mvm/gc.c (revision 17836) @@ -129,10 +129,17 @@ #pragma pack(pop) #endif +enum slot_color { + WHITE = 0x00, /* garbage */ + BLACK = 0x01, /* used */ + GRAY = 0x02, /* not sweep */ +}; + struct heaps_slot { void *membase; RVALUE *slot; int limit; + enum slot_color color; }; #define HEAP_MIN_SLOTS 10000 @@ -162,6 +169,11 @@ RVALUE *freelist; RVALUE *range[2]; RVALUE *freed; + size_t live; + size_t dead; + size_t do_heap_free; + size_t sweep_index; + size_t sweep_increment; } heap; struct { int dont_gc; @@ -200,6 +212,11 @@ #define himem objspace->heap.range[1] #define heaps_inc objspace->heap.increment #define heaps_freed objspace->heap.freed +#define live objspace->heap.live +#define dead objspace->heap.dead +#define do_heap_free objspace->heap.do_heap_free +#define heaps_sweep_index objspace->heap.sweep_index +#define heaps_sweep_inc objspace->heap.sweep_increment #define dont_gc objspace->flags.dont_gc #define during_gc objspace->flags.during_gc #define finalizer_table objspace->final.table @@ -249,6 +266,7 @@ static void run_final(rb_objspace_t *objspace, VALUE obj); static int garbage_collect(rb_objspace_t *objspace); +static int garbage_collect_force(rb_objspace_t *objspace); void rb_global_variable(VALUE *var) @@ -325,11 +343,11 @@ if ((ruby_gc_stress && !ruby_disable_gc_stress) || (malloc_increase+size) > malloc_limit) { - garbage_collect(objspace); + garbage_collect_force(objspace); } RUBY_CRITICAL(mem = malloc(size)); if (!mem) { - if (garbage_collect(objspace)) { + if (garbage_collect_force(objspace)) { RUBY_CRITICAL(mem = malloc(size)); } if (!mem) { @@ -365,10 +383,9 @@ objspace->malloc_params.allocated_size -= size; ptr = (size_t *)ptr - 1; #endif - RUBY_CRITICAL(mem = realloc(ptr, size)); if (!mem) { - if (garbage_collect(objspace)) { + if (garbage_collect_force(objspace)) { RUBY_CRITICAL(mem = realloc(ptr, size)); } if (!mem) { @@ -559,6 +576,8 @@ heaps_length = next_heaps_length; } +#define RANY(o) ((RVALUE*)(o)) + static void assign_heap_slot(rb_objspace_t *objspace) { @@ -602,6 +621,7 @@ heaps[hi].membase = membase; heaps[hi].slot = p; heaps[hi].limit = objs; + heaps[hi].color = BLACK; pend = p + objs; if (lomem == 0 || lomem > p) lomem = p; if (himem < pend) himem = pend; @@ -613,6 +633,9 @@ freelist = p; p++; } + if (hi < heaps_sweep_index) { + heaps_sweep_index++; + } } static void @@ -655,15 +678,13 @@ return Qfalse; } -#define RANY(o) ((RVALUE*)(o)) - static VALUE rb_newobj_from_heap(rb_objspace_t *objspace) { VALUE obj; if ((ruby_gc_stress && !ruby_disable_gc_stress) || !freelist) { - if (!heaps_increment(objspace) && !garbage_collect(objspace)) { + if (!garbage_collect(objspace)) { rb_memerror(); } } @@ -702,6 +723,13 @@ } #endif +int +rb_during_gc(void) +{ + rb_objspace_t *objspace = &rb_objspace; + return during_gc; +} + VALUE rb_newobj(void) { @@ -1037,6 +1065,7 @@ if (obj->as.basic.flags == 0) return; /* free cell */ if (obj->as.basic.flags & FL_MARK) return; /* already marked */ obj->as.basic.flags |= FL_MARK; + live++; if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) { if (!mark_stack_overflow) { @@ -1072,6 +1101,7 @@ if (obj->as.basic.flags == 0) return; /* free cell */ if (obj->as.basic.flags & FL_MARK) return; /* already marked */ obj->as.basic.flags |= FL_MARK; + live++; marking: if (FL_TEST(obj, FL_EXIVAR)) { @@ -1331,139 +1361,133 @@ if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */ VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE)); p->as.free.flags = 0; - p->as.free.next = freelist; - freelist = p; } p = tmp; } } -static void -free_unused_heaps(rb_objspace_t *objspace) +void rb_gc_abort_threads(void); + +static int +slot_sweep(rb_objspace_t *objspace, struct heaps_slot *target) { - size_t i, j; - RVALUE *last = 0; + RVALUE *p, *pend, *free; + RVALUE *final; + int freed = 0; - for (i = j = 1; j < heaps_used; i++) { - if (heaps[i].limit == 0) { - if (!last) { - last = heaps[i].membase; + if (target->color == BLACK || target->color == WHITE) { + return Qfalse; + } + + final = deferred_final_list; + free = freelist; + p = target->slot; pend = p + target->limit; + while (p < pend) { + if (!(p->as.basic.flags & FL_MARK)) { + if (p->as.basic.flags) { + obj_free(objspace, (VALUE)p); } + if (need_call_final && FL_TEST(p, FL_FINALIZE)) { + p->as.free.flags = FL_MARK; /* remain marked */ + p->as.free.next = deferred_final_list; + deferred_final_list = p; + } else { - free(heaps[i].membase); + VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE)); + p->as.free.flags = 0; + p->as.free.next = freelist; + freelist = p; } - heaps_used--; + freed++; } + else if (RBASIC(p)->flags == FL_MARK) { + /* objects to be finalized */ + /* do nothing remain marked */ + } else { - if (i != j) { - heaps[j] = heaps[i]; - } - j++; + p->as.basic.flags &= ~FL_MARK; } + p++; } - if (last) { - if (last < heaps_freed) { - free(heaps_freed); - heaps_freed = last; + dead += freed; + if (freed == target->limit && dead > do_heap_free) { + RVALUE *pp; + + target->limit = 0; + target->color = WHITE; + for (pp = deferred_final_list; pp != final; pp = pp->as.free.next) { + pp->as.free.flags |= FL_SINGLETON; /* freeing page mark */ } - else { - free(last); - } + freelist = free; /* cancel this page from freelist */ } + else { + target->color = BLACK; + } + return Qtrue; } static void -gc_sweep(rb_objspace_t *objspace) +heap_sweep_increment(rb_objspace_t *objspace) { - RVALUE *p, *pend, *final_list; - size_t freed = 0; - size_t i; - size_t live = 0, free_min = 0, do_heap_free = 0; + int i = 0; - do_heap_free = (heaps_used * HEAP_OBJ_LIMIT) * 0.65; - free_min = (heaps_used * HEAP_OBJ_LIMIT) * 0.2; - if (free_min < FREE_MIN) { - do_heap_free = heaps_used * HEAP_OBJ_LIMIT; - free_min = FREE_MIN; + while (i < heaps_sweep_inc && heaps_sweep_index < heaps_used) { + if (slot_sweep(objspace, &heaps[heaps_sweep_index])) { + i++; + } + heaps_sweep_index++; } +} - freelist = 0; - final_list = deferred_final_list; - deferred_final_list = 0; - for (i = 0; i < heaps_used; i++) { - int n = 0; - RVALUE *free = freelist; - RVALUE *final = final_list; +static void +heap_sweep(rb_objspace_t *objspace) +{ + while (!freelist && heaps_sweep_index < heaps_used) { + slot_sweep(objspace, &heaps[heaps_sweep_index]); + heaps_sweep_index++; + } +} - p = heaps[i].slot; pend = p + heaps[i].limit; - while (p < pend) { - if (!(p->as.basic.flags & FL_MARK)) { - if (p->as.basic.flags) { - obj_free(objspace, (VALUE)p); - } - if (need_call_final && FL_TEST(p, FL_FINALIZE)) { - p->as.free.flags = FL_MARK; /* remain marked */ - p->as.free.next = final_list; - final_list = p; - } - else { - VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE)); - p->as.free.flags = 0; - p->as.free.next = freelist; - freelist = p; - } - n++; - } - else if (RBASIC(p)->flags == FL_MARK) { - /* objects to be finalized */ - /* do nothing remain marked */ - } - else { - RBASIC(p)->flags &= ~FL_MARK; - live++; - } - p++; - } - if (n == heaps[i].limit && freed > do_heap_free) { - RVALUE *pp; +#define GC_NOT_LAZY_SWEEP 0 - heaps[i].limit = 0; - for (pp = final_list; pp != final; pp = pp->as.free.next) { - p->as.free.flags |= FL_SINGLETON; /* freeing page mark */ - } - freelist = free; /* cancel this page from freelist */ - } - else { - freed += n; - } +#ifdef GC_NOT_LAZY_SWEEP +static void +heap_all_sweep(rb_objspace_t *objspace) +{ + while (heaps_sweep_index < heaps_used) { + slot_sweep(objspace, &heaps[heaps_sweep_index]); + heaps_sweep_index++; } - if (malloc_increase > malloc_limit) { - malloc_limit += (malloc_increase - malloc_limit) * (double)live / (live + freed); - if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; +} +#endif + +static int +gc_lazy_sweep(rb_objspace_t *objspace, rb_thread_t *th) +{ + + if (heaps_increment(objspace)) { + heap_sweep_increment(objspace); } - malloc_increase = 0; - if (freed < free_min) { - set_heaps_increment(objspace); - heaps_increment(objspace); + else { + heap_sweep(objspace); } - during_gc = 0; - /* clear finalization list */ - if (final_list) { - deferred_final_list = final_list; - return; +#ifdef GC_NOT_LAZY_SWEEP + if (GC_NOT_LAZY_SWEEP) heap_all_sweep(objspace); +#endif + + if (!freelist) { + return Qfalse; } - free_unused_heaps(objspace); + + return Qtrue; } void rb_gc_force_recycle(VALUE p) { - rb_objspace_t *objspace = &rb_objspace; VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE)); RANY(p)->as.free.flags = 0; - RANY(p)->as.free.next = freelist; - freelist = RANY(p); } static void @@ -1664,30 +1688,87 @@ void rb_gc_mark_encodings(void); -static int -garbage_collect(rb_objspace_t *objspace) +static void +gc_mark_all_clear(rb_objspace_t *objspace) { - struct gc_list *list; - rb_thread_t *th = GET_THREAD(); + RVALUE *last = 0; + size_t i, j; + + for (i = j = 0; j < heaps_used; i++) { + if (heaps[i].color == WHITE && !deferred_final_list) { + if (!last) { + last = heaps[i].membase; + } + else { + free(heaps[i].membase); + } + heaps_used--; + } + else { + if (heaps[i].color == GRAY) { + RVALUE *p, *pend; + p = heaps[i].slot; pend = p + heaps[i].limit; + while (p < pend) { + if (!(RBASIC(p)->flags & FL_MARK)) { + if (p->as.basic.flags && !FL_TEST(p, FL_FINALIZE)) { + obj_free(objspace, (VALUE)p); + VALGRIND_MAKE_MEM_UNDEFINED((void*)p, sizeof(RVALUE)); + p->as.free.flags = 0; + } + } + else if (RBASIC(p)->flags != FL_MARK) { + p->as.basic.flags &= ~FL_MARK; + } + p++; + } + } + else { + heaps[i].color = GRAY; + } + if (i != j) { + heaps[j] = heaps[i]; + } + j++; + } + } + if (last) { + if (last < heaps_freed) { + free(heaps_freed); + heaps_freed = last; + } + else { + free(last); + } + } +} - if (GC_NOTIFY) printf("start garbage_collect()\n"); +static void +set_lazy_sweep_params(rb_objspace_t *objspace) +{ + size_t free_min = 0; - if (!heaps) { - return Qfalse; + dead = 0; + heaps_sweep_index = 0; + heaps_sweep_inc = (heaps_used / 10) + 1; + do_heap_free = (heaps_used * HEAP_OBJ_LIMIT) * 0.65; + free_min = (heaps_used * HEAP_OBJ_LIMIT) * 0.2; + if (free_min < FREE_MIN) free_min = FREE_MIN; + if (free_min > (heaps_used * HEAP_OBJ_LIMIT - live)) { + set_heaps_increment(objspace); + heaps_sweep_inc = (heaps_used + heaps_sweep_inc) / heaps_sweep_inc + 1; } +} - if (dont_gc || during_gc) { - if (!freelist) { - if (!heaps_increment(objspace)) { - set_heaps_increment(objspace); - heaps_increment(objspace); - } - } - return Qtrue; - } - during_gc++; - objspace->count++; +static void +gc_marks(rb_objspace_t *objspace, rb_thread_t *th) +{ + struct gc_list *list; + live = 0; + freelist = 0; + + gc_mark_all_clear(objspace); + SET_STACK_END; init_mark_stack(objspace); @@ -1704,6 +1785,7 @@ rb_gc_mark_symbols(); rb_gc_mark_encodings(); + /* mark protected global variables */ for (list = global_List; list; list = list->next) { rb_gc_mark_maybe(*list->varptr); @@ -1729,9 +1811,51 @@ } } - gc_sweep(objspace); + set_lazy_sweep_params(objspace); +} +static int +garbage_collect_force(rb_objspace_t *objspace) +{ + if (malloc_increase > malloc_limit) { + malloc_limit += (malloc_increase - malloc_limit) * (double)live / (heaps_used * HEAP_OBJ_LIMIT); + if (malloc_limit < GC_MALLOC_LIMIT) malloc_limit = GC_MALLOC_LIMIT; + } + malloc_increase = 0; + gc_marks(objspace, GET_THREAD()); + return garbage_collect(objspace); +} + +static int +garbage_collect(rb_objspace_t *objspace) +{ + rb_thread_t *th = GET_THREAD(); + + if (GC_NOTIFY) printf("start garbage_collect()\n"); + + if (!heaps) { + return Qfalse; + } + + if (dont_gc || during_gc) { + if (!freelist) { + if (!heaps_increment(objspace)) { + set_heaps_increment(objspace); + heaps_increment(objspace); + } + } + return Qtrue; + } + during_gc++; + objspace->count++; + + while (!gc_lazy_sweep(objspace, th)) { + gc_marks(objspace, th); + } + if (GC_NOTIFY) printf("end garbage_collect()\n"); + during_gc = 0; + return Qtrue; } @@ -2031,7 +2155,6 @@ if (p) { finalize_list(objspace, p); } - free_unused_heaps(objspace); } void @@ -2103,8 +2226,8 @@ rb_gc(void) { rb_objspace_t *objspace = &rb_objspace; + gc_finalize_deferred(objspace); garbage_collect(objspace); - gc_finalize_deferred(objspace); } /* @@ -2412,7 +2535,8 @@ rb_define_module_function(rb_mObSpace, "_id2ref", id2ref, 1); - nomem_error = rb_exc_new2(rb_eNoMemError, "failed to allocate memory"); + nomem_error = rb_exc_new3(rb_eNoMemError, + rb_obj_freeze(rb_str_new2("failed to allocate memory"))); OBJ_TAINT(nomem_error); OBJ_FREEZE(nomem_error); Index: mvm/regint.h =================================================================== --- mvm/regint.h (revision 17835) +++ mvm/regint.h (revision 17836) @@ -262,13 +262,13 @@ #define GET_ALIGNMENT_PAD_SIZE(addr,pad_size) do {\ (pad_size) = WORD_ALIGNMENT_SIZE \ - - ((unsigned int )(addr) % WORD_ALIGNMENT_SIZE);\ + - ((uintptr_t )(addr) % WORD_ALIGNMENT_SIZE);\ if ((pad_size) == WORD_ALIGNMENT_SIZE) (pad_size) = 0;\ } while (0) #define ALIGNMENT_RIGHT(addr) do {\ (addr) += (WORD_ALIGNMENT_SIZE - 1);\ - (addr) -= ((unsigned int )(addr) % WORD_ALIGNMENT_SIZE);\ + (addr) -= ((uintptr_t )(addr) % WORD_ALIGNMENT_SIZE);\ } while (0) #endif /* PLATFORM_UNALIGNED_WORD_ACCESS */ Index: mvm/Makefile.in =================================================================== --- mvm/Makefile.in (revision 17835) +++ mvm/Makefile.in (revision 17836) @@ -86,6 +86,7 @@ ARCHFILE = @ARCHFILE@ SETUP = EXTSTATIC = @EXTSTATIC@ +SET_LC_MESSAGES = env LC_MESSAGES=C CP = cp MV = mv Index: mvm/ext/bigdecimal/bigdecimal.c =================================================================== --- mvm/ext/bigdecimal/bigdecimal.c (revision 17835) +++ mvm/ext/bigdecimal/bigdecimal.c (revision 17836) @@ -22,6 +22,10 @@ #include <float.h> #include <math.h> #include "math.h" + +#ifdef HAVE_IEEEFP_H +#include <ieeefp.h> +#endif /* #define ENABLE_NUMERIC_STRING */ Index: mvm/ext/win32ole/win32ole.c =================================================================== --- mvm/ext/win32ole/win32ole.c (revision 17835) +++ mvm/ext/win32ole/win32ole.c (revision 17836) @@ -31,6 +31,7 @@ #include <varargs.h> #define va_init_list(a,b) va_start(a) #endif +#include <objidl.h> #define DOUT fprintf(stderr,"[%d]\n",__LINE__) #define DOUTS(x) fprintf(stderr,"[%d]:" #x "=%s\n",__LINE__,x) @@ -116,7 +117,7 @@ #define WC2VSTR(x) ole_wc2vstr((x), TRUE) -#define WIN32OLE_VERSION "1.1.7" +#define WIN32OLE_VERSION "1.1.8" typedef HRESULT (STDAPICALLTYPE FNCOCREATEINSTANCEEX) (REFCLSID, IUnknown*, DWORD, COSERVERINFO*, DWORD, MULTI_QI*); @@ -202,6 +203,9 @@ static char g_lcid_to_check[8 + 1]; static VARTYPE g_nil_to = VT_ERROR; static st_table *enc2cp_table; +static IMessageFilterVtbl message_filter; +static IMessageFilter imessage_filter = { &message_filter }; +static IMessageFilter* previous_filter; struct oledata { IDispatch *pDispatch; @@ -523,6 +527,101 @@ static void init_enc2cp(); static void free_enc2cp(); +static HRESULT (STDMETHODCALLTYPE mf_QueryInterface)( + IMessageFilter __RPC_FAR * This, + /* [in] */ REFIID riid, + /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject) +{ + if (MEMCMP(riid, &IID_IUnknown, GUID, 1) == 0 + || MEMCMP(riid, &IID_IMessageFilter, GUID, 1) == 0) + { + *ppvObject = &message_filter; + return S_OK; + } + return E_NOINTERFACE; +} + +static ULONG (STDMETHODCALLTYPE mf_AddRef)( + IMessageFilter __RPC_FAR * This) +{ + return 1; +} + +static ULONG (STDMETHODCALLTYPE mf_Release)( + IMessageFilter __RPC_FAR * This) +{ + return 1; +} + +static DWORD (STDMETHODCALLTYPE mf_HandleInComingCall)( + IMessageFilter __RPC_FAR * pThis, + DWORD dwCallType, //Type of incoming call + HTASK threadIDCaller, //Task handle calling this task + DWORD dwTickCount, //Elapsed tick count + LPINTERFACEINFO lpInterfaceInfo //Pointer to INTERFACEINFO structure + ) +{ +#ifdef DEBUG_MESSAGEFILTER + printf("incoming %08X, %08X, %d\n", dwCallType, threadIDCaller, dwTickCount); + fflush(stdout); +#endif + switch (dwCallType) + { + case CALLTYPE_ASYNC: + case CALLTYPE_TOPLEVEL_CALLPENDING: + case CALLTYPE_ASYNC_CALLPENDING: + if (rb_during_gc()) { + return SERVERCALL_RETRYLATER; + } + break; + default: + break; + } + if (previous_filter) { + return previous_filter->lpVtbl->HandleInComingCall(previous_filter, + dwCallType, + threadIDCaller, + dwTickCount, + lpInterfaceInfo); + } + return SERVERCALL_ISHANDLED; +} + +static DWORD (STDMETHODCALLTYPE mf_RetryRejectedCall)( + IMessageFilter* pThis, + HTASK threadIDCallee, //Server task handle + DWORD dwTickCount, //Elapsed tick count + DWORD dwRejectType //Returned rejection message + ) +{ + if (previous_filter) { + return previous_filter->lpVtbl->RetryRejectedCall(previous_filter, + threadIDCallee, + dwTickCount, + dwRejectType); + } + return 1000; +} + +static DWORD (STDMETHODCALLTYPE mf_MessagePending)( + IMessageFilter* pThis, + HTASK threadIDCallee, //Called applications task handle + DWORD dwTickCount, //Elapsed tick count + DWORD dwPendingType //Call type + ) +{ + if (rb_during_gc()) { + return PENDINGMSG_WAITNOPROCESS; + } + if (previous_filter) { + return previous_filter->lpVtbl->MessagePending(previous_filter, + threadIDCallee, + dwTickCount, + dwPendingType); + } + return PENDINGMSG_WAITNOPROCESS; +} + typedef struct _Win32OLEIDispatch { IDispatch dispatch; @@ -1059,6 +1158,11 @@ /* atexit((void (*)(void))ole_uninitialize); */ + hr = CoRegisterMessageFilter(&imessage_filter, &previous_filter); + if(FAILED(hr)) { + previous_filter = NULL; + ole_raise(hr, rb_eRuntimeError, "fail: install OLE MessageFilter"); + } } } @@ -8168,7 +8272,16 @@ com_vtbl.GetTypeInfo = GetTypeInfo; com_vtbl.GetIDsOfNames = GetIDsOfNames; com_vtbl.Invoke = Invoke; + + message_filter.QueryInterface = mf_QueryInterface; + message_filter.AddRef = mf_AddRef; + message_filter.Release = mf_Release; + message_filter.HandleInComingCall = mf_HandleInComingCall; + message_filter.RetryRejectedCall = mf_RetryRejectedCall; + message_filter.MessagePending = mf_MessagePending; + com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable()); + com_hash = Data_Wrap_Struct(rb_cData, rb_mark_hash, st_free_table, st_init_numtable()); rb_register_mark_object(com_hash); cWIN32OLE = rb_define_class("WIN32OLE", rb_cObject); Index: mvm/ext/json/ext/generator/generator.c =================================================================== --- mvm/ext/json/ext/generator/generator.c (revision 17835) +++ mvm/ext/json/ext/generator/generator.c (revision 17836) @@ -6,6 +6,10 @@ #include <string.h> #include <math.h> +#ifdef HAVE_IEEEFP_H +#include <ieeefp.h> +#endif + #define check_max_nesting(state, depth) do { \ long current_nesting = 1 + depth; \ if (state->max_nesting != 0 && current_nesting > state->max_nesting) \ Index: mvm/.merged-trunk-revision =================================================================== --- mvm/.merged-trunk-revision (revision 17835) +++ mvm/.merged-trunk-revision (revision 17836) @@ -1 +1 @@ -17785 +17835 Index: mvm/version.h =================================================================== --- mvm/version.h (revision 17835) +++ mvm/version.h (revision 17836) @@ -1,7 +1,7 @@ #define RUBY_VERSION "1.9.0" -#define RUBY_RELEASE_DATE "2008-07-02" +#define RUBY_RELEASE_DATE "2008-07-03" #define RUBY_VERSION_CODE 190 -#define RUBY_RELEASE_CODE 20080702 +#define RUBY_RELEASE_CODE 20080703 #define RUBY_PATCHLEVEL 0 #define RUBY_VERSION_MAJOR 1 @@ -9,7 +9,7 @@ #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_YEAR 2008 #define RUBY_RELEASE_MONTH 7 -#define RUBY_RELEASE_DAY 2 +#define RUBY_RELEASE_DAY 3 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[]; Index: mvm/test/ruby/test_settracefunc.rb =================================================================== --- mvm/test/ruby/test_settracefunc.rb (revision 17835) +++ mvm/test/ruby/test_settracefunc.rb (revision 17836) @@ -54,10 +54,14 @@ events.shift) assert_equal(["line", 4, __method__, self.class], events.shift) + assert_equal(["c-call", 4, :core_define_method, RubyVM::FrozenCore], + events.shift) assert_equal(["c-call", 4, :method_added, Module], events.shift) assert_equal(["c-return", 4, :method_added, Module], events.shift) + assert_equal(["c-return", 4, :core_define_method, RubyVM::FrozenCore], + events.shift) assert_equal(["line", 7, __method__, self.class], events.shift) assert_equal(["call", 6, :add, self.class], @@ -102,10 +106,14 @@ events.shift) assert_equal(["line", 5, nil, nil], events.shift) + assert_equal(["c-call", 5, :core_define_method, RubyVM::FrozenCore], + events.shift) assert_equal(["c-call", 5, :method_added, Module], events.shift) assert_equal(["c-return", 5, :method_added, Module], events.shift) + assert_equal(["c-return", 5, :core_define_method, RubyVM::FrozenCore], + events.shift) assert_equal(["end", 7, nil, nil], events.shift) assert_equal(["line", 8, __method__, self.class], @@ -145,34 +153,36 @@ events.shift) assert_equal(["line", 4, __method__, self.class], events.shift) - assert_equal(["c-call", 4, :raise, Kernel], + assert_equal(["line", 5, __method__, self.class], events.shift) - assert_equal(["c-call", 4, :new, Class], + assert_equal(["c-call", 5, :raise, Kernel], events.shift) - assert_equal(["c-call", 4, :initialize, Exception], + assert_equal(["c-call", 5, :exception, Exception], events.shift) - assert_equal(["c-return", 4, :initialize, Exception], + assert_equal(["c-call", 5, :initialize, Exception], events.shift) - assert_equal(["c-return", 4, :new, Class], + assert_equal(["c-return", 5, :initialize, Exception], events.shift) - assert_equal(["c-call", 4, :backtrace, Exception], + assert_equal(["c-return", 5, :exception, Exception], events.shift) - assert_equal(["c-return", 4, :backtrace, Exception], + assert_equal(["c-call", 5, :backtrace, Exception], events.shift) - assert_equal(["c-call", 4, :set_backtrace, Exception], + assert_equal(["c-return", 5, :backtrace, Exception], events.shift) - assert_equal(["c-return", 4, :set_backtrace, Exception], + assert_equal(["c-call", 5, :set_backtrace, Exception], events.shift) - assert_equal(["raise", 4, :test_raise, TestSetTraceFunc], + assert_equal(["c-return", 5, :set_backtrace, Exception], events.shift) - assert_equal(["c-call", 4, :===, Module], + assert_equal(["raise", 5, :test_raise, TestSetTraceFunc], events.shift) - assert_equal(["c-return", 4, :===, Module], + assert_equal(["c-call", 6, :===, Module], events.shift) - assert_equal(["line", 5, __method__, self.class], + assert_equal(["c-return", 6, :===, Module], events.shift) - assert_equal(["c-call", 5, :set_trace_func, Kernel], + assert_equal(["line", 8, __method__, self.class], events.shift) + assert_equal(["c-call", 8, :set_trace_func, Kernel], + events.shift) assert_equal([], events) end Index: mvm/test/win32ole/test_win32ole_event.rb =================================================================== --- mvm/test/win32ole/test_win32ole_event.rb (revision 17835) +++ mvm/test/win32ole/test_win32ole_event.rb (revision 17836) @@ -35,6 +35,8 @@ ev.on_event {|*args| default_handler(*args)} @ie.navigate("file:///#{@f}") while @ie.busy + WIN32OLE_EVENT.new(@ie, 'DWebBrowserEvents') + GC.start sleep 0.1 end assert_match(/BeforeNavigate/, @event) Index: mvm/rational.c =================================================================== --- mvm/rational.c (revision 17835) +++ mvm/rational.c (revision 17836) @@ -12,6 +12,10 @@ #define NDEBUG #include <assert.h> +#ifdef HAVE_IEEEFP_H +#include <ieeefp.h> +#endif + #ifndef RATIONAL_NAME #define RATIONAL_NAME "Rational" #endif Index: mvm/missing/tgamma.c =================================================================== --- mvm/missing/tgamma.c (revision 17835) +++ mvm/missing/tgamma.c (revision 17836) @@ -24,7 +24,6 @@ return 1/x < 0 ? -HUGE_VAL : HUGE_VAL; } if (x < 0) { - int sign; static double zero = 0.0; double i, f; f = modf(-x, &i); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/