[前][次][番号順一覧][スレッド一覧][生データ]

yarv-diff:308

From: ko1 atdot.net
Date: 22 Feb 2006 20:45:11 -0000
Subject: [yarv-diff:308] r473 - branches/multivm

Author: ko1
Date: 2006-02-23 05:45:10 +0900 (Thu, 23 Feb 2006)
New Revision: 473

Added:
   branches/multivm/multivm.c
   branches/multivm/test.rb
Modified:
   branches/multivm/array.c
   branches/multivm/bignum.c
   branches/multivm/class.c
   branches/multivm/common.mk
   branches/multivm/compar.c
   branches/multivm/dir.c
   branches/multivm/enum.c
   branches/multivm/error.c
   branches/multivm/eval.c
   branches/multivm/eval_method.h
   branches/multivm/eval_thread.c
   branches/multivm/file.c
   branches/multivm/gc.c
   branches/multivm/hash.c
   branches/multivm/inits.c
   branches/multivm/io.c
   branches/multivm/math.c
   branches/multivm/numeric.c
   branches/multivm/object.c
   branches/multivm/prec.c
   branches/multivm/process.c
   branches/multivm/range.c
   branches/multivm/re.c
   branches/multivm/ruby.c
   branches/multivm/ruby.h
   branches/multivm/string.c
   branches/multivm/struct.c
   branches/multivm/thread.c
   branches/multivm/time.c
   branches/multivm/variable.c
   branches/multivm/vm.c
   branches/multivm/yarv.h
   branches/multivm/yarvcore.c
   branches/multivm/yarvcore.h
Log:
Support Multi-VM instance


Modified: branches/multivm/array.c
===================================================================
--- branches/multivm/array.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/array.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -17,7 +17,9 @@
 #include "st.h"
 #include "node.h"
 
+#if !YARV_MULTI_VM
 VALUE rb_cArray, rb_cValues;
+#endif
 
 static ID id_cmp;
 

Modified: branches/multivm/bignum.c
===================================================================
--- branches/multivm/bignum.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/bignum.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -18,7 +18,9 @@
 #include <ieeefp.h>
 #endif
 
+#if !YARV_MULTI_VM
 VALUE rb_cBignum;
+#endif
 
 #if defined __MINGW32__
 #define USHORT _USHORT

Modified: branches/multivm/class.c
===================================================================
--- branches/multivm/class.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/class.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -16,8 +16,6 @@
 #include "st.h"
 #include <ctype.h>
 
-extern st_table *rb_class_tbl;
-
 VALUE
 rb_class_boot(VALUE super)
 {

Modified: branches/multivm/common.mk
===================================================================
--- branches/multivm/common.mk	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/common.mk	2006-02-22 20:45:10 UTC (rev 473)
@@ -68,6 +68,7 @@
 		vm_dump.$(OBJEXT) \
 		yarvcore.$(OBJEXT) \
 		thread.$(OBJEXT) \
+		multivm.$(OBJEXT) \
 		$(MISSING)
 
 SCRIPT_ARGS   =	--dest-dir="$(DESTDIR)" \
@@ -376,6 +377,8 @@
 vm_dump.$(OBJEXT): {$(VPATH)}yarvcore.h {$(VPATH)}vm.h
 yarvcore.$(OBJEXT): {$(VPATH)}yarvcore.c {$(VPATH)}yarvcore.h \
         {$(VPATH)}yarv_version.h {$(VPATH)}debug.h rev.inc
+multivm.$(OBJEXT): {$(VPATH)}multivm.c {$(VPATH)}yarvcore.h {$(VPATH)}ruby.h \
+        {$(VPATH)}debug.h rev.inc {$(VPATH)}yarv.h {$(VPATH)}eval_intern.h
 debug.$(OBJEXT): {$(VPATH)}debug.h
 blockinlining.$(OBJEXT): {$(VPATH)}yarv.h {$(VPATH)}yarvcore.h vm_opts.h
 

Modified: branches/multivm/compar.c
===================================================================
--- branches/multivm/compar.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/compar.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -12,7 +12,9 @@
 
 #include "ruby.h"
 
+#if !YARV_MULTI_VM
 VALUE rb_mComparable;
+#endif
 
 static ID cmp;
 

Modified: branches/multivm/dir.c
===================================================================
--- branches/multivm/dir.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/dir.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -347,7 +347,9 @@
 	return fnmatch_helper(&p, &s, flags);
 }
 
+#if !YARV_MULTI_VM
 VALUE rb_cDir;
