зеркало из https://github.com/github/ruby.git
Optimize away call data refs in JIT-ed method calls
According to ko1, `cd->cc != cc` was for GC.compact guard.
As we pin cc by rb_gc_mark(), we don't need the check.
```
$ benchmark-driver benchmark.yml -v --rbenv 'before --jit;after --jit' --repeat-count=12 --output=all
before --jit: ruby 2.8.0dev (2020-03-11T05:36:48Z master da6948753e
) +JIT [x86_64-linux]
after --jit: ruby 2.8.0dev (2020-03-11T06:26:34Z master 36b20b8b4a) +JIT [x86_64-linux]
Calculating -------------------------------------
before --jit after --jit
Optcarrot Lan_Master.nes 74.03480698689405 71.63404803273507 fps
74.15085286586992 73.43923328104295
75.51738277744781 75.75465268365384
76.24922600109410 76.74071607861318
76.45513422802325 77.47521029238116
76.86617230739330 78.14759496269018
77.71509137131933 79.14051571125866
77.72839157096146 79.35884822673313
78.25218904561633 79.92538876408051
78.72521071333249 79.98075556706726
78.79950460165091 80.51747831497875
79.43884960720381 80.97973166525254
```
This commit is contained in:
Родитель
da6948753e
Коммит
9511b4c8fa
3
iseq.c
3
iseq.c
|
@ -364,7 +364,8 @@ rb_iseq_mark(const rb_iseq_t *iseq)
|
|||
for (unsigned int i=0; i<body->ci_size; i++) {
|
||||
const struct rb_callcache *cc = cc_entries[i];
|
||||
if (cc != NULL) {
|
||||
rb_gc_mark((VALUE)cc); // pindown
|
||||
// Pin cc against GC.compact as the the address may be written in JIT-ed code.
|
||||
rb_gc_mark((VALUE)cc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,9 +38,8 @@
|
|||
}
|
||||
|
||||
% # JIT: Invalidate call cache if it requires vm_search_method. This allows to inline some of following things.
|
||||
fprintf(f, " const struct rb_call_data *cd = (const struct rb_callcache *)0x%"PRIxVALUE";\n", (VALUE)cd);
|
||||
fprintf(f, " const struct rb_callcache *cc = (const struct rb_callcache *)0x%"PRIxVALUE";\n", (VALUE)captured_cc);
|
||||
fprintf(f, " if (UNLIKELY(cd->cc != cc || !vm_cc_valid_p(cc, CLASS_OF(stack[%d])))) {\n", b->stack_size - 1 - argc);
|
||||
fprintf(f, " if (UNLIKELY(!vm_cc_valid_p(cc, CLASS_OF(stack[%d])))) {\n", b->stack_size - 1 - argc);
|
||||
fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos);
|
||||
fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size);
|
||||
fprintf(f, " goto send_cancel;\n");
|
||||
|
@ -63,7 +62,7 @@
|
|||
fprintf(f, " {\n");
|
||||
fprintf(f, " struct rb_calling_info calling;\n");
|
||||
% if insn.name == 'send'
|
||||
fprintf(f, " calling.block_handler = vm_caller_setup_arg_block(ec, reg_cfp, cd->ci, (rb_iseq_t *)0x%"PRIxVALUE", FALSE);\n", (VALUE)blockiseq);
|
||||
fprintf(f, " calling.block_handler = vm_caller_setup_arg_block(ec, reg_cfp, (const struct rb_callinfo *)0x%"PRIxVALUE", (rb_iseq_t *)0x%"PRIxVALUE", FALSE);\n", (VALUE)ci, (VALUE)blockiseq);
|
||||
% else
|
||||
fprintf(f, " calling.block_handler = VM_BLOCK_HANDLER_NONE;\n");
|
||||
% end
|
||||
|
|
Загрузка…
Ссылка в новой задаче