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/