From c034cd54eda57829608e8ec09a71cf35256e1966 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Thu, 3 Dec 2015 11:00:39 -0800 Subject: [PATCH 1/2] add PIC --- vm_core.h | 6 ++++++ vm_insnhelper.c | 36 ++++++++++++++++++++++++++++++++++++ vm_opts.h | 2 ++ 3 files changed, 44 insertions(+) diff --git a/vm_core.h b/vm_core.h index 2343e11..01023a9 100644 --- a/vm_core.h +++ b/vm_core.h @@ -241,6 +241,12 @@ struct rb_call_cache { vm_call_handler call; +#if OPT_POLYMORPHIC_INLINE_METHOD_CACHE + rb_serial_t class_serials[POLYMORPHIC_CACHE_SIZE]; + const rb_callable_method_entry_t *mes[POLYMORPHIC_CACHE_SIZE]; + vm_call_handler calls[POLYMORPHIC_CACHE_SIZE]; +#endif + union { unsigned int index; /* used by ivar */ enum method_missing_reason method_missing_reason; /* used by method_missing */ diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 033edea..8692b7a 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1123,9 +1123,32 @@ vm_search_method(const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE VALUE klass = CLASS_OF(recv); #if OPT_INLINE_METHOD_CACHE + int i; if (LIKELY(GET_GLOBAL_METHOD_STATE() == cc->method_state && RCLASS_SERIAL(klass) == cc->class_serial)) { /* cache hit! */ return; +# if OPT_POLYMORPHIC_INLINE_METHOD_CACHE + } else { + if (LIKELY(GET_GLOBAL_METHOD_STATE() == cc->method_state)) { + /* i = 0 will always be the same as the above branch, so we should + skip checking it here. */ + for(i = 1; i < POLYMORPHIC_CACHE_SIZE; i++) { + if (RCLASS_SERIAL(klass) == cc->class_serials[i]) { + cc->me = cc->mes[i]; + cc->class_serial = cc->class_serials[i]; + cc->call = cc->calls[i]; + /* cache hit! */ + return; + } + } + } else { + for(i = 0; i < POLYMORPHIC_CACHE_SIZE; i++) { + cc->mes[i] = 0; + cc->class_serials[i] = 0; + cc->calls[i] = 0; + } + } +# endif } #endif @@ -1135,6 +1158,19 @@ vm_search_method(const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE #if OPT_INLINE_METHOD_CACHE cc->method_state = GET_GLOBAL_METHOD_STATE(); cc->class_serial = RCLASS_SERIAL(klass); + +# if OPT_POLYMORPHIC_INLINE_METHOD_CACHE + for(i = POLYMORPHIC_CACHE_SIZE - 1; i > 0; i--) { + cc->mes[i] = cc->mes[i - 1]; + cc->class_serials[i] = cc->class_serials[i - 1]; + cc->calls[i] = cc->calls[i - 1]; + } + + cc->mes[0] = cc->me; + cc->class_serials[0] = cc->class_serial; + cc->calls[0] = cc->call; +# endif + #endif } diff --git a/vm_opts.h b/vm_opts.h index 3fedf1d..8ef387c 100644 --- a/vm_opts.h +++ b/vm_opts.h @@ -38,6 +38,8 @@ /* VM running option */ #define OPT_CHECKED_RUN 1 #define OPT_INLINE_METHOD_CACHE 1 +#define OPT_POLYMORPHIC_INLINE_METHOD_CACHE 1 +#define POLYMORPHIC_CACHE_SIZE 6 #define OPT_GLOBAL_METHOD_CACHE 1 #define OPT_BLOCKINLINING 0 -- 2.2.1