ruby-changes:6394
From: nobu <ko1@a...>
Date: Mon, 7 Jul 2008 00:01:02 +0900 (JST)
Subject: [ruby-changes:6394] Ruby:r17909 (mvm): * include/ruby/public_object.h: moved global variables to VM specific data.
nobu 2008-07-07 00:00:24 +0900 (Mon, 07 Jul 2008) New Revision: 17909 Modified files: branches/mvm/ChangeLog branches/mvm/array.c branches/mvm/bignum.c branches/mvm/class.c branches/mvm/common.mk branches/mvm/compar.c branches/mvm/complex.c branches/mvm/configure.in branches/mvm/cont.c branches/mvm/debug.c branches/mvm/dir.c branches/mvm/dln.c branches/mvm/encoding.c branches/mvm/enum.c branches/mvm/enumerator.c branches/mvm/error.c branches/mvm/eval.c branches/mvm/eval_jump.c branches/mvm/file.c branches/mvm/gc.c branches/mvm/hash.c branches/mvm/include/ruby/encoding.h branches/mvm/include/ruby/intern.h branches/mvm/include/ruby/mvm.h branches/mvm/include/ruby/ruby.h branches/mvm/io.c branches/mvm/iseq.c branches/mvm/marshal.c branches/mvm/math.c branches/mvm/numeric.c branches/mvm/object.c branches/mvm/prec.c branches/mvm/proc.c branches/mvm/process.c branches/mvm/range.c branches/mvm/rational.c branches/mvm/re.c branches/mvm/ruby.c branches/mvm/string.c branches/mvm/struct.c branches/mvm/thread.c branches/mvm/thread_pthread.c branches/mvm/thread_pthread.h branches/mvm/thread_win32.c branches/mvm/thread_win32.h branches/mvm/time.c branches/mvm/variable.c branches/mvm/vm.c branches/mvm/vm.h branches/mvm/vm_core.h branches/mvm/win32/Makefile.sub Log: * include/ruby/public_object.h: moved global variables to VM specific data. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=17909 Index: mvm/complex.c =================================================================== --- mvm/complex.c (revision 17908) +++ mvm/complex.c (revision 17909) @@ -19,8 +19,6 @@ #define ONE INT2FIX(1) #define TWO INT2FIX(2) -VALUE rb_cComplex; - static ID id_Unify, id_abs, id_abs2, id_arg, id_atan2_bang, id_cmp, id_conjugate, id_convert, id_cos, id_denominator, id_divmod, id_equal_p, id_exact_p, id_exp_bang, id_expt, id_floor, id_format, Index: mvm/array.c =================================================================== --- mvm/array.c (revision 17908) +++ mvm/array.c (revision 17909) @@ -15,8 +15,6 @@ #include "ruby/util.h" #include "ruby/st.h" -VALUE rb_cArray; - static ID id_cmp; #define ARY_DEFAULT_SIZE 16 Index: mvm/debug.c =================================================================== --- mvm/debug.c (revision 17908) +++ mvm/debug.c (revision 17909) @@ -22,6 +22,8 @@ enum ruby_value_type value_type; enum ruby_tag_type tag_type; enum node_type node_type; + enum ruby_public_object_vmkey public_vmkey; + enum ruby_private_object_vmkey private_vmkey; enum { RUBY_ENCODING_INLINE_MAX = ENCODING_INLINE_MAX, RUBY_ENCODING_SHIFT = ENCODING_SHIFT, @@ -65,7 +67,7 @@ RUBY_NODE_LMASK = NODE_LMASK, RUBY_NODE_FL_NEWLINE = NODE_FL_NEWLINE } various; -} dummy_gdb_enums; +} dummy_gdb_enums = {0}; const VALUE RUBY_FL_USER20 = FL_USER20; Index: mvm/encoding.c =================================================================== --- mvm/encoding.c (revision 17908) +++ mvm/encoding.c (revision 17909) @@ -12,14 +12,13 @@ #include "ruby/ruby.h" #include "ruby/encoding.h" #include "regenc.h" +#include "private_object.h" #include <ctype.h> #ifdef HAVE_LANGINFO_H #include <langinfo.h> #endif static ID id_encoding, id_base_encoding; -VALUE rb_cEncoding; -static VALUE rb_encoding_list; struct rb_encoding_entry { const char *name; @@ -1196,7 +1195,6 @@ rb_define_singleton_method(rb_cEncoding, "default_external", get_default_external, 0); rb_define_singleton_method(rb_cEncoding, "locale_charmap", rb_locale_charmap, 0); - rb_gc_register_address(&rb_encoding_list); list = rb_ary_new2(enc_table.count); RBASIC(list)->klass = 0; rb_encoding_list = list; Index: mvm/thread_win32.c =================================================================== --- mvm/thread_win32.c (revision 17908) +++ mvm/thread_win32.c (revision 17909) @@ -32,13 +32,13 @@ static void native_cond_initialize(rb_thread_cond_t *cond); static void native_cond_destroy(rb_thread_cond_t *cond); -static rb_thread_t * +rb_thread_t * ruby_thread_from_native(void) { return TlsGetValue(ruby_native_thread_key); } -static int +int ruby_thread_set_native(rb_thread_t *th) { return TlsSetValue(ruby_native_thread_key, th); @@ -290,6 +290,12 @@ #endif } +int +ruby_native_thread_lock(rb_thread_lock_t *lock) +{ + return native_mutex_lock(lock); +} + static int native_mutex_unlock(rb_thread_lock_t *lock) { @@ -302,6 +308,12 @@ #endif } +int +ruby_native_thread_unlock(rb_thread_lock_t *lock) +{ + return native_mutex_unlock(lock); +} + static int native_mutex_trylock(rb_thread_lock_t *lock) { Index: mvm/math.c =================================================================== --- mvm/math.c (revision 17908) +++ mvm/math.c (revision 17909) @@ -13,8 +13,6 @@ #include <math.h> #include <errno.h> -VALUE rb_mMath; - static VALUE to_flo(VALUE x) { Index: mvm/time.c =================================================================== --- mvm/time.c (revision 17908) +++ mvm/time.c (revision 17909) @@ -21,7 +21,6 @@ #include <math.h> -VALUE rb_cTime; static VALUE time_utc_offset _((VALUE)); static ID id_divmod, id_mul, id_submicro; Index: mvm/thread_win32.h =================================================================== --- mvm/thread_win32.h (revision 17908) +++ mvm/thread_win32.h (revision 17909) @@ -24,10 +24,14 @@ typedef HANDLE rb_thread_id_t; typedef CRITICAL_SECTION rb_thread_lock_t; typedef struct rb_thread_cond_struct rb_thread_cond_t; +#define RB_THREAD_LOCK_INITIALIZER {} typedef struct native_thread_data_struct { HANDLE interrupt_event; } native_thread_data_t; +int ruby_native_thread_lock(rb_thread_lock_t*); +int ruby_native_thread_unlock(rb_thread_lock_t*); + #endif /* RUBY_THREAD_WIN32_H */ Index: mvm/include/ruby/intern.h =================================================================== --- mvm/include/ruby/intern.h (revision 17908) +++ mvm/include/ruby/intern.h (revision 17909) @@ -282,8 +282,6 @@ int rb_obj_method_arity(VALUE, ID); VALUE rb_protect(VALUE (*)(VALUE), VALUE, int*); void rb_set_end_proc(void (*)(VALUE), VALUE); -void rb_mark_end_proc(void); -void rb_exec_end_proc(void); void Init_jump(void); void ruby_finalize(void); NORETURN(void ruby_stop(int)); @@ -640,7 +638,6 @@ void rb_autoload(VALUE, ID, const char*); VALUE rb_autoload_load(VALUE, ID); VALUE rb_autoload_p(VALUE, ID); -void rb_gc_mark_global_tbl(void); VALUE rb_f_trace_var(int, VALUE*); VALUE rb_f_untrace_var(int, VALUE*); VALUE rb_f_global_variables(void); Index: mvm/include/ruby/mvm.h =================================================================== --- mvm/include/ruby/mvm.h (revision 17908) +++ mvm/include/ruby/mvm.h (revision 17909) @@ -12,6 +12,8 @@ #ifndef RUBY_MVM_H #define RUBY_MVM_H 1 +#define HAVE_MVM 1 + typedef struct rb_vm_struct rb_vm_t; typedef struct rb_thread_struct rb_thread_t; @@ -32,4 +34,9 @@ rb_vm_t *ruby_vm_new(void); int ruby_vm_run(rb_vm_t *, VALUE); +int rb_vm_key_count(void); +int rb_vm_key_create(void); +VALUE *ruby_vm_specific_ptr(rb_vm_t *, int); +VALUE *rb_vm_specific_ptr(int); + #endif /* RUBY_MVM_H */ Index: mvm/include/ruby/ruby.h =================================================================== --- mvm/include/ruby/ruby.h (revision 17908) +++ mvm/include/ruby/ruby.h (revision 17909) @@ -742,6 +742,7 @@ void rb_define_variable(const char*,VALUE*); void rb_define_virtual_variable(const char*,VALUE(*)(ANYARGS),void(*)(ANYARGS)); void rb_define_hooked_variable(const char*,VALUE*,VALUE(*)(ANYARGS),void(*)(ANYARGS)); +void rb_define_vm_specific_variable(const char*,int,VALUE(*)(ANYARGS),void(*)(ANYARGS)); void rb_define_readonly_variable(const char*,VALUE*); void rb_define_const(VALUE,const char*,VALUE); void rb_define_global_const(const char*,VALUE); @@ -861,87 +862,8 @@ void *ruby_options(int, char**); int ruby_run_node(void *); -RUBY_EXTERN VALUE rb_mKernel; -RUBY_EXTERN VALUE rb_mComparable; -RUBY_EXTERN VALUE rb_mEnumerable; -RUBY_EXTERN VALUE rb_mPrecision; -RUBY_EXTERN VALUE rb_mErrno; -RUBY_EXTERN VALUE rb_mFileTest; -RUBY_EXTERN VALUE rb_mGC; -RUBY_EXTERN VALUE rb_mMath; -RUBY_EXTERN VALUE rb_mProcess; +#include "ruby/public_object.h" -RUBY_EXTERN VALUE rb_cBasicObject; -RUBY_EXTERN VALUE rb_cObject; -RUBY_EXTERN VALUE rb_cArray; -RUBY_EXTERN VALUE rb_cBignum; -RUBY_EXTERN VALUE rb_cBinding; -RUBY_EXTERN VALUE rb_cClass; -RUBY_EXTERN VALUE rb_cCont; -RUBY_EXTERN VALUE rb_cDir; -RUBY_EXTERN VALUE rb_cData; -RUBY_EXTERN VALUE rb_cFalseClass; -RUBY_EXTERN VALUE rb_cEnumerator; -RUBY_EXTERN VALUE rb_cFile; -RUBY_EXTERN VALUE rb_cFixnum; -RUBY_EXTERN VALUE rb_cFloat; -RUBY_EXTERN VALUE rb_cHash; -RUBY_EXTERN VALUE rb_cInteger; -RUBY_EXTERN VALUE rb_cIO; -RUBY_EXTERN VALUE rb_cMatch; -RUBY_EXTERN VALUE rb_cMethod; -RUBY_EXTERN VALUE rb_cModule; -RUBY_EXTERN VALUE rb_cNameErrorMesg; -RUBY_EXTERN VALUE rb_cNilClass; -RUBY_EXTERN VALUE rb_cNumeric; -RUBY_EXTERN VALUE rb_cProc; -RUBY_EXTERN VALUE rb_cRange; -RUBY_EXTERN VALUE rb_cRational; -RUBY_EXTERN VALUE rb_cComplex; -RUBY_EXTERN VALUE rb_cRegexp; -RUBY_EXTERN VALUE rb_cStat; -RUBY_EXTERN VALUE rb_cString; -RUBY_EXTERN VALUE rb_cStruct; -RUBY_EXTERN VALUE rb_cSymbol; -RUBY_EXTERN VALUE rb_cThread; -RUBY_EXTERN VALUE rb_cTime; -RUBY_EXTERN VALUE rb_cTrueClass; -RUBY_EXTERN VALUE rb_cUnboundMethod; - -RUBY_EXTERN VALUE rb_eException; -RUBY_EXTERN VALUE rb_eStandardError; -RUBY_EXTERN VALUE rb_eSystemExit; -RUBY_EXTERN VALUE rb_eInterrupt; -RUBY_EXTERN VALUE rb_eSignal; -RUBY_EXTERN VALUE rb_eFatal; -RUBY_EXTERN VALUE rb_eArgError; -RUBY_EXTERN VALUE rb_eEOFError; -RUBY_EXTERN VALUE rb_eIndexError; -RUBY_EXTERN VALUE rb_eStopIteration; -RUBY_EXTERN VALUE rb_eKeyError; -RUBY_EXTERN VALUE rb_eRangeError; -RUBY_EXTERN VALUE rb_eIOError; -RUBY_EXTERN VALUE rb_eRuntimeError; -RUBY_EXTERN VALUE rb_eSecurityError; -RUBY_EXTERN VALUE rb_eSystemCallError; -RUBY_EXTERN VALUE rb_eThreadError; -RUBY_EXTERN VALUE rb_eTypeError; -RUBY_EXTERN VALUE rb_eZeroDivError; -RUBY_EXTERN VALUE rb_eNotImpError; -RUBY_EXTERN VALUE rb_eNoMemError; -RUBY_EXTERN VALUE rb_eNoMethodError; -RUBY_EXTERN VALUE rb_eFloatDomainError; -RUBY_EXTERN VALUE rb_eLocalJumpError; -RUBY_EXTERN VALUE rb_eSysStackError; -RUBY_EXTERN VALUE rb_eRegexpError; - -RUBY_EXTERN VALUE rb_eScriptError; -RUBY_EXTERN VALUE rb_eNameError; -RUBY_EXTERN VALUE rb_eSyntaxError; -RUBY_EXTERN VALUE rb_eLoadError; - -RUBY_EXTERN VALUE rb_stdin, rb_stdout, rb_stderr; - static inline VALUE rb_class_of(VALUE obj) { Index: mvm/include/ruby/encoding.h =================================================================== --- mvm/include/ruby/encoding.h (revision 17908) +++ mvm/include/ruby/encoding.h (revision 17909) @@ -175,7 +175,6 @@ VALUE rb_locale_charmap(VALUE klass); long rb_memsearch(const void*,long,const void*,long,rb_encoding*); -RUBY_EXTERN VALUE rb_cEncoding; #define enc_initialized_p(enc) ((enc)->ruby_encoding_index != ENC_UNINITIALIZED) #define ENC_DUMMY_FLAG (1<<24) #define ENC_INDEX_MASK (~(~0U<<24)) Index: mvm/configure.in =================================================================== --- mvm/configure.in (revision 17908) +++ mvm/configure.in (revision 17909) @@ -1130,6 +1130,18 @@ AC_CHECK_FUNCS(getcontext setcontext) fi fi +AC_CACHE_CHECK([for thread specific data], rb_cv_thread_specific, +[rb_cv_thread_specific=no +for th in "__declspec(thread)" __thread; do + AC_TRY_COMPILE(AC_INCLUDES_DEFAULT[ +@%:@ifdef HAVE_PTHREAD_H +@%:@include <pthread.h> +@%:@endif +extern $th int foo_th_extern; static $th int foo_th_static;], + [if (foo_th_extern) return foo_th_static;], + [rb_cv_thread_specific="$th"; break]) +done]) +test "$rb_cv_thread_specific" = "" || AC_DEFINE_UNQUOTED(THREAD_SPECIFIC, $rb_cv_thread_specific) if test "$ac_cv_func_fork" = "yes" -a "$rb_with_pthread" = "yes"; then AC_CACHE_CHECK([if fork works with pthread], rb_cv_fork_with_pthread, Index: mvm/re.c =================================================================== --- mvm/re.c (revision 17908) +++ mvm/re.c (revision 17909) @@ -16,8 +16,6 @@ #include "regint.h" #include <ctype.h> -VALUE rb_eRegexpError; - typedef char onig_errmsg_buffer[ONIG_MAX_ERROR_MESSAGE_LEN]; #define BEG(no) regs->beg[no] @@ -767,8 +765,6 @@ * */ -VALUE rb_cMatch; - static VALUE match_alloc(VALUE klass) { @@ -1823,8 +1819,6 @@ return str; } -VALUE rb_cRegexp; - static int read_escaped_byte(const char **pp, const char *end, onig_errmsg_buffer err) { Index: mvm/ChangeLog =================================================================== --- mvm/ChangeLog (revision 17908) +++ mvm/ChangeLog (revision 17909) @@ -1,3 +1,7 @@ +Mon Jul 7 00:00:21 2008 Nobuyoshi Nakada <nobu@r...> + + * include/ruby/public_object.h: moved global variables to VM specific data. + Sun Jul 6 23:48:06 2008 Nobuyoshi Nakada <nobu@r...> * ext/socket/socket.c (bsock_send, s_recvfrom, ruby_connect, s_accept), Index: mvm/thread_pthread.c =================================================================== --- mvm/thread_pthread.c (revision 17908) +++ mvm/thread_pthread.c (revision 17909) @@ -135,7 +135,7 @@ #endif static void remove_signal_thread_list(rb_thread_t *th); -static rb_thread_lock_t signal_thread_list_lock; +static rb_thread_lock_t signal_thread_list_lock = RB_THREAD_LOCK_INITIALIZER;; static pthread_key_t ruby_native_thread_key; @@ -145,29 +145,44 @@ /* null */ } -static rb_thread_t * +rb_thread_t * ruby_thread_from_native(void) { +#ifdef THREAD_SPECIFIC + return ruby_current_thread; +#else return pthread_getspecific(ruby_native_thread_key); +#endif } -static int +int ruby_thread_set_native(rb_thread_t *th) { +#ifdef THREAD_SPECIFIC + ruby_current_thread = th; + return 1; +#else return pthread_setspecific(ruby_native_thread_key, th) == 0; +#endif } static void +init_once_native_thread(void) +{ + pthread_key_create(&ruby_native_thread_key, NULL); + posix_signal(SIGVTALRM, null_func); +} + +static void Init_native_thread(void) { rb_thread_t *th = GET_THREAD(); + static pthread_once_t init_for_all_thread = PTHREAD_ONCE_INIT; - pthread_key_create(&ruby_native_thread_key, NULL); + pthread_once(&init_for_all_thread, init_once_native_thread); th->thread_id = pthread_self(); native_cond_initialize(&th->native_thread_data.sleep_cond); ruby_thread_set_native(th); - native_mutex_initialize(&signal_thread_list_lock); - posix_signal(SIGVTALRM, null_func); } static void Index: mvm/enumerator.c =================================================================== --- mvm/enumerator.c (revision 17908) +++ mvm/enumerator.c (revision 17909) @@ -21,11 +21,8 @@ * A class which provides a method `each' to be used as an Enumerable * object. */ -VALUE rb_cEnumerator; static VALUE sym_each; -VALUE rb_eStopIteration; - struct enumerator { VALUE obj; ID meth; Index: mvm/thread_pthread.h =================================================================== --- mvm/thread_pthread.h (revision 17908) +++ mvm/thread_pthread.h (revision 17909) @@ -15,10 +15,14 @@ typedef pthread_t rb_thread_id_t; typedef pthread_mutex_t rb_thread_lock_t; typedef pthread_cond_t rb_thread_cond_t; +#define RB_THREAD_LOCK_INITIALIZER PTHREAD_MUTEX_INITIALIZER typedef struct native_thread_data_struct { void *signal_thread_list; pthread_cond_t sleep_cond; } native_thread_data_t; +#define ruby_native_thread_lock(lock) pthread_mutex_lock(lock) +#define ruby_native_thread_unlock(lock) pthread_mutex_unlock(lock) + #endif /* RUBY_THREAD_PTHREAD_H */ Index: mvm/variable.c =================================================================== --- mvm/variable.c (revision 17908) +++ mvm/variable.c (revision 17909) @@ -15,20 +15,22 @@ #include "ruby/node.h" #include "ruby/st.h" #include "ruby/util.h" +#include "vm_core.h" void rb_vm_change_state(void); -st_table *rb_global_tbl; -st_table *rb_class_tbl; -static ID autoload, classpath, tmp_classpath; +#define rb_global_tbl GET_VM()->global_tbl +static ID autoload, classpath, tmp_classpath, id_const_missing; void Init_var_tables(void) { - rb_global_tbl = st_init_numtable(); - rb_class_tbl = st_init_numtable(); + rb_vm_t *vm = GET_VM(); + vm->mark_object_ary = rb_ary_new(); + vm->global_tbl = st_init_numtable(); CONST_ID(autoload, "__autoload__"); CONST_ID(classpath, "__classpath__"); CONST_ID(tmp_classpath, "__tmp_classpath__"); + CONST_ID(id_const_missing, "const_missing"); } struct fc_result { @@ -120,9 +122,6 @@ if (RCLASS_IV_TBL(rb_cObject)) { st_foreach_safe(RCLASS_IV_TBL(rb_cObject), fc_i, (st_data_t)&arg); } - if (arg.path == 0) { - st_foreach_safe(rb_class_tbl, fc_i, (st_data_t)&arg); - } if (arg.path) { if (!RCLASS_IV_TBL(klass)) { RCLASS_IV_TBL(klass) = st_init_numtable(); @@ -291,8 +290,13 @@ struct trace_var *next; }; +enum gvar_flags { + gv_vm_specific_storage = 1 +}; + struct global_variable { int counter; + int flags; void *data; VALUE (*getter)(); void (*setter)(); @@ -301,11 +305,6 @@ struct trace_var *trace; }; -struct global_entry { - struct global_variable *var; - ID id; -}; - static VALUE undef_getter(ID id); static void undef_setter(VALUE val, ID id, void *data, struct global_variable *var); static void undef_marker(void); @@ -331,6 +330,7 @@ entry->id = id; entry->var = var; var->counter = 1; + var->flags = 0; var->data = 0; var->getter = undef_getter; var->setter = undef_setter; @@ -407,6 +407,12 @@ } static void +vm_marker(void *var) +{ + rb_gc_mark(*rb_vm_specific_ptr((int)var)); +} + +static void readonly_setter(VALUE val, ID id, void *var) { rb_name_error(id, "%s is a read-only variable", rb_id2name(id)); @@ -428,10 +434,10 @@ } void -rb_gc_mark_global_tbl(void) +rb_vm_mark_global_tbl(st_table *global_tbl) { - if (rb_global_tbl) - st_foreach_safe(rb_global_tbl, mark_global_entry, 0); + if (global_tbl) + st_foreach_safe(global_tbl, mark_global_entry, 0); } static ID @@ -459,16 +465,34 @@ struct global_variable *gvar; ID id; VALUE tmp; - - if (var) - tmp = *var; + int vmkey = -1; + if (var) { + rb_vm_t *vm = GET_VM(); + if (vm->specific_storage.ptr && + vm->specific_storage.ptr <= var && + var < vm->specific_storage.ptr + vm->specific_storage.len && + ((char *)var - (char *)vm->specific_storage.ptr) % sizeof(VALUE) == 0) { + vmkey = var - vm->specific_storage.ptr; + } + else { + tmp = *var; + } + } + id = global_id(name); gvar = rb_global_entry(id)->var; - gvar->data = (void*)var; + if (vmkey != -1) { + gvar->flags |= gv_vm_specific_storage; + gvar->data = (void*)vmkey; + gvar->marker = vm_marker; + } + else { + gvar->data = (void*)var; + gvar->marker = var_marker; + } gvar->getter = getter?getter:var_getter; gvar->setter = setter?setter:var_setter; - gvar->marker = var_marker; RB_GC_GUARD(tmp); } @@ -496,6 +520,30 @@ rb_define_hooked_variable(name, 0, getter, setter); } + +void +rb_define_vm_specific_variable( + const char *name, + int vmkey, + VALUE (*getter)(ANYARGS), + void (*setter)(ANYARGS)) +{ + struct global_variable *gvar; + ID id; + + if (!getter) getter = var_getter; + if (!setter) setter = var_setter; + else if (setter == (void (*)(ANYARGS))-1) setter = readonly_setter; + + id = global_id(name); + gvar = rb_global_entry(id)->var; + gvar->flags |= gv_vm_specific_storage; + gvar->data = (void*)vmkey; + gvar->getter = getter; + gvar->setter = setter; + gvar->marker = vm_marker; +} + static void rb_trace_eval(VALUE cmd, VALUE val) { @@ -632,7 +680,11 @@ rb_gvar_get(struct global_entry *entry) { struct global_variable *var = entry->var; - return (*var->getter)(entry->id, var->data, var); + void *data = var->data; + if (var->flags & gv_vm_specific_storage) { + data = (void *)rb_vm_specific_ptr((int)data); + } + return (*var->getter)(entry->id, data, var); } struct trace_data { @@ -665,10 +717,14 @@ { struct trace_data trace; struct global_variable *var = entry->var; + void *data = var->data; if (rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't change global variable value"); - (*var->setter)(val, entry->id, var->data, var); + if (var->flags & gv_vm_specific_storage) { + data = (void *)rb_vm_specific_ptr((int)data); + } + (*var->setter)(val, entry->id, data, var); if (var->trace && !var->block_trace) { var->block_trace = 1; @@ -773,16 +829,43 @@ entry1->var = entry2->var; } -static int special_generic_ivar = 0; -static st_table *generic_iv_tbl; +#define generic_iv_tbl ((st_table *)DATA_PTR(generic_iv)) +static int +generic_iv_mark_entry(st_data_t key, st_data_t val, st_data_t arg) +{ + rb_mark_tbl((st_table *)val); + return ST_CONTINUE; +} + +static void +generic_iv_mark(void *ptr) +{ + st_foreach(ptr, generic_iv_mark_entry, 0); +} + +static int +generic_iv_mark_free(st_data_t key, st_data_t val, st_data_t arg) +{ + st_free_table((st_table *)val); + return ST_DELETE; +} + +static void +generic_iv_free(void *ptr) +{ + st_foreach(ptr, generic_iv_mark_free, 0); + st_free_table(ptr); +} + st_table* rb_generic_ivar_table(VALUE obj) { st_data_t tbl; + VALUE generic_iv; if (!FL_TEST(obj, FL_EXIVAR)) return 0; - if (!generic_iv_tbl) return 0; + if (!(generic_iv = rb_generic_iv_tbl)) return 0; if (!st_lookup(generic_iv_tbl, obj, &tbl)) return 0; return (st_table *)tbl; } @@ -792,8 +875,9 @@ { st_data_t tbl; VALUE val; + VALUE generic_iv = rb_generic_iv_tbl; - if (generic_iv_tbl) { + if (generic_iv) { if (st_lookup(generic_iv_tbl, obj, &tbl)) { if (st_lookup((st_table *)tbl, id, &val)) { return val; @@ -811,13 +895,14 @@ { st_table *tbl; st_data_t data; + VALUE generic_iv; if (rb_special_const_p(obj)) { if (rb_obj_frozen_p(obj)) rb_error_frozen("object"); - special_generic_ivar = 1; } - if (!generic_iv_tbl) { - generic_iv_tbl = st_init_numtable(); + if (!(generic_iv = rb_generic_iv_tbl)) { + generic_iv = Data_Wrap_Struct(0, generic_iv_mark, generic_iv_free, st_init_numtable()); + rb_generic_iv_tbl = generic_iv; } if (!st_lookup(generic_iv_tbl, obj, &data)) { FL_SET(obj, FL_EXIVAR); @@ -835,8 +920,9 @@ st_table *tbl; st_data_t data; VALUE val; + VALUE generic_iv = rb_generic_iv_tbl; - if (!generic_iv_tbl) return Qfalse; + if (!generic_iv) return Qfalse; if (!st_lookup(generic_iv_tbl, obj, &data)) return Qfalse; tbl = (st_table *)data; if (st_lookup(tbl, id, &val)) { @@ -851,8 +937,9 @@ st_table *tbl; st_data_t data; int status; + VALUE generic_iv = rb_generic_iv_tbl; - if (!generic_iv_tbl) return 0; + if (!generic_iv) return 0; if (!st_lookup(generic_iv_tbl, obj, &data)) return 0; tbl = (st_table *)data; status = st_delete(tbl, &id, valp); @@ -867,8 +954,9 @@ rb_mark_generic_ivar(VALUE obj) { st_data_t tbl; + VALUE generic_iv = rb_generic_iv_tbl; - if (!generic_iv_tbl) return; + if (!generic_iv) return; if (st_lookup(generic_iv_tbl, obj, &tbl)) { rb_mark_tbl((st_table *)tbl); } @@ -893,8 +981,10 @@ void rb_mark_generic_ivar_tbl(void) { - if (!generic_iv_tbl) return; - if (special_generic_ivar == 0) return; + VALUE generic_iv = rb_generic_iv_tbl; + + if (!generic_iv) return; + if (generic_iv_tbl->num_entries == 0) return; st_foreach_safe(generic_iv_tbl, givar_i, 0); } @@ -902,8 +992,9 @@ rb_free_generic_ivar(VALUE obj) { st_data_t tbl; + VALUE generic_iv = rb_generic_iv_tbl; - if (!generic_iv_tbl) return; + if (!generic_iv) return; if (st_delete(generic_iv_tbl, &obj, &tbl)) st_free_table((st_table *)tbl); } @@ -912,8 +1003,9 @@ rb_copy_generic_ivar(VALUE clone, VALUE obj) { st_data_t data; + VALUE generic_iv = rb_generic_iv_tbl; - if (!generic_iv_tbl) return; + if (!generic_iv) return; if (!FL_TEST(obj, FL_EXIVAR)) { clear: if (FL_TEST(clone, FL_EXIVAR)) { @@ -1127,6 +1219,8 @@ void rb_ivar_foreach(VALUE obj, int (*func)(ANYARGS), st_data_t arg) { + VALUE generic_iv = rb_generic_iv_tbl; + switch (TYPE(obj)) { case T_OBJECT: obj_ivar_each(obj, func, arg); @@ -1138,7 +1232,7 @@ } break; default: - if (!generic_iv_tbl) break; + if (!generic_iv) break; if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj)) { st_data_t tbl; @@ -1269,7 +1363,7 @@ static VALUE const_missing(VALUE klass, ID id) { - return rb_funcall(klass, rb_intern("const_missing"), 1, ID2SYM(id)); + return rb_funcall(klass, id_const_missing, 1, ID2SYM(id)); } Index: mvm/vm_core.h =================================================================== --- mvm/vm_core.h (revision 17908) +++ mvm/vm_core.h (revision 17909) @@ -21,6 +21,7 @@ #include "ruby/signal.h" #include "ruby/st.h" #include "ruby/node.h" +#include "private_object.h" #include "debug.h" #include "vm_opts.h" @@ -282,15 +283,15 @@ struct iseq_compile_data *compile_data; }; -enum ruby_special_exceptions { - ruby_error_reenter, - ruby_error_nomemory, - ruby_error_sysstack, - ruby_special_error_count +typedef struct rb_iseq_struct rb_iseq_t; + +enum end_proc_type { + end_proc_ordinary, + end_proc_ephemeral, + end_proc_temporary, + end_proc_count }; -typedef struct rb_iseq_struct rb_iseq_t; - #define GetVMPtr(obj, ptr) \ GetCoreDataFromValue(obj, rb_vm_t, ptr) @@ -302,6 +303,10 @@ rb_thread_lock_t global_vm_lock; + VALUE global_state_version; + VALUE redefined_flag; + st_table *opt_method_table; + struct rb_thread_struct *main_thread; struct rb_thread_struct *running_thread; @@ -314,17 +319,17 @@ unsigned long trace_flag; volatile int sleeper; - VALUE argf; - /* object management */ VALUE mark_object_ary; + st_table *global_tbl; + struct { VALUE *ptr; long len; } specific_storage; - VALUE special_exceptions[ruby_special_error_count]; + struct end_proc_data *end_procs[end_proc_count]; /* load */ VALUE top_self; @@ -341,9 +346,6 @@ int src_encoding_index; - VALUE verbose, debug, progname; - VALUE coverages; - #ifdef RUBY_DEBUG_ENV int enable_coredump; #endif @@ -518,11 +520,6 @@ VALUE ruby_iseq_disasm_insn(VALUE str, VALUE *iseqval, int pos, rb_iseq_t *iseq, VALUE child); const char *ruby_node_name(int node); -RUBY_EXTERN VALUE rb_cISeq; -RUBY_EXTERN VALUE rb_cRubyVM; -RUBY_EXTERN VALUE rb_cEnv; -RUBY_EXTERN VALUE rb_mRubyVMFrozenCore; - /* each thread has this size stack : 128KB */ #define RUBY_VM_THREAD_STACK_SIZE (128 * 1024) @@ -608,6 +605,7 @@ typedef NODE *IC; void rb_vm_change_state(void); +void rb_vm_mark_global_tbl(st_table *); typedef VALUE CDHASH; @@ -681,17 +679,27 @@ NOINLINE(void rb_gc_save_machine_context(rb_thread_t *)); -#define sysstack_error GET_VM()->special_exceptions[ruby_error_sysstack] +void rb_mark_end_proc(struct end_proc_data **); +void rb_exec_end_proc(struct end_proc_data **); +#define sysstack_error rb_errSysStack + /* for thread */ #if RUBY_VM_THREAD_MODEL == 2 -RUBY_EXTERN rb_thread_t *ruby_current_thread; -extern rb_vm_t *ruby_current_vm; +#ifdef THREAD_SPECIFIC +extern THREAD_SPECIFIC rb_thread_t *ruby_current_thread; +#define rb_thread_set_current_raw(th) (void)(ruby_current_thread = (th)) +#else +#define ruby_current_thread ruby_thread_from_native() +#define rb_thread_set_current_raw(th) (void)ruby_thread_from_native(th) +#endif -#define GET_VM() ruby_current_vm +rb_thread_t * ruby_thread_from_native(void); +int ruby_thread_set_native(rb_thread_t *th); + +#define GET_VM() (GET_THREAD()->vm) #define GET_THREAD() ruby_current_thread -#define rb_thread_set_current_raw(th) (ruby_current_thread = th) #define rb_thread_set_current(th) do { \ rb_thread_set_current_raw(th); \ th->vm->running_thread = th; \ Index: mvm/iseq.c =================================================================== --- mvm/iseq.c (revision 17908) +++ mvm/iseq.c (revision 17909) @@ -23,8 +23,6 @@ void iseq_compile(VALUE self, NODE *node); int iseq_translate_threaded_code(rb_iseq_t *iseq); -VALUE rb_cISeq; - static void compile_data_free(struct iseq_compile_data *compile_data) { Index: mvm/enum.c =================================================================== --- mvm/enum.c (revision 17908) +++ mvm/enum.c (revision 17909) @@ -13,7 +13,6 @@ #include "ruby/node.h" #include "ruby/util.h" -VALUE rb_mEnumerable; static ID id_each, id_eqq, id_cmp, id_next, id_size; static VALUE Index: mvm/string.c =================================================================== --- mvm/string.c (revision 17908) +++ mvm/string.c (revision 17909) @@ -29,9 +29,6 @@ #undef rb_tainted_str_new2 #undef rb_usascii_str_new2 -VALUE rb_cString; -VALUE rb_cSymbol; - #define STR_TMPLOCK FL_USER7 #define STR_NOEMBED FL_USER1 #define STR_SHARED FL_USER2 /* = ELTS_SHARED */ Index: mvm/object.c =================================================================== --- mvm/object.c (revision 17908) +++ mvm/object.c (revision 17909) @@ -14,6 +14,7 @@ #include "ruby/ruby.h" #include "ruby/st.h" #include "ruby/util.h" +#include "private_object.h" #include "debug.h" #include <stdio.h> #include <errno.h> @@ -21,17 +22,6 @@ #include <math.h> #include <float.h> -VALUE rb_cBasicObject; -VALUE rb_mKernel; -VALUE rb_cObject; -VALUE rb_cModule; -VALUE rb_cClass; -VALUE rb_cData; - -VALUE rb_cNilClass; -VALUE rb_cTrueClass; -VALUE rb_cFalseClass; - static ID id_eq, id_eql, id_match, id_inspect, id_init_copy; /* @@ -698,8 +688,6 @@ OBJ_INFECT(obj1, obj2); } -static st_table *immediate_frozen_tbl = 0; - /* * call-seq: * obj.freeze => obj @@ -728,8 +716,15 @@ } OBJ_FREEZE(obj); if (SPECIAL_CONST_P(obj)) { - if (!immediate_frozen_tbl) { + VALUE *wrapper = &rb_immediate_frozen_tbl; + st_table *immediate_frozen_tbl; + + if (*wrapper) { + immediate_frozen_tbl = DATA_PTR(*wrapper); + } + else { immediate_frozen_tbl = st_init_numtable(); + *wrapper = rb_wrap_st_table(immediate_frozen_tbl); } st_insert(immediate_frozen_tbl, obj, (st_data_t)Qtrue); } @@ -753,8 +748,9 @@ { if (OBJ_FROZEN(obj)) return Qtrue; if (SPECIAL_CONST_P(obj)) { - if (!immediate_frozen_tbl) return Qfalse; - if (st_lookup(immediate_frozen_tbl, obj, 0)) return Qtrue; + VALUE tbl = rb_immediate_frozen_tbl; + if (!tbl) return Qfalse; + if (st_lookup(DATA_PTR(tbl), obj, 0)) return Qtrue; } return Qfalse; } @@ -2279,12 +2275,10 @@ static VALUE boot_defclass(const char *name, VALUE super) { - extern st_table *rb_class_tbl; VALUE obj = rb_class_boot(super); ID id = rb_intern(name); rb_name_class(obj, id); - st_add_direct(rb_class_tbl, id, obj); rb_const_set((rb_cObject ? rb_cObject : obj), id, obj); return obj; } Index: mvm/io.c =================================================================== --- mvm/io.c (revision 17908) +++ mvm/io.c (revision 17909) @@ -111,11 +111,6 @@ # endif #endif -VALUE rb_cIO; -VALUE rb_eEOFError; -VALUE rb_eIOError; - -VALUE rb_stdin, rb_stdout, rb_stderr; VALUE rb_deferr; /* rescue VIM plugin */ static VALUE orig_stdout, orig_stderr; @@ -141,13 +136,16 @@ }; static int max_file_descriptor = NOFILE; +static rb_thread_lock_t max_file_descriptor_lock; #define UPDATE_MAXFD(fd) \ do { \ + ruby_native_thread_lock(&max_file_descriptor_lock); \ if (max_file_descriptor < (fd)) max_file_descriptor = (fd); \ + ruby_native_thread_unlock(&max_file_descriptor_lock); \ } while (0) #define argf_of(obj) (*(struct argf *)DATA_PTR(obj)) -#define ruby_vm_argf(vm) ((vm)->argf) +#define ruby_vm_argf(vm) (*ruby_vm_specific_ptr(vm, rb_vmkey_argf)) #define ARGF argf_of(ruby_vm_argf(GET_VM())) #ifdef _STDIO_USES_IOSTREAM /* GNU libc */ @@ -3649,8 +3647,9 @@ } } if (ret == 0) { - UPDATE_MAXFD(pipes[0]); - UPDATE_MAXFD(pipes[1]); + int larger_file_descriptor = + pipes[0] > pipes[1] ? pipes[0] : pipes[1]; + UPDATE_MAXFD(larger_file_descriptor); } return ret; } @@ -7465,15 +7464,15 @@ const char * ruby_vm_get_inplace_mode(rb_vm_t *vm) { - return argf_of(vm->argf).inplace; + return argf_of(ruby_vm_argf(vm)).inplace; } void ruby_vm_set_inplace_mode(rb_vm_t *vm, const char *suffix) { - if (argf_of(vm->argf).inplace) free(argf_of(vm->argf).inplace); - argf_of(vm->argf).inplace = 0; - if (suffix) argf_of(vm->argf).inplace = strdup(suffix); + if (argf_of(ruby_vm_argf(vm)).inplace) free(argf_of(ruby_vm_argf(vm)).inplace); + argf_of(ruby_vm_argf(vm)).inplace = 0; + if (suffix) argf_of(ruby_vm_argf(vm)).inplace = strdup(suffix); } static VALUE @@ -7491,7 +7490,7 @@ VALUE ruby_vm_get_argv(rb_vm_t *vm) { - return argf_of(vm->argf).argv; + return argf_of(ruby_vm_argf(vm)).argv; } VALUE @@ -7582,7 +7581,7 @@ #undef rb_intern VALUE rb_cARGF; - VALUE *argfp = &GET_VM()->argf; + VALUE *argfp = &ruby_vm_argf(GET_VM()); #ifdef __CYGWIN__ #include <sys/cygwin.h> static struct __cygwin_perfile pf[] = Index: mvm/range.c =================================================================== --- mvm/range.c (revision 17908) +++ mvm/range.c (revision 17909) @@ -12,7 +12,6 @@ #include "ruby/ruby.h" #include "ruby/encoding.h" -VALUE rb_cRange; static ID id_cmp, id_succ, id_beg, id_end, id_excl; #define RANGE_BEG(r) (RSTRUCT(r)->as.ary[0]) Index: mvm/proc.c =================================================================== --- mvm/proc.c (revision 17908) +++ mvm/proc.c (revision 17909) @@ -20,11 +20,6 @@ NODE *body; }; -VALUE rb_cUnboundMethod; -VALUE rb_cMethod; -VALUE rb_cBinding; -VALUE rb_cProc; - static VALUE bmcall(VALUE, VALUE); static int method_arity(VALUE); static VALUE rb_obj_is_method(VALUE m); Index: mvm/thread.c =================================================================== --- mvm/thread.c (revision 17908) +++ mvm/thread.c (revision 17909) @@ -52,9 +52,6 @@ #define THREAD_DEBUG 0 #endif -VALUE rb_cMutex; -VALUE rb_cBarrier; - static void sleep_timeval(rb_thread_t *th, struct timeval time); static void sleep_wait_for_interrupt(rb_thread_t *th, double sleepsec); static void sleep_forever(rb_thread_t *th, int nodeadlock); @@ -297,7 +294,7 @@ } POP_TAG(); } - system_working = 0; + --system_working; } static void @@ -2092,8 +2089,7 @@ void rb_thread_stop_timer_thread(void) { - if (timer_thread_id) { - system_working = 0; + if (timer_thread_id && --system_working == 0) { native_thread_join(timer_thread_id); timer_thread_id = 0; } @@ -2410,8 +2406,6 @@ VALUE next_mutex; } mutex_t; -static VALUE rb_eMutex_OrphanLock; - #define GetMutexPtr(obj, tobj) \ Data_Get_Struct(obj, mutex_t, tobj) @@ -3563,9 +3557,18 @@ static struct { rb_thread_lock_t lock; int last; -} specific_key; +} specific_key = { + RB_THREAD_LOCK_INITIALIZER, + ruby_builtin_object_count + 8, +}; int +rb_vm_key_count(void) +{ + return specific_key.last; +} + +int rb_vm_key_create(void) { int key; @@ -3580,14 +3583,13 @@ { VALUE *ptr; - native_mutex_lock(&vm->global_vm_lock); ptr = vm->specific_storage.ptr; if (!ptr || vm->specific_storage.len <= key) { ptr = realloc(vm->specific_storage.ptr, sizeof(VALUE) * (key + 1)); vm->specific_storage.ptr = ptr; + MEMZERO(ptr, VALUE, key + 1 - vm->specific_storage.len); vm->specific_storage.len = key + 1; } - native_mutex_unlock(&vm->global_vm_lock); return &ptr[key]; } @@ -3617,11 +3619,12 @@ void rb_enable_coverages(void) { + VALUE *coverages = rb_vm_specific_ptr(rb_vmkey_coverages); VALUE rb_mCoverage; - if (!RTEST(GET_VM()->coverages)) { + if (!RTEST(*coverages)) { extern VALUE rb_vm_get_coverages(void); - GET_VM()->coverages = rb_hash_new(); + *coverages = rb_hash_new(); rb_add_event_hook(update_coverage, RUBY_EVENT_COVERAGE, Qnil); rb_mCoverage = rb_define_module("Coverage"); rb_define_module_function(rb_mCoverage, "result", rb_vm_get_coverages, 0); Index: mvm/common.mk =================================================================== --- mvm/common.mk (revision 17908) +++ mvm/common.mk (revision 17909) @@ -430,8 +430,11 @@ ### RUBY_H_INCLUDES = {$(VPATH)}ruby.h {$(VPATH)}config.h {$(VPATH)}defines.h \ - {$(VPATH)}intern.h {$(VPATH)}missing.h + {$(VPATH)}intern.h {$(VPATH)}missing.h \ + {$(VPATH)}public_object.h +VM_CORE_H_INCLUDES = {$(VPATH)}vm_core.h {$(VPATH)}private_object.h + array.$(OBJEXT): {$(VPATH)}array.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}util.h bignum.$(OBJEXT): {$(VPATH)}bignum.c $(RUBY_H_INCLUDES) \ @@ -450,35 +453,36 @@ dmyext.$(OBJEXT): {$(VPATH)}dmyext.c dmyencoding.$(OBJEXT): {$(VPATH)}dmyencoding.c \ {$(VPATH)}encoding.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h \ - {$(VPATH)}encoding.h {$(VPATH)}oniguruma.h {$(VPATH)}regenc.h + {$(VPATH)}encoding.h {$(VPATH)}oniguruma.h {$(VPATH)}regenc.h \ + {$(VPATH)}private_object.h encoding.$(OBJEXT): dmyencoding.$(OBJEXT) enum.$(OBJEXT): {$(VPATH)}enum.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}node.h {$(VPATH)}util.h enumerator.$(OBJEXT): {$(VPATH)}enumerator.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}debug.h {$(VPATH)}node.h error.$(OBJEXT): {$(VPATH)}error.c $(RUBY_H_INCLUDES) \ - {$(VPATH)}st.h {$(VPATH)}vm_core.h {$(VPATH)}signal.h {$(VPATH)}node.h \ + {$(VPATH)}st.h $(VM_CORE_H_INCLUDES) {$(VPATH)}signal.h {$(VPATH)}node.h \ {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h eval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}eval_intern.h \ $(RUBY_H_INCLUDES) {$(VPATH)}st.h {$(VPATH)}node.h \ - {$(VPATH)}util.h {$(VPATH)}signal.h {$(VPATH)}vm_core.h \ + {$(VPATH)}util.h {$(VPATH)}signal.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}dln.h \ {$(VPATH)}eval_error.c {$(VPATH)}eval_safe.c \ {$(VPATH)}eval_jump.c load.$(OBJEXT): {$(VPATH)}load.c {$(VPATH)}eval_intern.h \ $(RUBY_H_INCLUDES) {$(VPATH)}st.h {$(VPATH)}node.h \ - {$(VPATH)}util.h {$(VPATH)}signal.h {$(VPATH)}vm_core.h \ + {$(VPATH)}util.h {$(VPATH)}signal.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}dln.h file.$(OBJEXT): {$(VPATH)}file.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}io.h {$(VPATH)}encoding.h {$(VPATH)}oniguruma.h \ - {$(VPATH)}signal.h {$(VPATH)}util.h {$(VPATH)}dln.h + {$(VPATH)}signal.h {$(VPATH)}util.h {$(VPATH)}dln.h {$(VPATH)}private_object.h gc.$(OBJEXT): {$(VPATH)}gc.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}signal.h {$(VPATH)}node.h {$(VPATH)}re.h \ {$(VPATH)}regex.h {$(VPATH)}oniguruma.h {$(VPATH)}io.h \ - {$(VPATH)}encoding.h {$(VPATH)}vm_core.h {$(VPATH)}debug.h \ + {$(VPATH)}encoding.h $(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h \ {$(VPATH)}vm_opts.h {$(VPATH)}id.h {$(VPATH)}thread_$(THREAD_MODEL).h \ {$(VPATH)}gc.h {$(VPATH)}eval_intern.h hash.$(OBJEXT): {$(VPATH)}hash.c $(RUBY_H_INCLUDES) \ @@ -492,12 +496,13 @@ {$(VPATH)}st.h marshal.$(OBJEXT): {$(VPATH)}marshal.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}io.h {$(VPATH)}encoding.h \ - {$(VPATH)}oniguruma.h {$(VPATH)}util.h + {$(VPATH)}oniguruma.h {$(VPATH)}util.h {$(VPATH)}private_object.h math.$(OBJEXT): {$(VPATH)}math.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h numeric.$(OBJEXT): {$(VPATH)}numeric.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}encoding.h {$(VPATH)}oniguruma.h object.$(OBJEXT): {$(VPATH)}object.c $(RUBY_H_INCLUDES) \ - {$(VPATH)}st.h {$(VPATH)}util.h {$(VPATH)}debug.h {$(VPATH)}node.h + {$(VPATH)}st.h {$(VPATH)}util.h {$(VPATH)}debug.h {$(VPATH)}node.h \ + {$(VPATH)}private_object.h pack.$(OBJEXT): {$(VPATH)}pack.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h parse.$(OBJEXT): {$(VPATH)}parse.c {$(VPATH)}parse.y $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}node.h {$(VPATH)}encoding.h \ @@ -507,11 +512,11 @@ prec.$(OBJEXT): {$(VPATH)}prec.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h proc.$(OBJEXT): {$(VPATH)}proc.c {$(VPATH)}eval_intern.h \ $(RUBY_H_INCLUDES) {$(VPATH)}st.h {$(VPATH)}node.h \ - {$(VPATH)}util.h {$(VPATH)}signal.h {$(VPATH)}vm_core.h \ + {$(VPATH)}util.h {$(VPATH)}signal.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}dln.h {$(VPATH)}gc.h process.$(OBJEXT): {$(VPATH)}process.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h \ - {$(VPATH)}signal.h {$(VPATH)}vm_core.h \ + {$(VPATH)}signal.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}node.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h random.$(OBJEXT): {$(VPATH)}random.c $(RUBY_H_INCLUDES) \ @@ -545,11 +550,11 @@ ruby.$(OBJEXT): {$(VPATH)}ruby.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}node.h {$(VPATH)}encoding.h \ {$(VPATH)}oniguruma.h {$(VPATH)}eval_intern.h {$(VPATH)}util.h \ - {$(VPATH)}signal.h {$(VPATH)}vm_core.h {$(VPATH)}debug.h \ + {$(VPATH)}signal.h $(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h \ {$(VPATH)}vm_opts.h {$(VPATH)}id.h {$(VPATH)}thread_$(THREAD_MODEL).h \ {$(VPATH)}dln.h signal.$(OBJEXT): {$(VPATH)}signal.c $(RUBY_H_INCLUDES) \ - {$(VPATH)}st.h {$(VPATH)}signal.h {$(VPATH)}node.h {$(VPATH)}vm_core.h \ + {$(VPATH)}st.h {$(VPATH)}signal.h {$(VPATH)}node.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h sprintf.$(OBJEXT): {$(VPATH)}sprintf.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h \ @@ -564,14 +569,14 @@ {$(VPATH)}st.h thread.$(OBJEXT): {$(VPATH)}thread.c {$(VPATH)}eval_intern.h \ $(RUBY_H_INCLUDES) {$(VPATH)}st.h {$(VPATH)}node.h \ - {$(VPATH)}util.h {$(VPATH)}signal.h {$(VPATH)}vm_core.h \ + {$(VPATH)}util.h {$(VPATH)}signal.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}dln.h {$(VPATH)}vm.h \ {$(VPATH)}gc.h {$(VPATH)}thread_$(THREAD_MODEL).c transcode.$(OBJEXT): {$(VPATH)}transcode.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h \ {$(VPATH)}encoding.h {$(VPATH)}oniguruma.h {$(VPATH)}transcode_data.h cont.$(OBJEXT): {$(VPATH)}cont.c $(RUBY_H_INCLUDES) \ - {$(VPATH)}st.h {$(VPATH)}vm_core.h {$(VPATH)}signal.h {$(VPATH)}node.h \ + {$(VPATH)}st.h $(VM_CORE_H_INCLUDES) {$(VPATH)}signal.h {$(VPATH)}node.h \ {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}gc.h \ {$(VPATH)}eval_intern.h {$(VPATH)}util.h {$(VPATH)}dln.h @@ -580,17 +585,17 @@ util.$(OBJEXT): {$(VPATH)}util.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}util.h variable.$(OBJEXT): {$(VPATH)}variable.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h \ - {$(VPATH)}node.h {$(VPATH)}util.h + {$(VPATH)}node.h {$(VPATH)}util.h $(VM_CORE_H_INCLUDES) version.$(OBJEXT): {$(VPATH)}version.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h \ {$(VPATH)}version.h $(srcdir)/revision.h compile.$(OBJEXT): {$(VPATH)}compile.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h \ - {$(VPATH)}node.h {$(VPATH)}vm_core.h \ + {$(VPATH)}node.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}signal.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}compile.h \ {$(VPATH)}insns.inc {$(VPATH)}insns_info.inc {$(VPATH)}optinsn.inc iseq.$(OBJEXT): {$(VPATH)}iseq.c $(RUBY_H_INCLUDES) \ - {$(VPATH)}st.h {$(VPATH)}node.h {$(VPATH)}gc.h {$(VPATH)}vm_core.h \ + {$(VPATH)}st.h {$(VPATH)}node.h {$(VPATH)}gc.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}signal.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}insns.inc \ {$(VPATH)}insns_info.inc {$(VPATH)}node_name.inc @@ -598,36 +603,36 @@ {$(VPATH)}st.h {$(VPATH)}node.h {$(VPATH)}encoding.h \ {$(VPATH)}oniguruma.h {$(VPATH)}gc.h {$(VPATH)}insnhelper.h \ {$(VPATH)}eval_intern.h {$(VPATH)}util.h {$(VPATH)}signal.h \ - {$(VPATH)}vm_core.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ + $(VM_CORE_H_INCLUDES) {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}dln.h {$(VPATH)}vm.h \ {$(VPATH)}vm_insnhelper.c {$(VPATH)}insns.inc {$(VPATH)}vm_evalbody.c \ {$(VPATH)}vmtc.inc {$(VPATH)}vm.inc {$(VPATH)}insns.def \ {$(VPATH)}vm_method.c {$(VPATH)}vm_eval.c vm_dump.$(OBJEXT): {$(VPATH)}vm_dump.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h \ - {$(VPATH)}node.h {$(VPATH)}vm_core.h \ + {$(VPATH)}node.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}signal.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h {$(VPATH)}vm.h debug.$(OBJEXT): {$(VPATH)}debug.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}encoding.h {$(VPATH)}oniguruma.h \ - {$(VPATH)}debug.h {$(VPATH)}node.h {$(VPATH)}vm_core.h \ + {$(VPATH)}debug.h {$(VPATH)}node.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}signal.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h blockinlining.$(OBJEXT): {$(VPATH)}blockinlining.c $(RUBY_H_INCLUDES) \ - {$(VPATH)}st.h {$(VPATH)}node.h {$(VPATH)}vm_core.h \ + {$(VPATH)}st.h {$(VPATH)}node.h $(VM_CORE_H_INCLUDES) \ {$(VPATH)}signal.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h id.$(OBJEXT): {$(VPATH)}id.c $(RUBY_H_INCLUDES) \ {$(VPATH)}st.h {$(VPATH)}id.h miniprelude.$(OBJEXT): {$(VPATH)}miniprelude.c $(RUBY_H_INCLUDES) \ - {$(VPATH)}st.h {$(VPATH)}vm_core.h {$(VPATH)}signal.h \ + {$(VPATH)}st.h $(VM_CORE_H_INCLUDES) {$(VPATH)}signal.h \ {$(VPATH)}node.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h prelude.$(OBJEXT): {$(VPATH)}prelude.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h \ - {$(VPATH)}vm_core.h {$(VPATH)}signal.h \ + $(VM_CORE_H_INCLUDES) {$(VPATH)}signal.h \ {$(VPATH)}node.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h golf_prelude.$(OBJEXT): {$(VPATH)}golf_prelude.c $(RUBY_H_INCLUDES) \ - {$(VPATH)}st.h {$(VPATH)}vm_core.h {$(VPATH)}signal.h \ + {$(VPATH)}st.h $(VM_CORE_H_INCLUDES) {$(VPATH)}signal.h \ {$(VPATH)}node.h {$(VPATH)}debug.h {$(VPATH)}vm_opts.h {$(VPATH)}id.h \ {$(VPATH)}thread_$(THREAD_MODEL).h goruby.$(OBJEXT): {$(VPATH)}goruby.c {$(VPATH)}main.c $(RUBY_H_INCLUDES) {$(VPATH)}st.h Index: mvm/dir.c =================================================================== --- mvm/dir.c (revision 17908) +++ mvm/dir.c (revision 17909) @@ -338,8 +338,6 @@ return fnmatch_helper(&p, &s, flags); } -VALUE rb_cDir; - struct dir_data { DIR *dir; char *path; Index: mvm/win32/Makefile.sub =================================================================== --- mvm/win32/Makefile.sub (revision 17908) +++ mvm/win32/Makefile.sub (revision 17909) @@ -451,6 +451,7 @@ !if "$(PROCESSOR_ARCHITECTURE)" == "x86" || "$(ARCH)" == "x64" || "$(ARCH)" == "ia64" #define STACK_GROW_DIRECTION -1 !endif +#define THREAD_SPECIFIC __declspec(thread) #define DEFAULT_KCODE KCODE_NONE #define DLEXT ".so" #define RUBY_LIB "/lib/ruby/$(MAJOR).$(MINOR).$(TEENY)" Index: mvm/eval_jump.c =================================================================== --- mvm/eval_jump.c (revision 17908) +++ mvm/eval_jump.c (revision 17909) @@ -54,8 +54,6 @@ struct end_proc_data *next; }; -static struct end_proc_data *end_procs, *ephemeral_end_procs, *tmp_end_procs; - void rb_set_end_proc(void (*func)(VALUE), VALUE data) { @@ -64,10 +62,10 @@ rb_thread_t *th = GET_THREAD(); if (th->top_wrapper) { - list = &ephemeral_end_procs; + list = th->vm->end_procs + end_proc_ephemeral; } else { - list = &end_procs; + list = th->vm->end_procs + end_proc_ordinary; } link->next = *list; link->func = func; @@ -77,70 +75,48 @@ } void -rb_mark_end_proc(void) +rb_mark_end_proc(struct end_proc_data **endp) { struct end_proc_data *link; + int i; - link = end_procs; - while (link) { - rb_gc_mark(link->data); - link = link->next; + for (i = 0; i < end_proc_count; ++i) { + link = endp[i]; + while (link) { + rb_gc_mark(link->data); + link = link->next; + } } - link = ephemeral_end_procs; - while (link) { - rb_gc_mark(link->data); - link = link->next; - } - link = tmp_end_procs; - while (link) { - rb_gc_mark(link->data); - link = link->next; - } } void -rb_exec_end_proc(void) +rb_exec_end_proc(struct end_proc_data **end_procs) { struct end_proc_data *link, *tmp; - int status; + int status, i; volatile int safe = rb_safe_level(); - while (ephemeral_end_procs) { - tmp_end_procs = link = ephemeral_end_procs; - ephemeral_end_procs = 0; - while (link) { - PUSH_TAG(); - if ((status = EXEC_TAG()) == 0) { - rb_set_safe_level_force(link->safe); - (*link->func) (link->data); + i = end_proc_ephemeral; + do { + while ((link = end_procs[i]) != 0) { + end_procs[i] = 0; + end_procs[end_proc_temporary] = link; + while (link) { + PUSH_TAG(); + if ((status = EXEC_TAG()) == 0) { + rb_set_safe_level_force(link->safe); + (*link->func) (link->data); + } + POP_TAG(); + if (status) { + error_handle(status); + } + tmp = link; + end_procs[end_proc_temporary] = link = link->next; + xfree(tmp); } - POP_TAG(); - if (status) { - error_handle(status); - } - tmp = link; - tmp_end_procs = link = link->next; - xfree(tmp); } - } - while (end_procs) { - tmp_end_procs = link = end_procs; - end_procs = 0; - while (link) { - PUSH_TAG(); - if ((status = EXEC_TAG()) == 0) { - rb_set_safe_level_force(link->safe); - (*link->func) (link->data); - } - POP_TAG(); - if (status) { - error_handle(status); - } - tmp = link; - tmp_end_procs = link = link->next; - xfree(tmp); - } - } + } while (i-- > end_proc_ordinary); rb_set_safe_level_force(safe); } Index: mvm/struct.c =================================================================== --- mvm/struct.c (revision 17908) +++ mvm/struct.c (revision 17909) @@ -11,8 +11,6 @@ #include "ruby/ruby.h" -VALUE rb_cStruct; - static VALUE struct_alloc(VALUE); VALUE Index: mvm/eval.c =================================================================== --- mvm/eval.c (revision 17908) +++ mvm/eval.c (revision 17909) @@ -18,10 +18,8 @@ NORETURN(void rb_raise_jump(VALUE)); ID rb_frame_callee(void); -VALUE rb_eLocalJumpError; -VALUE rb_eSysStackError; -#define exception_error GET_VM()->special_exceptions[ruby_error_reenter] +#define exception_error rb_errReenterError #include "eval_error.c" #include "eval_safe.c" @@ -123,7 +121,7 @@ rb_trap_exit(); } POP_TAG(); - rb_exec_end_proc(); + rb_exec_end_proc(vm->end_procs); rb_clear_trace_func(); } @@ -621,8 +619,6 @@ } } -VALUE rb_eThreadError; - void rb_need_block() { @@ -1177,9 +1173,6 @@ void Init_eval(void) { - /* TODO: fix position */ - GET_THREAD()->vm->mark_object_ary = rb_ary_new(); - rb_define_virtual_variable("$@", errat_getter, errat_setter); rb_define_virtual_variable("$!", errinfo_getter, 0); Index: mvm/gc.c =================================================================== --- mvm/gc.c (revision 17908) +++ mvm/gc.c (revision 17909) @@ -84,7 +84,7 @@ #endif #endif -#define nomem_error GET_VM()->special_exceptions[ruby_error_nomemory] +#define nomem_error rb_errNoMemError #define MARK_STACK_MAX 1024 @@ -243,8 +243,6 @@ #define HEAP_OBJ_LIMIT (HEAP_SIZE / sizeof(struct RVALUE)) -extern st_table *rb_class_tbl; - int ruby_disable_gc_stress = 0; static void run_final(rb_objspace_t *objspace, VALUE obj); @@ -494,8 +492,6 @@ return old; } -VALUE rb_mGC; - void rb_register_mark_object(VALUE obj) { @@ -1715,10 +1711,7 @@ for (list = global_List; list; list = list->next) { rb_gc_mark_maybe(*list->varptr); } - rb_mark_end_proc(); - rb_gc_mark_global_tbl(); - mark_tbl(objspace, rb_class_tbl, 0); rb_gc_mark_trap_list(); /* mark generic instance variables for special constants */ Index: mvm/class.c =================================================================== --- mvm/class.c (revision 17908) +++ mvm/class.c (revision 17909) @@ -15,8 +15,6 @@ #include "ruby/st.h" #include <ctype.h> -extern st_table *rb_class_tbl; - static VALUE class_alloc(VALUE flags, VALUE klass) { @@ -243,7 +241,7 @@ rb_warn("no super class for `%s', Object assumed", name); } klass = rb_define_class_id(id, super); - st_add_direct(rb_class_tbl, id, klass); + rb_register_mark_object(klass); rb_name_class(klass, id); rb_const_set(rb_cObject, id, klass); rb_class_inherited(super, klass); @@ -315,7 +313,7 @@ rb_raise(rb_eTypeError, "%s is not a module", rb_obj_classname(module)); } module = rb_define_module_id(id); - st_add_direct(rb_class_tbl, id, module); + rb_register_mark_object(module); rb_const_set(rb_cObject, id, module); return module; Index: mvm/dln.c =================================================================== --- mvm/dln.c (revision 17908) +++ mvm/dln.c (revision 17909) @@ -1601,6 +1601,7 @@ #endif } +#ifndef HAVE_MVM static char fbuf[MAXPATHLEN]; char * @@ -1614,6 +1615,7 @@ { return dln_find_file_r(fname, path, fbuf, sizeof(fbuf)); } +#endif static char * dln_find_1(const char *fname, const char *path, char *fbuf, int size, Index: mvm/process.c =================================================================== --- mvm/process.c (revision 17908) +++ mvm/process.c (revision 17909) @@ -73,10 +73,6 @@ #include <grp.h> #endif -#if defined(HAVE_TIMES) || defined(_WIN32) -static VALUE rb_cProcessTms; -#endif - #ifndef WIFEXITED #define WIFEXITED(w) (((w) & 0xff) == 0) #endif @@ -213,8 +209,6 @@ * _stat_, we're referring to this 16 bit value. */ -static VALUE rb_cProcessStatus; - VALUE rb_last_status_get(void) { @@ -5060,12 +5054,7 @@ #endif } -VALUE rb_mProcess; -VALUE rb_mProcUID; -VALUE rb_mProcGID; -VALUE rb_mProcID_Syscall; - /* * The <code>Process</code> module is a collection of methods used to * manipulate processes. @@ -5074,6 +5063,10 @@ void Init_process(void) { + VALUE rb_mProcUID; + VALUE rb_mProcGID; + VALUE rb_mProcID_Syscall; + rb_define_virtual_variable("$?", rb_last_status_get, 0); rb_define_virtual_variable("$$", get_pid, 0); rb_define_global_function("exec", rb_f_exec, -1); Index: mvm/hash.c =================================================================== --- mvm/hash.c (revision 17908) +++ mvm/hash.c (revision 17909) @@ -31,8 +31,6 @@ return rb_obj_freeze(hash); } -VALUE rb_cHash; - static VALUE envtbl; static ID id_hash, id_yield, id_default; Index: mvm/prec.c =================================================================== --- mvm/prec.c (revision 17908) +++ mvm/prec.c (revision 17909) @@ -11,8 +11,6 @@ #include "ruby/ruby.h" -VALUE rb_mPrecision; - static ID prc_pr, prc_if; Index: mvm/error.c =================================================================== --- mvm/error.c (revision 17908) +++ mvm/error.c (revision 17909) @@ -310,33 +310,6 @@ /* exception classes */ #include <errno.h> -VALUE rb_eException; -VALUE rb_eSystemExit; -VALUE rb_eInterrupt; -VALUE rb_eSignal; -VALUE rb_eFatal; -VALUE rb_eStandardError; -VALUE rb_eRuntimeError; -VALUE rb_eTypeError; -VALUE rb_eArgError; -VALUE rb_eIndexError; -VALUE rb_eKeyError; -VALUE rb_eRangeError; -VALUE rb_eNameError; -VALUE rb_eNoMethodError; -VALUE rb_eSecurityError; -VALUE rb_eNotImpError; -VALUE rb_eNoMemError; -VALUE rb_cNameErrorMesg; - -VALUE rb_eScriptError; -VALUE rb_eSyntaxError; -VALUE rb_eLoadError; - -VALUE rb_eSystemCallError; -VALUE rb_mErrno; -static VALUE rb_eNOERROR; - VALUE rb_exc_new(VALUE etype, const char *ptr, long len) { @@ -852,12 +825,11 @@ * Errno.constants #=> :E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, ... */ -static st_table *syserr_tbl; - static VALUE set_syserr(int n, const char *name) { VALUE error; + st_table *syserr_tbl = DATA_PTR(rb_syserr_tbl); if (!st_lookup(syserr_tbl, n, &error)) { error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError); @@ -874,6 +846,7 @@ get_syserr(int n) { VALUE error; + st_table *syserr_tbl = DATA_PTR(rb_syserr_tbl); if (!st_lookup(syserr_tbl, n, &error)) { char name[8]; /* some Windows' errno have 5 digits. */ @@ -906,6 +879,7 @@ VALUE klass = rb_obj_class(self); if (klass == rb_eSystemCallError) { + st_table *syserr_tbl = DATA_PTR(rb_syserr_tbl); rb_scan_args(argc, argv, "11", &mesg, &error); if (argc == 1 && FIXNUM_P(mesg)) { error = mesg; mesg = Qnil; @@ -1058,7 +1032,7 @@ rb_eSecurityError = rb_define_class("SecurityError", rb_eException); rb_eNoMemError = rb_define_class("NoMemoryError", rb_eException); - syserr_tbl = st_init_numtable(); + rb_syserr_tbl = rb_wrap_st_table(st_init_numtable()); rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError); rb_define_method(rb_eSystemCallError, "initialize", syserr_initialize, -1); rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0); Index: mvm/numeric.c =================================================================== --- mvm/numeric.c (revision 17908) +++ mvm/numeric.c (revision 17909) @@ -82,14 +82,6 @@ static ID id_coerce, id_to_i, id_eq; -VALUE rb_cNumeric; -VALUE rb_cFloat; -VALUE rb_cInteger; -VALUE rb_cFixnum; - -VALUE rb_eZeroDivError; -VALUE rb_eFloatDomainError; - void rb_num_zerodiv(void) { Index: mvm/cont.c =================================================================== --- mvm/cont.c (revision 17908) +++ mvm/cont.c (revision 17909) @@ -39,10 +39,6 @@ enum context_type type; } rb_context_t; -static VALUE rb_cContinuation; -static VALUE rb_cFiber; -static VALUE rb_eFiberError; - #define GetContPtr(obj, ptr) \ Data_Get_Struct(obj, rb_context_t, ptr) Index: mvm/compar.c =================================================================== --- mvm/compar.c (revision 17908) +++ mvm/compar.c (revision 17909) @@ -11,8 +11,6 @@ #include "ruby/ruby.h" -VALUE rb_mComparable; - static ID cmp; void Index: mvm/vm.c =================================================================== --- mvm/vm.c (revision 17908) +++ mvm/vm.c (revision 17909) @@ -21,15 +21,10 @@ #define BUFSIZE 0x100 #define PROCDEBUG 0 -VALUE rb_cRubyVM; -VALUE rb_cThread; -VALUE rb_cEnv; -VALUE rb_mRubyVMFrozenCore; +#ifdef THREAD_SPECIFIC +THREAD_SPECIFIC rb_thread_t *ruby_current_thread = 0; +#endif -VALUE ruby_vm_global_state_version = 1; -rb_thread_t *ruby_current_thread = 0; -rb_vm_t *ruby_current_vm = 0; - void vm_analysis_operand(int insn, int n, VALUE op); void vm_analysis_register(int reg, int isset); void vm_analysis_insn(int insn); @@ -784,7 +779,6 @@ static VALUE make_localjump_error(const char *mesg, VALUE value, int reason) { - extern VALUE rb_eLocalJumpError; VALUE exc = rb_exc_new2(rb_eLocalJumpError, mesg); ID id; @@ -883,8 +877,7 @@ /* optimization: redefine management */ -VALUE ruby_vm_redefined_flag = 0; -static st_table *vm_opt_method_table = 0; +#define vm_opt_method_table GET_VM()->opt_method_table static void rb_vm_check_redefinition_opt_method(const NODE *node) @@ -910,12 +903,12 @@ } static void -vm_init_redefined_flag(void) +vm_init_redefined_flag(rb_vm_t *vm) { ID mid; VALUE bop; - vm_opt_method_table = st_init_numtable(); + vm->opt_method_table = st_init_numtable(); #define OP(mid_, bop_) (mid = id##mid_, bop = BOP_##bop_) #define C(k) add_opt_method(rb_c##k, mid, bop) @@ -1395,13 +1388,15 @@ RUBY_MARK_UNLESS_NULL(vm->load_path); RUBY_MARK_UNLESS_NULL(vm->loaded_features); RUBY_MARK_UNLESS_NULL(vm->top_self); - RUBY_MARK_UNLESS_NULL(vm->coverages); - rb_gc_mark_locations(vm->special_exceptions, vm->special_exceptions + ruby_special_error_count - 1); + rb_gc_mark_locations(vm->specific_storage.ptr, vm->specific_storage.ptr + vm->specific_storage.len - 1); if (vm->loading_table) { rb_mark_tbl(vm->loading_table); } + rb_vm_mark_global_tbl(vm->global_tbl); + rb_mark_end_proc(vm->end_procs); + mark_event_hooks(vm->event_hooks); } @@ -1413,6 +1408,9 @@ { MEMZERO(vm, rb_vm_t, 1); vm->src_encoding_index = -1; + vm->global_state_version = 1; + vm->specific_storage.len = rb_vm_key_count(); + vm->specific_storage.ptr = calloc(vm->specific_storage.len, sizeof(VALUE)); } /* Thread */ @@ -1693,11 +1691,6 @@ } VALUE insns_name_array(void); -extern VALUE *rb_gc_stack_start; -extern size_t rb_gc_stack_maxsize; -#ifdef __ia64 -extern VALUE *rb_gc_register_stack_start; -#endif /* debug functions */ @@ -1736,20 +1729,21 @@ Init_VM(void) { VALUE opts; + VALUE core; /* ::VM */ rb_cRubyVM = rb_define_class("RubyVM", rb_cObject); rb_undef_alloc_func(rb_cRubyVM); /* ::VM::FrozenCore */ - rb_mRubyVMFrozenCore = rb_define_module_under(rb_cRubyVM, "FrozenCore"); - rb_define_singleton_method(rb_mRubyVMFrozenCore, "core_set_method_alias", m_core_set_method_alias, 3); - rb_define_singleton_method(rb_mRubyVMFrozenCore, "core_set_variable_alias", m_core_set_variable_alias, 2); - rb_define_singleton_method(rb_mRubyVMFrozenCore, "core_undef_method", m_core_undef_method, 2); - rb_define_singleton_method(rb_mRubyVMFrozenCore, "core_define_method", m_core_define_method, 3); - rb_define_singleton_method(rb_mRubyVMFrozenCore, "core_define_singleton_method", m_core_define_singleton_method, 3); - rb_define_singleton_method(rb_mRubyVMFrozenCore, "core_set_postexe", m_core_set_postexe, 1); - rb_obj_freeze(rb_mRubyVMFrozenCore); + rb_mRubyVMFrozenCore = core = rb_define_module_under(rb_cRubyVM, "FrozenCore"); + rb_define_singleton_method(core, "core_set_method_alias", m_core_set_method_alias, 3); + rb_define_singleton_method(core, "core_set_variable_alias", m_core_set_variable_alias, 2); + rb_define_singleton_method(core, "core_undef_method", m_core_undef_method, 2); + rb_define_singleton_method(core, "core_define_method", m_core_define_method, 3); + rb_define_singleton_method(core, "core_define_singleton_method", m_core_define_singleton_method, 3); + rb_define_singleton_method(core, "core_set_postexe", m_core_set_postexe, 1); + rb_obj_freeze(core); /* ::VM::Env */ rb_cEnv = rb_define_class_under(rb_cRubyVM, "Env", rb_cObject); @@ -1807,8 +1801,8 @@ /* VM bootstrap: phase 2 */ { - rb_vm_t *vm = ruby_current_vm; rb_thread_t *th = GET_THREAD(); + rb_vm_t *vm = th->vm; VALUE filename = rb_str_new2("<dummy toplevel>"); volatile VALUE iseqval = rb_iseq_new(0, filename, filename, 0, ISEQ_TYPE_TOP); volatile VALUE th_self; @@ -1833,8 +1827,8 @@ GetISeqPtr(iseqval, iseq); th->cfp->iseq = iseq; th->cfp->pc = iseq->iseq_encoded; + vm_init_redefined_flag(vm); } - vm_init_redefined_flag(); } #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE @@ -1856,10 +1850,9 @@ #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE vm->objspace = rb_objspace_alloc(); #endif - ruby_current_vm = vm; - th_init2(th, 0); th->vm = vm; + th_init2(th, 0); ruby_thread_init_stack(th); } @@ -1896,13 +1889,13 @@ VALUE * ruby_vm_verbose_ptr(rb_vm_t *vm) { - return &vm->verbose; + return ruby_vm_specific_ptr(vm, rb_vmkey_verbose); } VALUE * ruby_vm_debug_ptr(rb_vm_t *vm) { - return &vm->debug; + return ruby_vm_specific_ptr(vm, rb_vmkey_debug); } VALUE * @@ -1920,5 +1913,5 @@ VALUE rb_vm_get_coverages(void) { - return GET_VM()->coverages; + return *rb_vm_specific_ptr(rb_vmkey_coverages); } Index: mvm/vm.h =================================================================== --- mvm/vm.h (revision 17908) +++ mvm/vm.h (revision 17909) @@ -18,9 +18,8 @@ typedef rb_num_t GENTRY; typedef rb_iseq_t *ISEQ; -extern VALUE rb_cEnv; -extern VALUE ruby_vm_global_state_version; -extern VALUE ruby_vm_redefined_flag; +#define ruby_vm_global_state_version (GET_VM()->global_state_version) +#define ruby_vm_redefined_flag (GET_VM()->redefined_flag) /** Index: mvm/ruby.c =================================================================== --- mvm/ruby.c (revision 17908) +++ mvm/ruby.c (revision 17909) @@ -629,8 +629,8 @@ goto reswitch; case 'd': - vm->debug = Qtrue; - vm->verbose = Qtrue; + *ruby_vm_specific_ptr(vm, rb_vmkey_debug) = Qtrue; + *ruby_vm_specific_ptr(vm, rb_vmkey_verbose) = Qtrue; s++; goto reswitch; @@ -647,7 +647,7 @@ ruby_show_version(); opt->verbose = 1; case 'w': - vm->verbose = Qtrue; + *ruby_vm_specific_ptr(vm, rb_vmkey_verbose) = Qtrue; s++; goto reswitch; @@ -664,13 +664,13 @@ } switch (v) { case 0: - vm->verbose = Qnil; + *ruby_vm_specific_ptr(vm, rb_vmkey_verbose) = Qnil; break; case 1: - vm->verbose = Qfalse; + *ruby_vm_specific_ptr(vm, rb_vmkey_verbose) = Qfalse; break; default: - vm->verbose = Qtrue; + *ruby_vm_specific_ptr(vm, rb_vmkey_verbose) = Qtrue; break; } } @@ -850,8 +850,8 @@ if (strcmp("copyright", s) == 0) opt->copyright = 1; else if (strcmp("debug", s) == 0) { - vm->debug = Qtrue; - vm->verbose = Qtrue; + *ruby_vm_specific_ptr(vm, rb_vmkey_debug) = Qtrue; + *ruby_vm_specific_ptr(vm, rb_vmkey_verbose) = Qtrue; } else if (strncmp("enable", s, n = 6) == 0 && (!s[n] || s[n] == '-' || s[n] == '=')) { @@ -882,7 +882,7 @@ opt->version = 1; else if (strcmp("verbose", s) == 0) { opt->verbose = 1; - vm->verbose = Qtrue; + *ruby_vm_specific_ptr(vm, rb_vmkey_verbose) = Qtrue; } else if (strcmp("yydebug", s) == 0) opt->yydebug = 1; @@ -952,7 +952,7 @@ return i; } -#define rb_progname (vm->progname) +#define rb_progname (*ruby_vm_specific_ptr(vm, rb_vmkey_progname)) VALUE rb_argv0; static VALUE @@ -1064,9 +1064,9 @@ ruby_script(opt->script); #if defined DOSISH || defined __CYGWIN__ - translate_char(RSTRING_PTR(vm->progname), '\\', '/'); + translate_char(RSTRING_PTR(*ruby_vm_specific_ptr(vm, rb_vmkey_progname)), '\\', '/'); #endif - opt->script_name = rb_str_new4(vm->progname); + opt->script_name = rb_str_new4(*ruby_vm_specific_ptr(vm, rb_vmkey_progname)); opt->script = RSTRING_PTR(opt->script_name); ruby_vm_set_argv(vm, argc, argv); process_sflag(vm, opt); @@ -1153,7 +1153,6 @@ static NODE * load_file(rb_vm_t *vm, VALUE parser, const char *fname, int script, struct cmdline_options *opt) { - extern VALUE rb_stdin; VALUE f; int line_start = 1; NODE *tree = 0; @@ -1396,7 +1395,7 @@ } } #endif - *var = rb_obj_freeze(rb_tainted_str_new(s, i)); + *rb_vm_specific_ptr((int)var) = rb_obj_freeze(rb_tainted_str_new(s, i)); } DEPRECATED(void ruby_script(const char *name)); @@ -1404,7 +1403,7 @@ ruby_script(const char *name) { if (name) { - GET_VM()->progname = rb_obj_freeze(rb_tainted_str_new2(name)); + *rb_vm_specific_ptr(rb_vmkey_progname) = rb_obj_freeze(rb_tainted_str_new2(name)); } } @@ -1464,15 +1463,15 @@ void ruby_vm_prog_init(rb_vm_t *vm) { - rb_define_hooked_variable("$VERBOSE", &vm->verbose, 0, verbose_setter); - rb_define_hooked_variable("$-v", &vm->verbose, 0, verbose_setter); - rb_define_hooked_variable("$-w", &vm->verbose, 0, verbose_setter); - rb_define_hooked_variable("$-W", &vm->verbose, opt_W_getter, 0); - rb_define_variable("$DEBUG", &vm->debug); - rb_define_variable("$-d", &vm->debug); + rb_define_vm_specific_variable("$VERBOSE", rb_vmkey_verbose, 0, verbose_setter); + rb_define_vm_specific_variable("$-v", rb_vmkey_verbose, 0, verbose_setter); + rb_define_vm_specific_variable("$-w", rb_vmkey_verbose, 0, verbose_setter); + rb_define_vm_specific_variable("$-W", rb_vmkey_verbose, opt_W_getter, 0); + rb_define_vm_specific_variable("$DEBUG", rb_vmkey_debug, 0, 0); + rb_define_vm_specific_variable("$-d", rb_vmkey_debug, 0, 0); - rb_define_hooked_variable("$0", &vm->progname, 0, set_arg0); - rb_define_hooked_variable("$PROGRAM_NAME", &vm->progname, 0, set_arg0); + rb_define_vm_specific_variable("$0", rb_vmkey_progname, 0, set_arg0); + rb_define_vm_specific_variable("$PROGRAM_NAME", rb_vmkey_progname, 0, set_arg0); rb_define_global_const("ARGV", rb_argv); } @@ -1542,7 +1541,7 @@ NODE *tree; if (argv[0]) { /* for the time being */ - vm->progname = rb_tainted_str_new2(argv[0]); + *ruby_vm_specific_ptr(vm, rb_vmkey_progname) = rb_tainted_str_new2(argv[0]); } args.vm = vm; args.argc = argc; @@ -1551,7 +1550,7 @@ opt.ext.enc.index = -1; tree = (NODE *)rb_vm_call_cfunc(vm->top_self, process_options, (VALUE)&args, - 0, vm->progname); + 0, *ruby_vm_specific_ptr(vm, rb_vmkey_progname)); rb_define_readonly_boolean("$-p", opt.do_print); rb_define_readonly_boolean("$-l", opt.do_line); @@ -1564,7 +1563,7 @@ { rb_vm_t *vm = GET_VM(); VALUE result = ruby_vm_process_options(vm, argc, argv); - rb_argv0 = rb_str_new4(vm->progname); + rb_argv0 = rb_str_new4(*ruby_vm_specific_ptr(vm, rb_vmkey_progname)); return (void *)result; } Index: mvm/bignum.c =================================================================== --- mvm/bignum.c (revision 17908) +++ mvm/bignum.c (revision 17909) @@ -18,8 +18,6 @@ #include <ieeefp.h> #endif -VALUE rb_cBignum; - #if defined __MINGW32__ #define USHORT _USHORT #endif Index: mvm/marshal.c =================================================================== --- mvm/marshal.c (revision 17908) +++ mvm/marshal.c (revision 17909) @@ -14,6 +14,7 @@ #include "ruby/st.h" #include "ruby/util.h" #include "ruby/encoding.h" +#include "private_object.h" #include <math.h> #ifdef HAVE_FLOAT_H @@ -91,9 +92,6 @@ VALUE (*loader)(VALUE, VALUE); } marshal_compat_t; -static st_table *compat_allocator_tbl; -static VALUE compat_allocator_tbl_wrapper; - static int mark_marshal_compat_i(st_data_t key, st_data_t value) { @@ -115,6 +113,7 @@ { marshal_compat_t *compat; rb_alloc_func_t allocator = rb_get_alloc_func(newclass); + st_table *compat_allocator_tbl = DATA_PTR(rb_compat_allocator_tbl); if (!allocator) { rb_raise(rb_eTypeError, "no allocator"); @@ -140,6 +139,7 @@ st_table *compat_tbl; VALUE wrapper; st_table *encodings; + st_table *compat_allocator_tbl; }; struct dump_call_arg { @@ -624,7 +624,7 @@ { st_data_t compat_data; rb_alloc_func_t allocator = rb_get_alloc_func(RBASIC(obj)->klass); - if (st_lookup(compat_allocator_tbl, + if (st_lookup(arg->compat_allocator_tbl, (st_data_t)allocator, &compat_data)) { marshal_compat_t *compat = (marshal_compat_t*)compat_data; @@ -880,6 +880,7 @@ arg.compat_tbl = st_init_numtable(); arg.wrapper = Data_Wrap_Struct(rb_cData, mark_dump_arg, 0, &arg); arg.encodings = 0; + arg.compat_allocator_tbl = DATA_PTR(rb_compat_allocator_tbl); c_arg.obj = obj; c_arg.arg = &arg; c_arg.limit = limit; @@ -899,6 +900,7 @@ VALUE data; VALUE proc; int taint; + st_table *compat_allocator_tbl; st_table *compat_tbl; VALUE compat_tbl_wrapper; }; @@ -1094,7 +1096,7 @@ VALUE real_obj = (VALUE)data; rb_alloc_func_t allocator = rb_get_alloc_func(CLASS_OF(real_obj)); st_data_t key = v; - if (st_lookup(compat_allocator_tbl, (st_data_t)allocator, &data)) { + if (st_lookup(arg->compat_allocator_tbl, (st_data_t)allocator, &data)) { marshal_compat_t *compat = (marshal_compat_t*)data; compat->loader(real_obj, v); } @@ -1161,7 +1163,7 @@ klass = path2class(path); allocator = rb_get_alloc_func(klass); - if (st_lookup(compat_allocator_tbl, (st_data_t)allocator, &data)) { + if (st_lookup(arg->compat_allocator_tbl, (st_data_t)allocator, &data)) { marshal_compat_t *compat = (marshal_compat_t*)data; VALUE real_obj = rb_obj_alloc(klass); VALUE obj = rb_obj_alloc(compat->oldclass); @@ -1612,6 +1614,7 @@ arg.offset = 0; arg.compat_tbl = st_init_numtable(); arg.compat_tbl_wrapper = Data_Wrap_Struct(rb_cData, rb_mark_tbl, 0, arg.compat_tbl); + arg.compat_allocator_tbl = DATA_PTR(rb_compat_allocator_tbl); major = r_byte(&arg); minor = r_byte(&arg); @@ -1695,10 +1698,8 @@ rb_define_const(rb_mMarshal, "MAJOR_VERSION", INT2FIX(MARSHAL_MAJOR)); rb_define_const(rb_mMarshal, "MINOR_VERSION", INT2FIX(MARSHAL_MINOR)); - compat_allocator_tbl = st_init_numtable(); - rb_gc_register_address(&compat_allocator_tbl_wrapper); - compat_allocator_tbl_wrapper = - Data_Wrap_Struct(rb_cData, mark_marshal_compat_t, 0, compat_allocator_tbl); + rb_compat_allocator_tbl = + Data_Wrap_Struct(rb_cData, mark_marshal_compat_t, 0, st_init_numtable()); } VALUE Index: mvm/rational.c =================================================================== --- mvm/rational.c (revision 17908) +++ mvm/rational.c (revision 17909) @@ -24,8 +24,6 @@ #define ONE INT2FIX(1) #define TWO INT2FIX(2) -VALUE rb_cRational; - static ID id_Unify, id_abs, id_cmp, id_convert, id_equal_p, id_expt, id_floor, id_format, id_idiv, id_inspect, id_negate, id_new, id_new_bang, id_to_f, id_to_i, id_to_s, id_truncate; Index: mvm/file.c =================================================================== --- mvm/file.c (revision 17908) +++ mvm/file.c (revision 17909) @@ -24,6 +24,7 @@ #include "ruby/signal.h" #include "ruby/util.h" #include "dln.h" +#include "private_object.h" #ifdef HAVE_UNISTD_H #include <unistd.h> @@ -94,10 +95,6 @@ #define fchown be_fchown #endif /* __BEOS__ */ -VALUE rb_cFile; -VALUE rb_mFileTest; -VALUE rb_cStat; - static VALUE rb_get_path_check(VALUE obj, int check) { @@ -4328,8 +4325,6 @@ return Qfalse; } -VALUE rb_mFConst; - void rb_file_const(const char *name, VALUE value) { -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/