Skip to content

Instantly share code, notes, and snippets.

@nurse
Last active March 24, 2016 02:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nurse/5d7ce276e60be4a43916 to your computer and use it in GitHub Desktop.
Save nurse/5d7ce276e60be4a43916 to your computer and use it in GitHub Desktop.
Original:
Performance counter stats for './miniruby -e@v=42; n=100_000_000;while n>0; x=@v; x=@v; x=@v; n-=1;end':
5675.422561 task-clock (msec) # 0.998 CPUs utilized
159 context-switches # 0.028 K/sec
2 cpu-migrations # 0.000 K/sec
889 page-faults # 0.157 K/sec
16521817067 cycles # 2.911 GHz
4121915626 stalled-cycles-frontend # 24.95% frontend cycles idle
<not supported> stalled-cycles-backend
35724222782 instructions # 2.16 insns per cycle
# 0.12 stalled cycles per insn
5105044210 branches # 899.500 M/sec
200180709 branch-misses # 3.92% of all branches
5.687665622 seconds time elapsed
With patch:
Performance counter stats for './miniruby -e@v=42; n=100_000_000;while n>0; x=@v; x=@v; x=@v; n-=1;end':
3371.817523 task-clock (msec) # 0.997 CPUs utilized
47 context-switches # 0.014 K/sec
2 cpu-migrations # 0.001 K/sec
891 page-faults # 0.264 K/sec
9886210809 cycles # 2.932 GHz
3685439982 stalled-cycles-frontend # 37.28% frontend cycles idle
<not supported> stalled-cycles-backend
25821528963 instructions # 2.61 insns per cycle
# 0.14 stalled cycles per insn
3004551132 branches # 891.078 M/sec
169865 branch-misses # 0.01% of all branches
3.381315509 seconds time elapsed
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 39ca48a..8abd78f 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -774,20 +774,30 @@ vm_search_const_defined_class(const VALUE cbase, ID id)
#define USE_IC_FOR_IVAR 1
#endif
+#define RB_TYPE_P_(obj, type) ((flags & RUBY_T_MASK) == T_OBJECT)
+#define ROBJECT_NUMIV_(o) \
+ ((flags & ROBJECT_EMBED) ? \
+ ROBJECT_EMBED_LEN_MAX : \
+ ROBJECT(o)->as.heap.numiv)
+#define ROBJECT_IVPTR_(o) \
+ ((flags & ROBJECT_EMBED) ? \
+ ROBJECT(o)->as.ary : \
+ ROBJECT(o)->as.heap.ivptr)
static inline VALUE
vm_getivar(VALUE obj, ID id, IC ic, struct rb_call_cache *cc, int is_attr)
{
+ VALUE flags = T_OBJECT | ROBJECT_EMBED;
#if USE_IC_FOR_IVAR
- if (RB_TYPE_P(obj, T_OBJECT)) {
+ if (RB_TYPE_P_(obj, T_OBJECT) && (flags & ROBJECT_EMBED)) {
VALUE val = Qundef;
VALUE klass = RBASIC(obj)->klass;
- const long len = ROBJECT_NUMIV(obj);
- const VALUE *const ptr = ROBJECT_IVPTR(obj);
+ const long len = ROBJECT_NUMIV_(obj);
+ const VALUE *const ptr = ROBJECT_IVPTR_(obj);
if (LIKELY(is_attr ? cc->aux.index > 0 : ic->ic_serial == RCLASS_SERIAL(klass))) {
long index = !is_attr ? (long)ic->ic_value.index : (long)(cc->aux.index - 1);
- if (index < len) {
+ if (LIKELY(index < len)) {
val = ptr[index];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment