ruby-changes:30948
From: charliesome <ko1@a...>
Date: Tue, 24 Sep 2013 14:02:20 +0900 (JST)
Subject: [ruby-changes:30948] charliesome:r43027 (trunk): * class.c (class_alloc): remove mc_tbl
charliesome 2013-09-24 14:02:13 +0900 (Tue, 24 Sep 2013) New Revision: 43027 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43027 Log: * class.c (class_alloc): remove mc_tbl * gc.c (obj_free): ditto * internal.h (struct rb_classext_struct): ditto * method.h (rb_method_entry): remove ent param * vm_method.c: restore the global method cache. Per class cache tables turned out to be far too slow. [ruby-core:57289] [Bug #8930] Modified files: trunk/ChangeLog trunk/class.c trunk/gc.c trunk/internal.h trunk/method.h trunk/vm_method.c Index: method.h =================================================================== --- method.h (revision 43026) +++ method.h (revision 43027) @@ -122,7 +122,7 @@ rb_method_entry_t *rb_method_entry_with_ https://github.com/ruby/ruby/blob/trunk/method.h#L122 rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr); -rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, ID id, VALUE *define_class_ptr, method_cache_entry_t *ent); +rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, ID id, VALUE *define_class_ptr); rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex); int rb_method_entry_arity(const rb_method_entry_t *me); Index: ChangeLog =================================================================== --- ChangeLog (revision 43026) +++ ChangeLog (revision 43027) @@ -1,3 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Sep 24 14:01:00 2013 Charlie Somerville <charliesome@r...> + + * class.c (class_alloc): remove mc_tbl + + * gc.c (obj_free): ditto + + * internal.h (struct rb_classext_struct): ditto + + * method.h (rb_method_entry): remove ent param + + * vm_method.c: restore the global method cache. Per class cache tables + turned out to be far too slow. + + [ruby-core:57289] [Bug #8930] + Tue Sep 24 12:51:07 2013 Nobuyoshi Nakada <nobu@r...> * ext/win32/lib/win32/registry.rb (Win32::Registry::API): need Index: vm_method.c =================================================================== --- vm_method.c (revision 43026) +++ vm_method.c (revision 43027) @@ -2,6 +2,10 @@ https://github.com/ruby/ruby/blob/trunk/vm_method.c#L2 * This file is included by vm.c */ +#define GLOBAL_METHOD_CACHE_SIZE 0x800 +#define GLOBAL_METHOD_CACHE_MASK 0x7ff +#define GLOBAL_METHOD_CACHE_KEY(c,m) ((((c)>>3)^(m))&GLOBAL_METHOD_CACHE_MASK) +#define GLOBAL_METHOD_CACHE(c,m) (global_method_cache + GLOBAL_METHOD_CACHE_KEY(c,m)) #include "method.h" #define NOEX_NOREDEF 0 @@ -20,6 +24,15 @@ static void rb_vm_check_redefinition_opt https://github.com/ruby/ruby/blob/trunk/vm_method.c#L24 #define singleton_undefined idSingleton_method_undefined #define attached id__attached__ +struct cache_entry { + vm_state_version_t vm_state; + vm_state_version_t seq; + ID mid; + rb_method_entry_t* me; + VALUE defined_class; +}; + +static struct cache_entry global_method_cache[GLOBAL_METHOD_CACHE_SIZE]; #define ruby_running (GET_VM()->running) /* int ruby_running = 0; */ @@ -520,26 +533,25 @@ rb_method_entry_at(VALUE klass, ID id) https://github.com/ruby/ruby/blob/trunk/vm_method.c#L533 */ rb_method_entry_t * rb_method_entry_get_without_cache(VALUE klass, ID id, - VALUE *defined_class_ptr, - method_cache_entry_t *ent) + VALUE *defined_class_ptr) { VALUE defined_class; rb_method_entry_t *me = search_method(klass, id, &defined_class); if (ruby_running) { + struct cache_entry *ent; + ent = GLOBAL_METHOD_CACHE(klass, id); ent->seq = RCLASS_EXT(klass)->seq; ent->vm_state = GET_VM_STATE_VERSION(); + ent->defined_class = defined_class; + ent->mid = id; if (UNDEFINED_METHOD_ENTRY_P(me)) { - ent->mid = id; ent->me = 0; - ent->defined_class = defined_class; me = 0; } else { - ent->mid = id; ent->me = me; - ent->defined_class = defined_class; } } @@ -555,7 +567,7 @@ verify_method_cache(VALUE klass, ID id, https://github.com/ruby/ruby/blob/trunk/vm_method.c#L567 VALUE actual_defined_class; method_cache_entry_t ent; rb_method_entry_t *actual_me = - rb_method_entry_get_without_cache(klass, id, &actual_defined_class, &ent); + rb_method_entry_get_without_cache(klass, id, &actual_defined_class); if (me != actual_me || defined_class != actual_defined_class) { rb_bug("method cache verification failed"); @@ -567,19 +579,10 @@ rb_method_entry_t * https://github.com/ruby/ruby/blob/trunk/vm_method.c#L579 rb_method_entry(VALUE klass, ID id, VALUE *defined_class_ptr) { #if OPT_GLOBAL_METHOD_CACHE - method_cache_entry_t *ent; - - if (RCLASS_EXT(klass)->mc_tbl == NULL) { - RCLASS_EXT(klass)->mc_tbl = st_init_numtable(); - } - - if (!st_lookup(RCLASS_EXT(klass)->mc_tbl, (st_index_t)id, (st_data_t *)&ent)) { - ent = calloc(1, sizeof(*ent)); - st_insert(RCLASS_EXT(klass)->mc_tbl, (st_index_t)id, (st_data_t)ent); - } - - if (ent->seq == RCLASS_EXT(klass)->seq && - ent->vm_state == GET_VM_STATE_VERSION() && + struct cache_entry *ent; + ent = GLOBAL_METHOD_CACHE(klass, id); + if (ent->vm_state == GET_VM_STATE_VERSION() && + ent->seq == RCLASS_EXT(klass)->seq && ent->mid == id) { if (defined_class_ptr) *defined_class_ptr = ent->defined_class; @@ -593,7 +596,7 @@ rb_method_entry(VALUE klass, ID id, VALU https://github.com/ruby/ruby/blob/trunk/vm_method.c#L596 method_cache_entry_t* ent = &ent_; #endif - return rb_method_entry_get_without_cache(klass, id, defined_class_ptr, ent); + return rb_method_entry_get_without_cache(klass, id, defined_class_ptr); } static rb_method_entry_t * Index: gc.c =================================================================== --- gc.c (revision 43026) +++ gc.c (revision 43027) @@ -1261,10 +1261,6 @@ obj_free(rb_objspace_t *objspace, VALUE https://github.com/ruby/ruby/blob/trunk/gc.c#L1261 } RCLASS_EXT(obj)->subclasses = NULL; } - if (RCLASS_EXT(obj)->mc_tbl) { - rb_free_mc_table(RCLASS_EXT(obj)->mc_tbl); - RCLASS_EXT(obj)->mc_tbl = NULL; - } rb_class_remove_from_module_subclasses(obj); rb_class_remove_from_super_subclasses(obj); if (RANY(obj)->as.klass.ptr) Index: class.c =================================================================== --- class.c (revision 43026) +++ class.c (revision 43027) @@ -165,7 +165,6 @@ class_alloc(VALUE flags, VALUE klass) https://github.com/ruby/ruby/blob/trunk/class.c#L165 RCLASS_EXT(obj)->parent_subclasses = NULL; RCLASS_EXT(obj)->module_subclasses = NULL; RCLASS_EXT(obj)->seq = rb_next_class_sequence(); - RCLASS_EXT(obj)->mc_tbl = NULL; RCLASS_REFINED_CLASS(obj) = Qnil; RCLASS_EXT(obj)->allocator = 0; Index: internal.h =================================================================== --- internal.h (revision 43026) +++ internal.h (revision 43027) @@ -266,7 +266,6 @@ struct rb_classext_struct { https://github.com/ruby/ruby/blob/trunk/internal.h#L266 VALUE super; struct st_table *iv_tbl; struct st_table *const_tbl; - struct st_table *mc_tbl; rb_subclass_entry_t *subclasses; rb_subclass_entry_t **parent_subclasses; /** -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/