Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
* 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 ruby#8930]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43027 b2dd03c8-39d4-4d8f-98ff-823fe69b080e

Conflicts:
	ChangeLog
  • Loading branch information
Charlie Somerville committed Oct 23, 2013
commit d4aeb9f562a5cc3f81827cb43e72470fa5a521eb
1 change: 0 additions & 1 deletion class.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 0 additions & 4 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -964,10 +964,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)
Expand Down
1 change: 0 additions & 1 deletion internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,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;
/**
Expand Down
2 changes: 1 addition & 1 deletion method.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,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);
Expand Down
45 changes: 24 additions & 21 deletions vm_method.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -15,6 +19,15 @@ static ID object_id;
static ID removed, singleton_removed, undefined, singleton_undefined;
static ID added, singleton_added, 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; */

Expand Down Expand Up @@ -497,26 +510,25 @@ search_method(VALUE klass, ID id, VALUE *defined_class_ptr)
*/
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;
}
}

Expand All @@ -532,7 +544,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");
Expand All @@ -544,19 +556,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;
Expand All @@ -570,7 +573,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 *
Expand Down