зеркало из https://github.com/github/ruby.git
* 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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43027 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
aaccbfeda1
Коммит
f088828106
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
Tue Sep 24 14:01:00 2013 Charlie Somerville <charliesome@ruby-lang.org>
|
||||
|
||||
* 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@ruby-lang.org>
|
||||
|
||||
* ext/win32/lib/win32/registry.rb (Win32::Registry::API): need
|
||||
|
|
1
class.c
1
class.c
|
@ -165,7 +165,6 @@ class_alloc(VALUE flags, VALUE klass)
|
|||
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;
|
||||
|
|
4
gc.c
4
gc.c
|
@ -1261,10 +1261,6 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
|
|||
}
|
||||
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)
|
||||
|
|
|
@ -266,7 +266,6 @@ struct rb_classext_struct {
|
|||
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;
|
||||
/**
|
||||
|
|
2
method.h
2
method.h
|
@ -122,7 +122,7 @@ rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id,
|
|||
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);
|
||||
|
|
45
vm_method.c
45
vm_method.c
|
@ -2,6 +2,10 @@
|
|||
* 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_method(const rb_method_entry_t *me, VAL
|
|||
#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)
|
|||
*/
|
||||
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, VALUE defined_class, rb_method_entry_t *
|
|||
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 *
|
|||
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, VALUE *defined_class_ptr)
|
|||
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 *
|
||||
|
|
Загрузка…
Ссылка в новой задаче