Slide 101
Slide 101 text
Compiler Modifications
- PUSH_SEND_R(ret, location, method_id, INT2FIX(orig_argc), block_iseq, INT2FIX(flags), kw_arg);
+ LABEL *not_basic_new = NEW_LABEL(location.line);
+ LABEL *not_basic_new_finish = NEW_LABEL(location.line);
+
+ bool inline_new = ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction &&
+ method_id == rb_intern("new") &&
+ call_node->block == NULL &&
+ !(flags & VM_CALL_ARGS_BLOCKARG);
+
+ if (inline_new) {
+ if (LAST_ELEMENT(ret) == opt_new_prelude) {
+ PUSH_INSN(ret, location, putnil);
+ PUSH_INSN(ret, location, swap);
+ }
+ else {
+ ELEM_INSERT_NEXT(opt_new_prelude, &new_insn_body(iseq, location.line, location.node_id, BIN(swap), 0)->link);
+ ELEM_INSERT_NEXT(opt_new_prelude, &new_insn_body(iseq, location.line, location.node_id, BIN(putnil), 0)->link);
+ }
+
+ // Jump unless the receiver uses the "basic" implementation of "new"
+ VALUE ci;
+ if (flags & VM_CALL_FORWARDING) {
+ ci = (VALUE)new_callinfo(iseq, method_id, orig_argc + 1, flags, kw_arg, 0);
+ }
+ else {
+ ci = (VALUE)new_callinfo(iseq, method_id, orig_argc, flags, kw_arg, 0);
+ }
+
+ PUSH_INSN2(ret, location, opt_new, ci, not_basic_new);
+ LABEL_REF(not_basic_new);
+ // optimized path
+ PUSH_SEND_R(ret, location, rb_intern("initialize"), INT2FIX(orig_argc), block_iseq, INT2FIX(flags | VM_CALL_FCALL), kw_arg);
+ PUSH_INSNL(ret, location, jump, not_basic_new_finish);
+
Is this a call to
“new”?
Insert special
instructions
If not new, jump to
slow path