зеркало из https://github.com/github/ruby.git
Pin and inline cme in JIT-ed method calls
```
$ benchmark-driver benchmark.yml -v --rbenv 'before --jit;after --jit' --repeat-count=12 --output=all
before --jit: ruby 2.8.0dev (2020-03-11T07:43:12Z master e89ebdcb87
) +JIT [x86_64-linux]
after --jit: ruby 2.8.0dev (2020-03-11T07:54:18Z master 143776a0da) +JIT [x86_64-linux]
Calculating -------------------------------------
before --jit after --jit
Optcarrot Lan_Master.nes 73.86976729561439 77.20184819316513 fps
74.46997176460742 78.43493030231805
77.59686308754307 78.55714131655935
78.53693921126656 79.08984255596820
80.10158944910573 79.17751731838183
80.12254974411167 79.60853122429181
80.28678655204945 79.74674066871896
80.38690681095379 79.90624544440300
80.79223498756919 80.57881084206193
80.82857188422419 80.70677614429169
81.06447745878245 81.03868541295149
81.21620802278490 82.16354660940607
```
This commit is contained in:
Родитель
e89ebdcb87
Коммит
da4b97a0e3
3
iseq.c
3
iseq.c
|
@ -364,8 +364,9 @@ 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) {
|
||||
// Pin cc against GC.compact as the the address may be written in JIT-ed code.
|
||||
// Pin `cc` and `cc->cme` against GC.compact as their addresses may be written in JIT-ed code.
|
||||
rb_gc_mark((VALUE)cc);
|
||||
rb_gc_mark((VALUE)vm_cc_cme(cc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
|
||||
% # JIT: Invalidate call cache if it requires vm_search_method. This allows to inline some of following things.
|
||||
fprintf(f, " const struct rb_callcache *cc = (const struct rb_callcache *)0x%"PRIxVALUE";\n", (VALUE)captured_cc);
|
||||
fprintf(f, " if (UNLIKELY(!vm_cc_valid_p(cc, CLASS_OF(stack[%d])))) {\n", b->stack_size - 1 - argc);
|
||||
fprintf(f, " const rb_callable_method_entry_t *cc_cme = (const rb_callable_method_entry_t *)0x%"PRIxVALUE";\n", (VALUE)vm_cc_cme(captured_cc));
|
||||
fprintf(f, " if (UNLIKELY(!vm_cc_valid_p(cc, cc_cme, 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");
|
||||
|
@ -72,7 +73,7 @@
|
|||
% # JIT: Special CALL_METHOD. Bypass captured_cc->call and inline vm_call_iseq_setup_normal for vm_call_iseq_setup_func FASTPATH.
|
||||
fprintf(f, " {\n");
|
||||
fprintf(f, " VALUE v;\n");
|
||||
fprintf(f, " vm_call_iseq_setup_normal(ec, reg_cfp, &calling, vm_cc_cme(cc), 0, %d, %d);\n",
|
||||
fprintf(f, " vm_call_iseq_setup_normal(ec, reg_cfp, &calling, cc_cme, 0, %d, %d);\n",
|
||||
param_size, iseq->body->local_table_size); // fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE
|
||||
if (iseq->body->catch_except_p) {
|
||||
fprintf(f, " VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n");
|
||||
|
|
|
@ -316,11 +316,12 @@ vm_cc_markable(const struct rb_callcache *cc)
|
|||
return FL_TEST_RAW(cc, VM_CALLCACHE_UNMARKABLE) == 0;
|
||||
}
|
||||
|
||||
// For MJIT. cc_cme is supposed to have inlined `vm_cc_cme(cc)`.
|
||||
static inline bool
|
||||
vm_cc_valid_p(const struct rb_callcache *cc, VALUE klass)
|
||||
vm_cc_valid_p(const struct rb_callcache *cc, const rb_callable_method_entry_t *cc_cme, VALUE klass)
|
||||
{
|
||||
VM_ASSERT(IMEMO_TYPE_P(cc, imemo_callcache));
|
||||
if (cc->klass == klass && !METHOD_ENTRY_INVALIDATED(vm_cc_cme(cc))) {
|
||||
if (cc->klass == klass && !METHOD_ENTRY_INVALIDATED(cc_cme)) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
|
|
Загрузка…
Ссылка в новой задаче