From d36c76dc71b47b201707185b8a0b4264e83de205 Mon Sep 17 00:00:00 2001 From: nobu Date: Fri, 18 Sep 2009 07:29:17 +0000 Subject: * common.mk (eval.o): needs vm.h. * eval.c (ruby_cleanup): destruct current VM before exit. * gc.c (rb_objspace_free): free object space. * vm.c (ruby_vm_destruct): destruct and free VM struct. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@25000 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 10 ++++++++++ common.mk | 2 +- eval.c | 7 ++++++- gc.c | 36 +++++++++++++++++++++++++++++++++++- include/ruby/vm.h | 6 ++++++ vm.c | 41 ++++++++++++++++++++++++++++++----------- vm_core.h | 9 +++++++++ 7 files changed, 97 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index d24cf34b12..0e20a6f3a1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +Fri Sep 18 16:29:16 2009 Nobuyoshi Nakada + + * common.mk (eval.o): needs vm.h. + + * eval.c (ruby_cleanup): destruct current VM before exit. + + * gc.c (rb_objspace_free): free object space. + + * vm.c (ruby_vm_destruct): destruct and free VM struct. + Fri Sep 18 16:15:04 2009 Nobuyoshi Nakada * compile.c (iseq_compile_each), parse.y (stmt, arg): arg_concat() diff --git a/common.mk b/common.mk index 4c37b93e39..e154625605 100644 --- a/common.mk +++ b/common.mk @@ -536,7 +536,7 @@ enum.$(OBJEXT): {$(VPATH)}enum.c $(RUBY_H_INCLUDES) {$(VPATH)}node.h \ enumerator.$(OBJEXT): {$(VPATH)}enumerator.c $(RUBY_H_INCLUDES) error.$(OBJEXT): {$(VPATH)}error.c {$(VPATH)}known_errors.inc \ $(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h -eval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}eval_intern.h \ +eval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}eval_intern.h {$(VPATH)}vm.h \ $(RUBY_H_INCLUDES) $(VM_CORE_H_INCLUDES) {$(VPATH)}eval_error.c \ {$(VPATH)}eval_jump.c {$(VPATH)}debug.h {$(VPATH)}gc.h {$(VPATH)}iseq.h load.$(OBJEXT): {$(VPATH)}load.c {$(VPATH)}eval_intern.h \ diff --git a/eval.c b/eval.c index 7ba413bd49..b979f28ea7 100644 --- a/eval.c +++ b/eval.c @@ -14,6 +14,7 @@ #include "eval_intern.h" #include "iseq.h" #include "gc.h" +#include "ruby/vm.h" #define numberof(array) (int)(sizeof(array) / sizeof((array)[0])) @@ -159,6 +160,7 @@ ruby_cleanup(volatile int ex) POP_TAG(); rb_thread_stop_timer_thread(); + state = 0; for (nerr = 0; nerr < numberof(errs); ++nerr) { VALUE err = errs[nerr]; @@ -172,12 +174,15 @@ ruby_cleanup(volatile int ex) } else if (rb_obj_is_kind_of(err, rb_eSignal)) { VALUE sig = rb_iv_get(err, "signo"); - ruby_default_signal(NUM2INT(sig)); + state = NUM2INT(sig); + break; } else if (ex == 0) { ex = 1; } } + ruby_vm_destruct(GET_VM()); + if (state) ruby_default_signal(state); #if EXIT_SUCCESS != 0 || EXIT_FAILURE != 1 switch (ex) { diff --git a/gc.c b/gc.c index 6469e98b58..a7f92806ae 100644 --- a/gc.c +++ b/gc.c @@ -366,6 +366,8 @@ int *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress; #define need_call_final (finalizer_table && finalizer_table->num_entries) +static void rb_objspace_call_finalizer(rb_objspace_t *objspace); + #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE rb_objspace_t * rb_objspace_alloc(void) @@ -377,6 +379,33 @@ rb_objspace_alloc(void) return objspace; } + +void +rb_objspace_free(rb_objspace_t *objspace) +{ + rb_objspace_call_finalizer(objspace); + if (objspace->profile.record) { + free(objspace->profile.record); + objspace->profile.record = 0; + } + if (global_List) { + struct gc_list *list, *next; + for (list = global_List; list; list = next) { + next = list->next; + free(list); + } + } + if (heaps) { + int i; + for (i = 0; i < heaps_used; ++i) { + free(heaps[i].membase); + } + free(heaps); + heaps_used = 0; + heaps = 0; + } + free(objspace); +} #endif /* tiny heap size */ @@ -2613,7 +2642,12 @@ chain_finalized_object(st_data_t key, st_data_t val, st_data_t arg) void rb_gc_call_finalizer_at_exit(void) { - rb_objspace_t *objspace = &rb_objspace; + rb_objspace_call_finalizer(&rb_objspace); +} + +void +rb_objspace_call_finalizer(rb_objspace_t *objspace) +{ RVALUE *p, *pend; RVALUE *final_list = 0; size_t i; diff --git a/include/ruby/vm.h b/include/ruby/vm.h index 6843469735..27b976dd85 100644 --- a/include/ruby/vm.h +++ b/include/ruby/vm.h @@ -19,4 +19,10 @@ * http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/mvm/ */ +/* VM type declaration */ +typedef struct rb_vm_struct ruby_vm_t; + +/* core API */ +int ruby_vm_destruct(ruby_vm_t *vm); + #endif /* RUBY_VM_H */ diff --git a/vm.c b/vm.c index d886f4c83b..4254fd94bb 100644 --- a/vm.c +++ b/vm.c @@ -25,6 +25,8 @@ #include "vm_method.c" #include "vm_eval.c" +#include + #define BUFSIZE 0x100 #define PROCDEBUG 0 @@ -41,6 +43,8 @@ char ruby_vm_redefined_flag[BOP_LAST_]; rb_thread_t *ruby_current_thread = 0; rb_vm_t *ruby_current_vm = 0; +static void thread_free(void *ptr); + VALUE rb_insns_name_array(void); void vm_analysis_operand(int insn, int n, VALUE op); @@ -1464,21 +1468,36 @@ rb_vm_mark(void *ptr) RUBY_MARK_LEAVE("vm"); } -static void -vm_free(void *ptr) +#define vm_free 0 + +int +ruby_vm_destruct(rb_vm_t *vm) { RUBY_FREE_ENTER("vm"); - if (ptr) { - rb_vm_t *vmobj = ptr; - - st_free_table(vmobj->living_threads); - vmobj->living_threads = 0; - /* TODO: MultiVM Instance */ - /* VM object should not be cleaned by GC */ - /* ruby_xfree(ptr); */ - /* ruby_current_vm = 0; */ + if (vm) { + rb_thread_t *th = vm->main_thread; +#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_xfree(vm); + ruby_current_vm = 0; +#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE + if (objspace) { + rb_objspace_free(objspace); + } +#endif } RUBY_FREE_LEAVE("vm"); + return 0; } static size_t diff --git a/vm_core.h b/vm_core.h index 6c7624193a..6a5c31c922 100644 --- a/vm_core.h +++ b/vm_core.h @@ -31,6 +31,10 @@ #error "unsupported thread type" #endif +#ifndef ENABLE_VM_OBJSPACE +#define ENABLE_VM_OBJSPACE 1 +#endif + #include #include @@ -239,6 +243,11 @@ enum ruby_special_exceptions { #define GetVMPtr(obj, ptr) \ GetCoreDataFromValue(obj, rb_vm_t, ptr) +#if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE +struct rb_objspace; +void rb_objspace_free(struct rb_objspace *); +#endif + typedef struct rb_vm_struct { VALUE self; -- cgit v1.2.3