summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-12-10 23:55:46 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-12-13 10:29:15 +0900
commitbd4268210e87d45d7d514712de80ec53ebd79e03 (patch)
treef0906e8c03c7bdaeaa146de6097f76af2b5df2dc /src
parent523197c831631031ef90ca8fb76f375414b1cb8e (diff)
downloadmruby-bd4268210e87d45d7d514712de80ec53ebd79e03.tar.gz
mruby-bd4268210e87d45d7d514712de80ec53ebd79e03.zip
class.c: implement method cache (off by default).
Diffstat (limited to 'src')
-rw-r--r--src/class.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/class.c b/src/class.c
index 97a37c54a..90baa05eb 100644
--- a/src/class.c
+++ b/src/class.c
@@ -37,6 +37,11 @@ typedef struct mt_tbl {
struct mt_elem *table;
} mt_tbl;
+#ifdef MRB_USE_INLINE_METHOD_CACHE
+#define MT_CACHE_SIZE 256
+static uint8_t mt_cache[MT_CACHE_SIZE];
+#endif
+
/* Creates the method table. */
static mt_tbl*
mt_new(mrb_state *mrb)
@@ -142,11 +147,23 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym)
if (t->size == 0) return NULL;
hash = kh_int_hash_func(mrb, sym);
+#ifdef MRB_USE_INLINE_METHOD_CACHE
+ size_t cpos = (hash^(uintptr_t)t) % MT_CACHE_SIZE;
+ pos = mt_cache[cpos];
+ if (cpos < t->alloc && t->table[cpos].key == sym) {
+ return &t->table[cpos];
+ }
+#endif
start = pos = hash & (t->alloc-1);
for (;;) {
struct mt_elem *slot = &t->table[pos];
if (slot->key == sym) {
+#ifdef MRB_USE_INLINE_METHOD_CACHE
+ if (pos < 0xff) {
+ mt_cache[cpos] = pos;
+ }
+#endif
return slot;
}
else if (slot_empty_p(slot)) {