ruby-changes:14000
From: nobu <ko1@a...>
Date: Tue, 17 Nov 2009 12:02:08 +0900 (JST)
Subject: [ruby-changes:14000] Ruby:r25808 (mvm): * vm_core.h (rb_vm_t): manage references from other VMs.
nobu 2009-11-17 12:00:58 +0900 (Tue, 17 Nov 2009) New Revision: 25808 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25808 Log: * vm_core.h (rb_vm_t): manage references from other VMs. * mvm.c (ruby_vm_destruct): ditto. * vm.c (ruby_vm_free, vm_init2, vm_create, InitVM_VM): ditto. * vm.c (rb_vm_send): reject terminated VM. Modified files: branches/mvm/ChangeLog branches/mvm/mvm.c branches/mvm/vm.c branches/mvm/vm_core.h Index: mvm/ChangeLog =================================================================== --- mvm/ChangeLog (revision 25807) +++ mvm/ChangeLog (revision 25808) @@ -1,3 +1,12 @@ +Tue Nov 17 12:00:56 2009 Nobuyoshi Nakada <nobu@r...> + + * vm_core.h (rb_vm_t): manage references from other VMs. + + * mvm.c (ruby_vm_destruct): ditto. + + * vm.c (ruby_vm_free, vm_init2, vm_create, InitVM_VM): ditto. + + * vm.c (rb_vm_send): reject terminated VM. Mon Nov 16 22:24:57 2009 Nobuyoshi Nakada <nobu@r...> * regint.h (USE_PARSE_TREE_NODE_RECYCLE): disabled. Index: mvm/vm_core.h =================================================================== --- mvm/vm_core.h (revision 25807) +++ mvm/vm_core.h (revision 25808) @@ -297,6 +297,8 @@ unsigned long trace_flag; volatile int sleeper; + int ref_count; + /* object management */ VALUE mark_object_ary; @@ -697,6 +699,8 @@ void *ruby_objspace_xrealloc2(struct rb_objspace *objspace, void *ptr, size_t n, size_t size); void ruby_objspace_xfree(struct rb_objspace *objspace, void *ptr); +int ruby_vm_free(rb_vm_t *vm); + #define sysstack_error rb_errSysStack VALUE rb_str_resurrect(VALUE str); Index: mvm/mvm.c =================================================================== --- mvm/mvm.c (revision 25807) +++ mvm/mvm.c (revision 25808) @@ -16,7 +16,6 @@ static void vmmgr_add(rb_vm_t *vm); static void vmmgr_del(rb_vm_t *vm); -void rb_vm_free(rb_vm_t *vm); static int vm_join(rb_vm_t *vm); @@ -51,8 +50,10 @@ int ruby_vm_destruct(rb_vm_t *vm) { - rb_vm_free(vm); - vmmgr_del(vm); + if (ruby_vm_free(vm)) { + vmmgr_del(vm); + free(vm); + } return 0; } Index: mvm/vm.c =================================================================== --- mvm/vm.c (revision 25807) +++ mvm/vm.c (revision 25808) @@ -1477,31 +1477,34 @@ struct rb_objspace *rb_objspace_alloc(void); #endif -#define vm_free 0 - -void -rb_vm_free(void *ptr) +int +ruby_vm_free(rb_vm_t *vm) { - rb_vm_t *vm = ptr; + if (!vm) return FALSE; - RUBY_FREE_ENTER("vm"); - if (vm && vm == GET_VM()) { - rb_thread_t *th = vm->main_thread; + if (vm == GET_VM()) { + if (vm->self) { + vm->self = 0; + } + else { + rb_thread_t *th = vm->main_thread; + vm->main_thread = 0; + if (th) { + thread_free(th); + } + if (vm->living_threads) { + st_free_table(vm->living_threads); + vm->living_threads = 0; + } + ruby_native_thread_unlock(&vm->global_vm_lock); + ruby_native_cond_signal(&vm->global_vm_waiting); + } + } + if (!--vm->ref_count) { #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE struct rb_objspace *objspace = vm->objspace; #endif - rb_gc_force_recycle(vm->self); - vm->main_thread = 0; - if (th) { - thread_free(th); - } - if (vm->living_threads) { - st_free_table(vm->living_threads); - vm->living_threads = 0; - } - ruby_native_thread_unlock(&vm->global_vm_lock); ruby_native_thread_lock_destroy(&vm->global_vm_lock); - ruby_native_cond_signal(&vm->global_vm_waiting); ruby_native_cond_destroy(&vm->global_vm_waiting); rb_queue_destroy(&vm->queue.message); #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE @@ -1509,8 +1512,18 @@ rb_objspace_free(objspace); } #endif - free(vm); + return TRUE; } + return FALSE; +} + +static void +vm_free(void *ptr) +{ + rb_vm_t *vm = ptr; + + RUBY_FREE_ENTER("vm"); + ruby_vm_destruct(vm); RUBY_FREE_LEAVE("vm"); } @@ -1535,6 +1548,7 @@ vm_init2(rb_vm_t *vm) { MEMZERO(vm, rb_vm_t, 1); + vm->ref_count = 1; vm->argc = -1; ruby_native_thread_lock_initialize(&vm->global_vm_lock); ruby_native_cond_initialize(&vm->global_vm_waiting); @@ -2028,6 +2042,7 @@ rb_vm_t *vm = arg; int status; ruby_native_thread_unlock(&vm->global_vm_lock); + vm->ref_count++; status = ruby_vm_run(vm, 0); ruby_native_cond_signal(&vm->global_vm_waiting); return (VALUE)status; @@ -2070,6 +2085,9 @@ if (!rb_special_const_p(val) && vm->objspace != GET_VM()->objspace) { rb_raise(rb_eTypeError, "expected special constants"); } + if (!vm->self) { + rb_raise(rb_eArgError, "terminated VM"); + } if (!rb_queue_push(&vm->queue.message, (void *)val)) rb_sys_fail(0); return (VALUE)val; @@ -2205,6 +2223,7 @@ /* create vm object */ vm->self = TypedData_Wrap_Struct(rb_cRubyVM, &vm_data_type, vm); + vm->ref_count++; /* create main thread */ th_self = th->self = TypedData_Wrap_Struct(rb_cThread, &thread_data_type, th); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/