+#endif
 
 struct dir_data {
     DIR *dir;

Modified: branches/multivm/enum.c
===================================================================
--- branches/multivm/enum.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/enum.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -14,7 +14,10 @@
 #include "node.h"
 #include "util.h"
 
+#if !YARV_MULTI_VM
 VALUE rb_mEnumerable;
+#endif
+
 static ID id_each, id_eqq, id_cmp;
 
 static VALUE

Modified: branches/multivm/error.c
===================================================================
--- branches/multivm/error.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/error.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -240,6 +240,7 @@
 /* exception classes */
 #include <errno.h>
 
+#if !YARV_MULTI_VM
 VALUE rb_eException;
 VALUE rb_eSystemExit;
 VALUE rb_eInterrupt;
@@ -257,7 +258,6 @@
 VALUE rb_eSecurityError;
 VALUE rb_eNotImpError;
 VALUE rb_eNoMemError;
-static VALUE rb_cNameErrorMesg;
 
 VALUE rb_eScriptError;
 VALUE rb_eSyntaxError;
@@ -265,7 +265,10 @@
 
 VALUE rb_eSystemCallError;
 VALUE rb_mErrno;
+#endif
+
 static VALUE eNOERROR;
+static VALUE rb_cNameErrorMesg;
 
 VALUE
 rb_exc_new(VALUE etype, const char *ptr, long len)

Modified: branches/multivm/eval.c
===================================================================
--- branches/multivm/eval.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/eval.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -14,8 +14,10 @@
 
 #include "eval_intern.h"
 
+#if !YARV_MULTI_VM
 VALUE rb_cProc;
 VALUE rb_cBinding;
+#endif
 
 VALUE proc_invoke(VALUE, VALUE, VALUE, VALUE);
 VALUE rb_f_binding(VALUE);

Modified: branches/multivm/eval_method.h
===================================================================
--- branches/multivm/eval_method.h	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/eval_method.h	2006-02-22 20:45:10 UTC (rev 473)
@@ -2,10 +2,11 @@
  * This file is included by eval.c
  */
 
-#define CACHE_SIZE 0x800
 #define CACHE_MASK 0x7ff
 #define EXPR1(c,m) ((((c)>>3)^(m))&CACHE_MASK)
 
+#if !YARV_MULTI_VM
+
 struct cache_entry {		/* method hash table. */
     ID mid;			/* method's id */
     ID mid0;			/* method's original id */
@@ -15,7 +16,12 @@
 
 static struct cache_entry cache[CACHE_SIZE];
 static int ruby_running = 0;
+#else
+#define cache        YARV_VM_VALUE(cache)
+#define ruby_running YARV_VM_VALUE(ruby_running)
 
+#endif
+
 void
 rb_clear_cache()
 {

Modified: branches/multivm/eval_thread.c
===================================================================
--- branches/multivm/eval_thread.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/eval_thread.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -81,7 +81,9 @@
 
 int rb_thread_pending = 0;
 
+#if !YARV_MULTI_VM
 VALUE rb_cThread;
+#endif
 
 extern VALUE rb_last_status;
 

Modified: branches/multivm/file.c
===================================================================
--- branches/multivm/file.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/file.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -99,8 +99,11 @@
 #define fchown be_fchown
 #endif /* __BEOS__ */
 
+#if !YARV_MULTI_VM
 VALUE rb_cFile;
 VALUE rb_mFileTest;
+#endif
+
 static VALUE rb_cStat;
 
 VALUE

Modified: branches/multivm/gc.c
===================================================================
--- branches/multivm/gc.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/gc.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -69,19 +69,10 @@
 #endif
 #endif
 
-static unsigned long malloc_increase = 0;
-static unsigned long malloc_limit = GC_MALLOC_LIMIT;
-static VALUE nomem_error;
-
-static int dont_gc;
-static int during_gc;
-static int need_call_final = 0;
-static st_table *finalizer_table = 0;
-
 #define MARK_STACK_MAX 1024
-static VALUE mark_stack[MARK_STACK_MAX];
-static VALUE *mark_stack_ptr;
-static int mark_stack_overflow;
+#define HEAPS_INCREMENT 10
+#define HEAP_MIN_SLOTS 10000
+#define FREE_MIN  4096
 
 #undef GC_DEBUG
 
@@ -112,9 +103,67 @@
 #endif
 } RVALUE;
 
+#if YARV_MULTIVM
+/***********************************************************/
+struct gc_management_struct {
+    RVALUE *freelist;
+    RVALUE *deferred_final_list;
+
+    VALUE mark_stack[MARK_STACK_MAX];
+    VALUE *mark_stack_ptr;
+    int mark_stack_overflow;
+    unsigned long malloc_increase;
+    unsigned long malloc_limit;
+    VALUE nomem_error;
+    int dont_gc;
+    int during_gc;
+    int need_call_final;
+    st_table *finalizer_table;
+
+    struct heaps_slot {
+	RVALUE *slot;
+	int limit;
+    } *heaps;
+    
+    int heaps_length;
+    int heaps_used;
+    int heap_slots;
+    RVALUE *himem, *lomem;
+};
+
+struct gc_management_struct *
+ruby_allocate_gc_management_block(void)
+{
+    struct gc_management_struct *gcm = malloc(sizeof(struct gc_management_struct));
+    MEMZERO(gcm, struct gc_management_struct, 1);
+    gcm->malloc_limit = GC_MALLOC_LIMIT;
+    gcm->heap_slots = HEAP_MIN_SLOTS;
+    return gcm;
+}
+
+#define GCMT(th, v) th->vm->gcm->v
+#define GCM(v) GCMT(GET_THREAD(), v)
+
+#else
+/***********************************************************/
+
 static RVALUE *freelist = 0;
 static RVALUE *deferred_final_list = 0;
 
+static unsigned long malloc_increase = 0;
+static unsigned long malloc_limit = GC_MALLOC_LIMIT;
+static VALUE nomem_error;
+
+static int dont_gc;
+static int during_gc;
+static int need_call_final = 0;
+static st_table *finalizer_table = 0;
+
+#define MARK_STACK_MAX 1024
+static VALUE mark_stack[MARK_STACK_MAX];
+static VALUE *mark_stack_ptr;
+static int mark_stack_overflow;
+
 #define HEAPS_INCREMENT 10
 static struct heaps_slot {
     RVALUE *slot;
@@ -122,21 +171,29 @@
 } *heaps;
 static int heaps_length = 0;
 static int heaps_used   = 0;
-
-#define HEAP_MIN_SLOTS 10000
 static int heap_slots = HEAP_MIN_SLOTS;
 
-#define FREE_MIN  4096
-
 static RVALUE *himem, *lomem;
 
-extern st_table *rb_class_tbl;
+#define GCMT(th, v) (v)
+#define GCM(v) (v)
+
+void *
+ruby_allocate_gc_management_block(void)
+{
+    return 0;
+}
+
+/***********************************************************/
+#endif
+
 VALUE *rb_gc_stack_start = 0;
+int gc_stress = 0;
+
 #ifdef __ia64
 VALUE *rb_gc_register_stack_start = 0;
 #endif
 
-int gc_stress = 0;
 
 
 #ifdef DJGPP
@@ -171,12 +228,12 @@
 rb_memerror(void)
 {
   static int recurse = 0;
-    if (!nomem_error || (recurse > 0 && rb_safe_level() < 4)) {
+    if (!GCM(nomem_error) || (recurse > 0 && rb_safe_level() < 4)) {
 	fprintf(stderr, "[FATAL] failed to allocate memory\n");
 	exit(1);
     }
     recurse++;
-    rb_exc_raise(nomem_error);
+    rb_exc_raise(GCM(nomem_error));
 }
 
 /*
@@ -221,9 +278,9 @@
 	rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
     }
     if (size == 0) size = 1;
-    malloc_increase += size;
+    GCM(malloc_increase) += size;
 
-    if (gc_stress || malloc_increase > malloc_limit) {
+    if (gc_stress || GCM(malloc_increase) > GCM(malloc_limit)) {
 	garbage_collect();
     }
     RUBY_CRITICAL(mem = malloc(size));
@@ -270,7 +327,7 @@
     }
     if (!ptr) return ruby_xmalloc(size);
     if (size == 0) size = 1;
-    malloc_increase += size;
+    GCM(malloc_increase) += size;
     if (gc_stress) garbage_collect();
     RUBY_CRITICAL(mem = realloc(ptr, size));
     if (!mem) {
@@ -319,9 +376,9 @@
 VALUE
 rb_gc_enable(void)
 {
-    int old = dont_gc;
+    int old = GCM(dont_gc);
 
-    dont_gc = Qfalse;
+    GCM(dont_gc) = Qfalse;
     return old;
 }
 
@@ -340,13 +397,15 @@
 VALUE
 rb_gc_disable(void)
 {
-    int old = dont_gc;
+    int old = GCM(dont_gc);
 
-    dont_gc = Qtrue;
+    GCM(dont_gc) = Qtrue;
     return old;
 }
 
+#if !YARV_MULTI_VM
 VALUE rb_mGC;
+#endif
 
 static struct gc_list {
     VALUE *varptr;
@@ -397,46 +456,47 @@
 {
     RVALUE *p, *pend;
 
-    if (heaps_used == heaps_length) {
+    if (GCM(heaps_used) == GCM(heaps_length)) {
 	/* Realloc heaps */
 	struct heaps_slot *p;
 	int length;
 
-	heaps_length += HEAPS_INCREMENT;
-	length = heaps_length*sizeof(struct heaps_slot);
+	GCM(heaps_length) += HEAPS_INCREMENT;
+	length = GCM(heaps_length)*sizeof(struct heaps_slot);
 	RUBY_CRITICAL(
-	    if (heaps_used > 0) {
-		p = (struct heaps_slot *)realloc(heaps, length);
-		if (p) heaps = p;
+	    if (GCM(heaps_used) > 0) {
+		p = (struct heaps_slot *)realloc(GCM(heaps), length);
+		if (p) GCM(heaps) = p;
 	    }
 	    else {
-		p = heaps = (struct heaps_slot *)malloc(length);
+		p = GCM(heaps) = (struct heaps_slot *)malloc(length);
 	    });
 	if (p == 0) rb_memerror();
     }
 
     for (;;) {
-	RUBY_CRITICAL(p = heaps[heaps_used].slot = (RVALUE*)malloc(sizeof(RVALUE)*heap_slots));
-	heaps[heaps_used].limit = heap_slots;
+	RUBY_CRITICAL(p = GCM(heaps)[GCM(heaps_used)].slot =
+		      (RVALUE*)malloc(sizeof(RVALUE)*GCM(heap_slots)));
+	GCM(heaps)[GCM(heaps_used)].limit = GCM(heap_slots);
 	if (p == 0) {
-	    if (heap_slots == HEAP_MIN_SLOTS) {
+	    if (GCM(heap_slots) == HEAP_MIN_SLOTS) {
 		rb_memerror();
 	    }
-	    heap_slots = HEAP_MIN_SLOTS;
+	    GCM(heap_slots) = HEAP_MIN_SLOTS;
 	    continue;
 	}
 	break;
     }
-    pend = p + heap_slots;
-    if (lomem == 0 || lomem > p) lomem = p;
-    if (himem < pend) himem = pend;
-    heaps_used++;
-    heap_slots *= 1.8;
+    pend = p + GCM(heap_slots);
+    if (GCM(lomem) == 0 || GCM(lomem) > p) GCM(lomem) = p;
+    if (GCM(himem) < pend) GCM(himem) = pend;
+    GCM(heaps_used)++;
+    GCM(heap_slots) *= 1.8;
 
     while (p < pend) {
 	p->as.free.flags = 0;
-	p->as.free.next = freelist;
-	freelist = p;
+	p->as.free.next = GCM(freelist);
+	GCM(freelist) = p;
 	p++;
     }
 }
@@ -447,11 +507,11 @@
 {
     VALUE obj;
 
-    if ((gc_stress || !freelist) && !garbage_collect())
+    if ((gc_stress || !GCM(freelist)) && !garbage_collect())
 	rb_memerror();
 
-    obj = (VALUE)freelist;
-    freelist = freelist->as.free.next;
+    obj = (VALUE)GCM(freelist);
+    GCM(freelist) = GCM(freelist)->as.free.next;
     MEMZERO((void*)obj, RVALUE, 1);
 #ifdef GC_DEBUG
     RANY(obj)->file = ruby_sourcefile;
@@ -536,11 +596,11 @@
 static void
 init_mark_stack(void)
 {
-    mark_stack_overflow = 0;
-    mark_stack_ptr = mark_stack;
+    GCM(mark_stack_overflow) = 0;
+    GCM(mark_stack_ptr) = GCM(mark_stack);
 }
 
-#define MARK_STACK_EMPTY (mark_stack_ptr == mark_stack)
+#define MARK_STACK_EMPTY (GCM(mark_stack_ptr) == GCM(mark_stack))
 
 static st_table *source_filenames;
 
@@ -591,8 +651,8 @@
     int i;
 
     init_mark_stack();
-    for (i = 0; i < heaps_used; i++) {
-	p = heaps[i].slot; pend = p + heaps[i].limit;
+    for (i = 0; i < GCM(heaps_used); i++) {
+	p = GCM(heaps)[i].slot; pend = p + GCM(heaps)[i].limit;
 	while (p < pend) {
 	    if ((p->as.basic.flags & FL_MARK) &&
 		(p->as.basic.flags != FL_MARK)) {
@@ -609,8 +669,8 @@
     VALUE tmp_arry[MARK_STACK_MAX];
     VALUE *p;
 
-    p = (mark_stack_ptr - mark_stack) + tmp_arry;
-    MEMCPY(tmp_arry, mark_stack, VALUE, MARK_STACK_MAX);
+    p = (GCM(mark_stack_ptr) - GCM(mark_stack)) + tmp_arry;
+    MEMCPY(tmp_arry, GCM(mark_stack), VALUE, MARK_STACK_MAX);
 
     init_mark_stack();
     while(p != tmp_arry){
@@ -626,12 +686,12 @@
     register RVALUE *heap_org;
     register long i;
 
-    if (p < lomem || p > himem) return Qfalse;
+    if (p < GCM(lomem) || p > GCM(himem)) return Qfalse;
 
     /* check if p looks like a pointer */
-    for (i=0; i < heaps_used; i++) {
-	heap_org = heaps[i].slot;
-	if (heap_org <= p && p < heap_org + heaps[i].limit &&
+    for (i=0; i < GCM(heaps_used); i++) {
+	heap_org = GCM(heaps)[i].slot;
+	if (heap_org <= p && p < heap_org + GCM(heaps)[i].limit &&
 	    ((((char*)p)-((char*)heap_org))%sizeof(RVALUE)) == 0)
 	    return Qtrue;
     }
@@ -723,13 +783,13 @@
     obj->as.basic.flags |= FL_MARK;
 
     if (lev > GC_LEVEL_MAX || (lev == 0 && ruby_stack_check())) {
-	if (!mark_stack_overflow) {
-	    if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {
-		*mark_stack_ptr = ptr;
-		mark_stack_ptr++;		
+	if (!GCM(mark_stack_overflow)) {
+	    if (GCM(mark_stack_ptr) - GCM(mark_stack) < MARK_STACK_MAX) {
+		*GCM(mark_stack_ptr) = ptr;
+		GCM(mark_stack_ptr)++;		
 	    }
 	    else {
-		mark_stack_overflow = 1;
+		GCM(mark_stack_overflow) = 1;
 	    }
 	}
 	return;
@@ -1001,8 +1061,8 @@
 	run_final((VALUE)p);
 	if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
 	    p->as.free.flags = 0;
-	    p->as.free.next = freelist;
-	    freelist = p;
+	    p->as.free.next = GCM(freelist);
+	    GCM(freelist) = p;
 	}
 	p = tmp;
     }
@@ -1013,14 +1073,14 @@
 {
     int i, j;
 
-    for (i = j = 1; j < heaps_used; i++) {
-	if (heaps[i].limit == 0) {
-	    free(heaps[i].slot);
-	    heaps_used--;
+    for (i = j = 1; j < GCM(heaps_used); i++) {
+	if (GCM(heaps)[i].limit == 0) {
+	    free(GCM(heaps)[i].slot);
+	    GCM(heaps_used)--;
 	}
 	else {
 	    if (i != j) {
-		heaps[j] = heaps[i];
+		GCM(heaps)[j] = GCM(heaps)[i];
 	    }
 	    j++;
 	}
@@ -1042,29 +1102,29 @@
         st_foreach(source_filenames, sweep_source_filename, 0);
     }
 
-    freelist = 0;
-    final_list = deferred_final_list;
-    deferred_final_list = 0;
-    for (i = 0; i < heaps_used; i++) {
+    GCM(freelist) = 0;
+    final_list = GCM(deferred_final_list);
+    GCM(deferred_final_list) = 0;
+    for (i = 0; i < GCM(heaps_used); i++) {
 	int n = 0;
-	RVALUE *free = freelist;
+	RVALUE *free = GCM(freelist);
 	RVALUE *final = final_list;
 
-	p = heaps[i].slot; pend = p + heaps[i].limit;
+	p = GCM(heaps)[i].slot; pend = p + GCM(heaps)[i].limit;
 	while (p < pend) {
 	    if (!(p->as.basic.flags & FL_MARK)) {
 		if (p->as.basic.flags) {
 		    obj_free((VALUE)p);
 		}
-		if (need_call_final && FL_TEST(p, FL_FINALIZE)) {
+		if (GCM(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 {
 		    p->as.free.flags = 0;
-		    p->as.free.next = freelist;
-		    freelist = p;
+		    p->as.free.next = GCM(freelist);
+		    GCM(freelist) = p;
 		}
 		n++;
 	    }
@@ -1078,32 +1138,33 @@
 	    }
 	    p++;
 	}
-	if (n == heaps[i].limit && freed > FREE_MIN) {
+	if (n == GCM(heaps)[i].limit && freed > FREE_MIN) {
 	    RVALUE *pp;
 
-	    heaps[i].limit = 0;
+	    GCM(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 */
+	    GCM(freelist) = free;	/* cancel this page from freelist */
 	}
 	else {
 	    freed += n;
 	}
     }
-    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;
+    if (GCM(malloc_increase) > GCM(malloc_limit)) {
+	GCM(malloc_limit) += (GCM(malloc_increase) - GCM(malloc_limit))
+	  * (double)live / (live + freed);
+	if (GCM(malloc_limit) < GC_MALLOC_LIMIT) GCM(malloc_limit) = GC_MALLOC_LIMIT;
     }
-    malloc_increase = 0;
+    GCM(malloc_increase) = 0;
     if (freed < FREE_MIN) {
 	add_heap();
     }
-    during_gc = 0;
+    GCM(during_gc) = 0;
 
     /* clear finalization list */
     if (final_list) {
-	deferred_final_list = final_list;
+	GCM(deferred_final_list) = final_list;
 	return;
     }
     free_unused_heaps();
@@ -1113,8 +1174,8 @@
 rb_gc_force_recycle(VALUE p)
 {
     RANY(p)->as.free.flags = 0;
-    RANY(p)->as.free.next = freelist;
-    freelist = RANY(p);
+    RANY(p)->as.free.next = GCM(freelist);
+    GCM(freelist) = RANY(p);
 }
 
 static void
@@ -1276,17 +1337,17 @@
     jmp_buf save_regs_gc_mark;
     yarv_thread_t *th = GET_THREAD();
 
-    if (!heaps) {
+    if (!GCM(heaps)) {
 	return Qfalse;
     }
 
-    if (dont_gc || during_gc) {
-	if (!freelist) {
+    if (GCM(dont_gc) || GCM(during_gc)) {
+	if (!GCM(freelist)) {
 	    add_heap();
 	}
 	return Qtrue;
     }
-    during_gc++;
+    GCM(during_gc)++;
 
     YARV_SET_STACK_END;
 
@@ -1294,8 +1355,8 @@
 
     rb_gc_mark(GET_THREAD()->vm->self);
 
-    if (finalizer_table) {
-	mark_tbl(finalizer_table, 0);
+    if (GCM(finalizer_table)) {
+	mark_tbl(GCM(finalizer_table), 0);
     }
 
     FLUSH_REGISTER_WINDOWS;
@@ -1361,7 +1422,7 @@
 
     /* gc_mark objects whose marking are not completed*/
     while (!MARK_STACK_EMPTY){
-	if (mark_stack_overflow){
+	if (GCM(mark_stack_overflow)){
 	    gc_mark_all();
 	}
 	else {
@@ -1564,10 +1625,10 @@
     int i;
     int n = 0;
 
-    for (i = 0; i < heaps_used; i++) {
+    for (i = 0; i < GCM(heaps_used); i++) {
 	RVALUE *p, *pend;
 
-	p = heaps[i].slot; pend = p + heaps[i].limit;
+	p = GCM(heaps)[i].slot; pend = p + GCM(heaps)[i].limit;
 	for (;p < pend; p++) {
 	    if (p->as.basic.flags) {
 		switch (TYPE(p)) {
@@ -1594,10 +1655,10 @@
     int i;
     int n = 0;
 
-    for (i = 0; i < heaps_used; i++) {
+    for (i = 0; i < GCM(heaps_used); i++) {
 	RVALUE *p, *pend;
 
-	p = heaps[i].slot; pend = p + heaps[i].limit;
+	p = GCM(heaps)[i].slot; pend = p + GCM(heaps)[i].limit;
 	for (;p < pend; p++) {
 	    if (p->as.basic.flags) {
 		switch (TYPE(p)) {
@@ -1713,7 +1774,7 @@
 call_final(VALUE os, VALUE obj)
 {
     rb_warn("ObjectSpace::call_finalizer is deprecated; use define_finalizer");
-    need_call_final = 1;
+    GCM(need_call_final) = 1;
     FL_SET(obj, FL_FINALIZE);
     return obj;
 }
@@ -1729,8 +1790,8 @@
 static VALUE
 undefine_final(VALUE os, VALUE obj)
 {
-    if (finalizer_table) {
-	st_delete(finalizer_table, (st_data_t*)&obj, 0);
+    if (GCM(finalizer_table)) {
+	st_delete(GCM(finalizer_table), (st_data_t*)&obj, 0);
     }
     return obj;
 }
@@ -1757,19 +1818,19 @@
 	rb_raise(rb_eArgError, "wrong type argument %s (should be callable)",
 		 rb_obj_classname(block));
     }
-    need_call_final = 1;
+    GCM(need_call_final) = 1;
     FL_SET(obj, FL_FINALIZE);
 
     block = rb_ary_new3(2, INT2FIX(rb_safe_level()), block);
 
-    if (!finalizer_table) {
-	finalizer_table = st_init_numtable();
+    if (!GCM(finalizer_table)) {
+	GCM(finalizer_table) = st_init_numtable();
     }
-    if (st_lookup(finalizer_table, obj, &table)) {
+    if (st_lookup(GCM(finalizer_table), obj, &table)) {
 	rb_ary_push(table, block);
     }
     else {
-	st_add_direct(finalizer_table, obj, rb_ary_new3(1, block));
+	st_add_direct(GCM(finalizer_table), obj, rb_ary_new3(1, block));
     }
     return block;
 }
@@ -1779,10 +1840,10 @@
 {
     VALUE table;
 
-    if (!finalizer_table) return;
+    if (!GCM(finalizer_table)) return;
     if (!FL_TEST(obj, FL_FINALIZE)) return;
-    if (st_lookup(finalizer_table, obj, &table)) {
-	st_insert(finalizer_table, dest, table);
+    if (st_lookup(GCM(finalizer_table), obj, &table)) {
+	st_insert(GCM(finalizer_table), dest, table);
     }
     FL_SET(dest, FL_FINALIZE);
 }
@@ -1810,7 +1871,7 @@
 	if (!args[1]) args[1] = rb_ary_new3(1, objid);
 	rb_protect((VALUE(*)(VALUE))run_single_final, (VALUE)args, &status);
     }
-    if (finalizer_table && st_delete(finalizer_table, (st_data_t*)&obj, &table)) {
+    if (GCM(finalizer_table) && st_delete(GCM(finalizer_table), (st_data_t*)&obj, &table)) {
 	for (i=0; i<RARRAY(table)->len; i++) {
 	    VALUE final = RARRAY(table)->ptr[i];
 	    args[0] = RARRAY(final)->ptr[1];
@@ -1825,15 +1886,15 @@
 void
 rb_gc_finalize_deferred(void)
 {
-    RVALUE *p = deferred_final_list;
+    RVALUE *p = GCM(deferred_final_list);
 
-    during_gc++;
-    deferred_final_list = 0;
+    GCM(during_gc)++;
+    GCM(deferred_final_list) = 0;
     if (p) {
 	finalize_list(p);
     }
     free_unused_heaps();
-    during_gc = 0;
+    GCM(during_gc) = 0;
 }
 
 void
@@ -1843,14 +1904,14 @@
     int i;
 
     /* finalizers are part of garbage collection */
-    during_gc++;
+    GCM(during_gc)++;
     /* run finalizers */
-    if (need_call_final) {
-	p = deferred_final_list;
-	deferred_final_list = 0;
+    if (GCM(need_call_final)) {
+	p = GCM(deferred_final_list);
+	GCM(deferred_final_list) = 0;
 	finalize_list(p);
-	for (i = 0; i < heaps_used; i++) {
-	    p = heaps[i].slot; pend = p + heaps[i].limit;
+	for (i = 0; i < GCM(heaps_used); i++) {
+	    p = GCM(heaps)[i].slot; pend = p + GCM(heaps)[i].limit;
 	    while (p < pend) {
 		if (FL_TEST(p, FL_FINALIZE)) {
 		    FL_UNSET(p, FL_FINALIZE);
@@ -1862,8 +1923,8 @@
 	}
     }
     /* run data object's finalizers */
-    for (i = 0; i < heaps_used; i++) {
-	p = heaps[i].slot; pend = p + heaps[i].limit;
+    for (i = 0; i < GCM(heaps_used); i++) {
+	p = GCM(heaps)[i].slot; pend = p + GCM(heaps)[i].limit;
 	while (p < pend) {
 	    if (BUILTIN_TYPE(p) == T_DATA &&
 		DATA_PTR(p) && RANY(p)->as.data.dfree &&
@@ -1884,7 +1945,7 @@
 	    p++;
 	}
     }
-    during_gc = 0;
+    GCM(during_gc) = 0;
 }
 
 /*
@@ -1972,6 +2033,6 @@
 
     source_filenames = st_init_strtable();
 
-    rb_global_variable(&nomem_error);
-    nomem_error = rb_exc_new2(rb_eNoMemError, "failed to allocate memory");
+    rb_global_variable(&GCM(nomem_error));
+    GCM(nomem_error) = rb_exc_new2(rb_eNoMemError, "failed to allocate memory");
 }

Modified: branches/multivm/hash.c
===================================================================
--- branches/multivm/hash.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/hash.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -30,7 +30,9 @@
     return rb_obj_freeze(hash);
 }
 
+#if !YARV_MULTI_VM
 VALUE rb_cHash;
+#endif
 
 static VALUE envtbl;
 static ID id_hash, id_call, id_default;

Modified: branches/multivm/inits.c
===================================================================
--- branches/multivm/inits.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/inits.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -48,12 +48,17 @@
 void Init_version _((void));
 void Init_yarvcore _((void));
 void Init_jump _((void));
+void Init_multivm _((void));
 
-
 void
 rb_call_inits()
 {
-    Init_sym();
+    static int first = 1;
+
+    if (first) {
+	first = 0;
+	Init_sym();
+    }
     Init_var_tables();
     Init_Object();
     Init_Comparable();
@@ -87,5 +92,6 @@
     Init_marshal();
     Init_Enumerator();
     Init_yarvcore();
+    Init_multivm();
     Init_version();
 }

Modified: branches/multivm/io.c
===================================================================
--- branches/multivm/io.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/io.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -105,12 +105,15 @@
 # endif
 #endif
 
+#if !YARV_MULTI_VM
 VALUE rb_cIO;
 VALUE rb_eEOFError;
 VALUE rb_eIOError;
 
 VALUE rb_stdin, rb_stdout, rb_stderr;
+#endif
 VALUE rb_deferr;		/* rescue VIM plugin */
+
 static VALUE orig_stdout, orig_stderr;
 
 VALUE rb_output_fs;

Modified: branches/multivm/math.c
===================================================================
--- branches/multivm/math.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/math.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -14,7 +14,9 @@
 #include <math.h>
 #include <errno.h>
 
+#if !YARV_MULTI_VM
 VALUE rb_mMath;
+#endif
 
 #define Need_Float(x) (x) = rb_Float(x)
 #define Need_Float2(x,y) do {\

Added: branches/multivm/multivm.c
===================================================================
--- branches/multivm/multivm.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/multivm.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -0,0 +1,43 @@
+
+
+#include "ruby.h"
+#include "node.h"
+#include "yarvcore.h"
+#include "yarv.h"
+#include "eval_intern.h"
+
+
+static void
+yarv_create_and_launch_vm(yarv_vm_t *parent_vm, VALUE script)
+{
+    int state;
+    
+    // bootstrap
+    Init_yarv();
+    Init_heap();
+    Init_stack((void *)&state);
+    Init_heap();
+    rb_call_inits();
+
+    // dispatch on another thread
+
+    yarvcore_eval(Qnil, script, rb_str_new2("AnotherVM"), 1);
+    native_mutex_unlock(&GET_THREAD()->vm->global_interpreter_lock);
+    
+    // restore to the parent vm
+    theYarvVM = parent_vm;
+    yarv_set_current_running_thread_raw(parent_vm->running_thread);
+}
+
+VALUE
+multivm_create(VALUE self, VALUE script)
+{
+    yarv_create_and_launch_vm(GET_THREAD()->vm, script);
+    return self;
+}
+
+void
+Init_multivm()
+{
+    rb_define_global_function("create_vm", multivm_create, 1);
+}

Modified: branches/multivm/numeric.c
===================================================================
--- branches/multivm/numeric.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/numeric.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -64,6 +64,7 @@
 
 static ID id_coerce, id_to_i, id_eq;
 
+#if !YARV_MULTI_VM
 VALUE rb_cNumeric;
 VALUE rb_cFloat;
 VALUE rb_cInteger;
@@ -71,6 +72,7 @@
 
 VALUE rb_eZeroDivError;
 VALUE rb_eFloatDomainError;
+#endif
 
 void
 rb_num_zerodiv(void)

Modified: branches/multivm/object.c
===================================================================
--- branches/multivm/object.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/object.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -20,6 +20,7 @@
 #include <ctype.h>
 #include <math.h>
 
+#if !YARV_MULTI_VM
 VALUE rb_mKernel;
 VALUE rb_cObject;
 VALUE rb_cModule;
@@ -30,6 +31,7 @@
 VALUE rb_cTrueClass;
 VALUE rb_cFalseClass;
 VALUE rb_cSymbol;
+#endif
 
 static ID id_eq, id_eql, id_inspect, id_init_copy;
 
@@ -2335,10 +2337,13 @@
     return rb_Array(arg);
 }
 
+#if !YARV_MULTI_VM
+extern st_table *rb_class_tbl;
+#endif
+
 static VALUE
 boot_defclass(char *name, VALUE super)
 {
-    extern st_table *rb_class_tbl;
     VALUE obj = rb_class_boot(super);
     ID id = rb_intern(name);
 

Modified: branches/multivm/prec.c
===================================================================
--- branches/multivm/prec.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/prec.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -12,7 +12,9 @@
 
 #include "ruby.h"
 
+#if !YARV_MULTI_VM
 VALUE rb_mPrecision;
+#endif
 
 static ID prc_pr, prc_if;
 

Modified: branches/multivm/process.c
===================================================================
--- branches/multivm/process.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/process.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -3758,7 +3758,9 @@
 #endif
 }
 
+#if !YARV_MULTI_VM
 VALUE rb_mProcess;
+#endif
 VALUE rb_mProcUID;
 VALUE rb_mProcGID;
 VALUE rb_mProcID_Syscall;

Modified: branches/multivm/range.c
===================================================================
--- branches/multivm/range.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/range.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -12,7 +12,9 @@
 
 #include "ruby.h"
 
+#if !YARV_MULTI_VM
 VALUE rb_cRange;
+#endif
 static ID id_cmp, id_succ, id_beg, id_end, id_excl;
 
 #define EXCL(r) RTEST(rb_ivar_get((r), id_excl))

Modified: branches/multivm/re.c
===================================================================
--- branches/multivm/re.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/re.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -1339,7 +1339,9 @@
     return RMATCH(match)->str;	/* str is frozen */
 }
 
+#if !YARV_MULTI_VM
 VALUE rb_cRegexp;
+#endif
 
 static void
 rb_reg_initialize(VALUE obj, const char *s, long len, int options,	/* CASEFOLD  = 1 */

Modified: branches/multivm/ruby.c
===================================================================
--- branches/multivm/ruby.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/ruby.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -890,7 +890,6 @@
 static void
 load_file(const char *fname, int script)
 {
-    extern VALUE rb_stdin;
     VALUE parser;
     VALUE f;
     int line_start = 1;

Modified: branches/multivm/ruby.h
===================================================================
--- branches/multivm/ruby.h	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/ruby.h	2006-02-22 20:45:10 UTC (rev 473)
@@ -626,6 +626,80 @@
 void ruby_options(int, char**);
 NORETURN(void ruby_run(void));
 
+#define YARV_MULTI_VM 1
+
+#if YARV_MULTI_VM
+#include "node.h"
+#include "yarvcore.h"
+#include "yarv.h"
+
+#define YARV_VM_VALUE(v) (GET_THREAD()->vm->vm_value__##v)
+
+#define rb_mKernel           YARV_VM_VALUE(rb_mKernel)
+#define rb_mComparable       YARV_VM_VALUE(rb_mComparable)
+#define rb_mEnumerable       YARV_VM_VALUE(rb_mEnumerable)
+#define rb_mPrecision        YARV_VM_VALUE(rb_mPrecision)
+#define rb_mErrno            YARV_VM_VALUE(rb_mErrno)
+#define rb_mFileTest         YARV_VM_VALUE(rb_mFileTest)
+#define rb_mGC               YARV_VM_VALUE(rb_mGC)
+#define rb_mMath             YARV_VM_VALUE(rb_mMath)
+#define rb_mProcess          YARV_VM_VALUE(rb_mProcess)
+#define rb_cObject           YARV_VM_VALUE(rb_cObject)
+#define rb_cArray            YARV_VM_VALUE(rb_cArray)
+#define rb_cValues           YARV_VM_VALUE(rb_cValues)
+#define rb_cBignum           YARV_VM_VALUE(rb_cBignum)
+#define rb_cClass            YARV_VM_VALUE(rb_cClass)
+#define rb_cDir              YARV_VM_VALUE(rb_cDir)
+#define rb_cData             YARV_VM_VALUE(rb_cData)
+#define rb_cFalseClass       YARV_VM_VALUE(rb_cFalseClass)
+#define rb_cFile             YARV_VM_VALUE(rb_cFile)
+#define rb_cFixnum           YARV_VM_VALUE(rb_cFixnum)
+#define rb_cFloat            YARV_VM_VALUE(rb_cFloat)
+#define rb_cHash             YARV_VM_VALUE(rb_cHash)
+#define rb_cInteger          YARV_VM_VALUE(rb_cInteger)
+#define rb_cIO               YARV_VM_VALUE(rb_cIO)
+#define rb_cModule           YARV_VM_VALUE(rb_cModule)
+#define rb_cNilClass         YARV_VM_VALUE(rb_cNilClass)
+#define rb_cNumeric          YARV_VM_VALUE(rb_cNumeric)
+#define rb_cProc             YARV_VM_VALUE(rb_cProc)
+#define rb_cRange            YARV_VM_VALUE(rb_cRange)
+#define rb_cRegexp           YARV_VM_VALUE(rb_cRegexp)
+#define rb_cString           YARV_VM_VALUE(rb_cString)
+#define rb_cSymbol           YARV_VM_VALUE(rb_cSymbol)
+#define rb_cThread           YARV_VM_VALUE(rb_cThread)
+#define rb_cTime             YARV_VM_VALUE(rb_cTime)
+#define rb_cTrueClass        YARV_VM_VALUE(rb_cTrueClass)
+#define rb_cStruct           YARV_VM_VALUE(rb_cStruct)
+#define rb_eException        YARV_VM_VALUE(rb_eException)
+#define rb_eStandardError    YARV_VM_VALUE(rb_eStandardError)
+#define rb_eSystemExit       YARV_VM_VALUE(rb_eSystemExit)
+#define rb_eInterrupt        YARV_VM_VALUE(rb_eInterrupt)
+#define rb_eSignal           YARV_VM_VALUE(rb_eSignal)
+#define rb_eFatal            YARV_VM_VALUE(rb_eFatal)
+#define rb_eArgError         YARV_VM_VALUE(rb_eArgError)
+#define rb_eEOFError         YARV_VM_VALUE(rb_eEOFError)
+#define rb_eIndexError       YARV_VM_VALUE(rb_eIndexError)
+#define rb_eKeyError         YARV_VM_VALUE(rb_eKeyError)
+#define rb_eRangeError       YARV_VM_VALUE(rb_eRangeError)
+#define rb_eIOError          YARV_VM_VALUE(rb_eIOError)
+#define rb_eRuntimeError     YARV_VM_VALUE(rb_eRuntimeError)
+#define rb_eSecurityError    YARV_VM_VALUE(rb_eSecurityError)
+#define rb_eSystemCallError  YARV_VM_VALUE(rb_eSystemCallError)
+#define rb_eTypeError        YARV_VM_VALUE(rb_eTypeError)
+#define rb_eZeroDivError     YARV_VM_VALUE(rb_eZeroDivError)
+#define rb_eNotImpError      YARV_VM_VALUE(rb_eNotImpError)
+#define rb_eNoMemError       YARV_VM_VALUE(rb_eNoMemError)
+#define rb_eNoMethodError    YARV_VM_VALUE(rb_eNoMethodError)
+#define rb_eFloatDomainError YARV_VM_VALUE(rb_eFloatDomainError)
+#define rb_eScriptError      YARV_VM_VALUE(rb_eScriptError)
+#define rb_eNameError        YARV_VM_VALUE(rb_eNameError)
+#define rb_eSyntaxError      YARV_VM_VALUE(rb_eSyntaxError)
+#define rb_eLoadError        YARV_VM_VALUE(rb_eLoadError)
+#define rb_stdin             YARV_VM_VALUE(rb_stdin)
+#define rb_stdout            YARV_VM_VALUE(rb_stdout)
+#define rb_stderr            YARV_VM_VALUE(rb_stderr)
+#define rb_class_tbl         YARV_VM_VALUE(rb_class_tbl) 
+#else
 RUBY_EXTERN VALUE rb_mKernel;
 RUBY_EXTERN VALUE rb_mComparable;
 RUBY_EXTERN VALUE rb_mEnumerable;
@@ -691,6 +765,8 @@
 RUBY_EXTERN VALUE rb_eLoadError;
 
 RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr;
+extern st_table *rb_class_tbl;
+#endif
 
 static inline VALUE
 rb_class_of(VALUE obj)

Modified: branches/multivm/string.c
===================================================================
--- branches/multivm/string.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/string.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -25,7 +25,9 @@
 #include <unistd.h>
 #endif
 
+#if !YARV_MULTI_VM
 VALUE rb_cString;
+#endif
 
 #define STR_TMPLOCK FL_USER1
 #define STR_ASSOC   FL_USER3

Modified: branches/multivm/struct.c
===================================================================
--- branches/multivm/struct.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/struct.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -12,7 +12,9 @@
 
 #include "ruby.h"
 
+#if !YARV_MULTI_VM
 VALUE rb_cStruct;
+#endif
 
 static VALUE struct_alloc(VALUE);
 

Added: branches/multivm/test.rb
===================================================================
--- branches/multivm/test.rb	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/test.rb	2006-02-22 20:45:10 UTC (rev 473)
@@ -0,0 +1,17 @@
+Const = :Const
+$foo = :foo
+
+p Thread.current
+create_vm(%q{
+  p Thread.current
+  p defined?(Const)
+  p $foo
+  Thread.new{
+    30.times{|i|
+      p [i]
+      sleep 0.1
+    }
+  }
+})
+p Thread.current
+

Modified: branches/multivm/thread.c
===================================================================
--- branches/multivm/thread.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/thread.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -1580,8 +1580,7 @@
 static void
 timer_function(void)
 {
-    // TODO: GET_VM() should not be used
-    GET_THREAD()->vm->running_thread->interrupt_flag = 1;
+    theYarvVM->running_thread->interrupt_flag = 1;
 }
 
 /*

Modified: branches/multivm/time.c
===================================================================
--- branches/multivm/time.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/time.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -20,7 +20,9 @@
 
 #include <math.h>
 
+#if !YARV_MULTI_VM
 VALUE rb_cTime;
+#endif
 
 struct time_object {
     struct timeval tv;

Modified: branches/multivm/variable.c
===================================================================
--- branches/multivm/variable.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/variable.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -18,10 +18,16 @@
 #include "util.h"
 
 void rb_vm_change_state(void);
-static st_table *rb_global_tbl;
-st_table *rb_class_tbl;
 static ID autoload, classpath, tmp_classpath;
 
+#if !YARV_MULTI_VM
+st_table *rb_global_tbl;
+st_table *rb_class_tbl;
+#else
+#define rb_global_tbl YARV_VM_VALUE(rb_global_tbl)
+#define rb_class_tbl  YARV_VM_VALUE(rb_class_tbl) 
+#endif
+
 void
 Init_var_tables(void)
 {
@@ -299,10 +305,12 @@
     struct trace_var *trace;
 };
 
+#if !YARV_MULTI_VM
 struct global_entry {
     struct global_variable *var;
     ID id;
 };
+#endif
 
 static VALUE undef_getter(ID id);
 static void  undef_setter(VALUE val, ID id, void *data, struct global_variable *var);

Modified: branches/multivm/vm.c
===================================================================
--- branches/multivm/vm.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/vm.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -43,26 +43,6 @@
 static VALUE yarv_finish_insn_seq[1] = { BIN(finish) };
 #endif
 
-/* imporeted from eval.c */
-struct cache_entry {		/* method hash table. */
-    ID mid;			/* method's id */
-    ID mid0;			/* method's original id */
-    VALUE klass;		/* receiver's class */
-    VALUE origin;		/* where method defined  */
-    NODE *method;
-    int noex;
-};
-
-#define CACHE_SIZE 0x800
-
-//RUBY_EXTERN struct cache_entry ruby_cache_table[CACHE_SIZE];
-//static struct cache_entry *global_method_cache = &ruby_cache_table[0];
-
-#define cache global_method_cache
-
-#define CACHE_MASK 0x7ff
-#define EXPR1(c,m) ((((c)>>3)^(m))&CACHE_MASK)
-
 #include "call_cfunc.h"
 
 void

Modified: branches/multivm/yarv.h
===================================================================
--- branches/multivm/yarv.h	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/yarv.h	2006-02-22 20:45:10 UTC (rev 473)
@@ -24,7 +24,7 @@
 
 #if YARV_THREAD_MODEL == 2
 
-extern yarv_thread_t *yarvCurrentThread;
+extern __thread yarv_thread_t *yarvCurrentThread;
 extern yarv_vm_t *theYarvVM;
 
 static inline VALUE

Modified: branches/multivm/yarvcore.c
===================================================================
--- branches/multivm/yarvcore.c	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/yarvcore.c	2006-02-22 20:45:10 UTC (rev 473)
@@ -119,7 +119,7 @@
 /* YARVCore */
 /************/
 
-yarv_thread_t *yarvCurrentThread = 0;
+yarv_thread_t __thread *yarvCurrentThread = 0;
 yarv_vm_t *theYarvVM = 0;
 static VALUE yarvVMArray = Qnil;
 
@@ -643,10 +643,12 @@
 }
 
 static void
-th_init2(yarv_thread_t *th)
+th_init2(yarv_thread_t *th, yarv_vm_t *vm)
 {
     MEMZERO(th, yarv_thread_t, 1);
 
+    th->vm = vm;
+
     /* allocate thread stack */
     th->stack = ALLOC_N(VALUE, YARV_THREAD_STACK_SIZE);
 
@@ -678,7 +680,7 @@
 static void
 th_init(yarv_thread_t *th)
 {
-    th_init2(th);
+    th_init2(th, GET_THREAD()->vm);
     th_klass_init(th);
 }
 
@@ -1277,17 +1279,23 @@
     }
 }
 
+struct gc_management_struct *ruby_allocate_gc_management_block(void);
+
 void
 Init_yarv(void)
 {
     /* initialize main thread */
-    yarv_vm_t *vm = ALLOC(yarv_vm_t);
-    yarv_thread_t *th = ALLOC(yarv_thread_t);
+    yarv_vm_t *vm = malloc(sizeof(yarv_vm_t));
+    yarv_thread_t *th = malloc(sizeof(yarv_thread_t));
 
     vm_init2(vm);
+
     theYarvVM = vm;
+    yarv_set_current_running_thread_raw(th);
 
-    th_init2(th);
     th->vm = vm;
-    yarv_set_current_running_thread_raw(th);
+    vm->gcm = ruby_allocate_gc_management_block();
+
+    th_init2(th, vm);
 }
+

Modified: branches/multivm/yarvcore.h
===================================================================
--- branches/multivm/yarvcore.h	2006-02-22 20:11:46 UTC (rev 472)
+++ branches/multivm/yarvcore.h	2006-02-22 20:45:10 UTC (rev 473)
@@ -299,7 +299,87 @@
 
     /* object management */
     VALUE mark_object_ary;
+    struct gc_management_struct *gcm;
+
+
+#if YARV_MULTI_VM
+    VALUE vm_value__rb_mKernel;
+    VALUE vm_value__rb_mComparable;
+    VALUE vm_value__rb_mEnumerable;
+    VALUE vm_value__rb_mPrecision;
+    VALUE vm_value__rb_mErrno;
+    VALUE vm_value__rb_mFileTest;
+    VALUE vm_value__rb_mGC;
+    VALUE vm_value__rb_mMath;
+    VALUE vm_value__rb_mProcess;
+    VALUE vm_value__rb_cObject;
+    VALUE vm_value__rb_cArray;
+    VALUE vm_value__rb_cValues;
+    VALUE vm_value__rb_cBignum;
+    VALUE vm_value__rb_cClass;
+    VALUE vm_value__rb_cDir;
+    VALUE vm_value__rb_cData;
+    VALUE vm_value__rb_cFalseClass;
+    VALUE vm_value__rb_cFile;
+    VALUE vm_value__rb_cFixnum;
+    VALUE vm_value__rb_cFloat;
+    VALUE vm_value__rb_cHash;
+    VALUE vm_value__rb_cInteger;
+    VALUE vm_value__rb_cIO;
+    VALUE vm_value__rb_cModule;
+    VALUE vm_value__rb_cNilClass;
+    VALUE vm_value__rb_cNumeric;
+    VALUE vm_value__rb_cProc;
+    VALUE vm_value__rb_cRange;
+    VALUE vm_value__rb_cRegexp;
+    VALUE vm_value__rb_cString;
+    VALUE vm_value__rb_cSymbol;
+    VALUE vm_value__rb_cThread;
+    VALUE vm_value__rb_cTime;
+    VALUE vm_value__rb_cTrueClass;
+    VALUE vm_value__rb_cStruct;
+    VALUE vm_value__rb_eException;
+    VALUE vm_value__rb_eStandardError;
+    VALUE vm_value__rb_eSystemExit;
+    VALUE vm_value__rb_eInterrupt;
+    VALUE vm_value__rb_eSignal;
+    VALUE vm_value__rb_eFatal;
+    VALUE vm_value__rb_eArgError;
+    VALUE vm_value__rb_eEOFError;
+    VALUE vm_value__rb_eIndexError;
+    VALUE vm_value__rb_eKeyError;
+    VALUE vm_value__rb_eRangeError;
+    VALUE vm_value__rb_eIOError;
+    VALUE vm_value__rb_eRuntimeError;
+    VALUE vm_value__rb_eSecurityError;
+    VALUE vm_value__rb_eSystemCallError;
+    VALUE vm_value__rb_eTypeError;
+    VALUE vm_value__rb_eZeroDivError;
+    VALUE vm_value__rb_eNotImpError;
+    VALUE vm_value__rb_eNoMemError;
+    VALUE vm_value__rb_eNoMethodError;
+    VALUE vm_value__rb_eFloatDomainError;
+    VALUE vm_value__rb_eScriptError;
+    VALUE vm_value__rb_eNameError;
+    VALUE vm_value__rb_eSyntaxError;
+    VALUE vm_value__rb_eLoadError;
+    VALUE vm_value__rb_stdin;
+    VALUE vm_value__rb_stdout;
+    VALUE vm_value__rb_stderr;
     
+    int vm_value__ruby_running;
+
+    #define CACHE_SIZE 0x800
+    struct cache_entry {
+	ID mid;
+	ID mid0;
+	VALUE klass;
+	NODE *method;
+    } vm_value__cache[CACHE_SIZE];
+
+    st_table *vm_value__rb_global_tbl;
+    st_table *vm_value__rb_class_tbl;
+#endif
 } yarv_vm_t;
 
 typedef struct {


-- 
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧][生データ]