summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2022-10-17 17:50:42 +0900
committerKoichi Sasada <ko1@atdot.net>2022-10-20 17:38:28 +0900
commite35c528d721d209ed8531b10b46c2ac725ea7bf5 (patch)
tree7a5fe3d73461b9e628f04226dedfffe8632a5438 /vm_insnhelper.c
parent7563604fb868d87057733f52d780d841fc1ab6bb (diff)
push dummy frame for loading process
This patch pushes dummy frames when loading code for the profiling purpose. The following methods push a dummy frame: * `Kernel#require` * `Kernel#load` * `RubyVM::InstructionSequence.compile_file` * `RubyVM::InstructionSequence.load_from_binary` https://bugs.ruby-lang.org/issues/18559
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/6572
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c32
1 files changed, 31 insertions, 1 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 8b19c6c10d..2434c5c3c6 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -201,7 +201,9 @@ vm_check_frame_detail(VALUE type, int req_block, int req_me, int req_cref, VALUE
if ((type & VM_FRAME_MAGIC_MASK) == VM_FRAME_MAGIC_DUMMY) {
VM_ASSERT(iseq == NULL ||
- RUBY_VM_NORMAL_ISEQ_P(iseq) /* argument error. it should be fixed */);
+ RBASIC_CLASS((VALUE)iseq) == 0 || // dummy frame for loading
+ RUBY_VM_NORMAL_ISEQ_P(iseq) //argument error
+ );
}
else {
VM_ASSERT(is_cframe == !RUBY_VM_NORMAL_ISEQ_P(iseq));
@@ -429,6 +431,34 @@ rb_vm_pop_frame(rb_execution_context_t *ec)
vm_pop_frame(ec, ec->cfp, ec->cfp->ep);
}
+// it pushes pseudo-frame with fname filename.
+VALUE
+rb_vm_push_frame_fname(rb_execution_context_t *ec, VALUE fname)
+{
+ VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
+ void *ptr = ruby_xcalloc(sizeof(struct rb_iseq_constant_body) + sizeof(struct rb_iseq_struct), 1);
+ rb_imemo_tmpbuf_set_ptr(tmpbuf, ptr);
+
+ struct rb_iseq_struct *dmy_iseq = (struct rb_iseq_struct *)ptr;
+ struct rb_iseq_constant_body *dmy_body = (struct rb_iseq_constant_body *)&dmy_iseq[1];
+ dmy_iseq->body = dmy_body;
+ dmy_body->type = ISEQ_TYPE_TOP;
+ dmy_body->location.pathobj = fname;
+
+ vm_push_frame(ec,
+ dmy_iseq, //const rb_iseq_t *iseq,
+ VM_FRAME_MAGIC_DUMMY | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH, // VALUE type,
+ ec->cfp->self, // VALUE self,
+ VM_BLOCK_HANDLER_NONE, // VALUE specval,
+ Qfalse, // VALUE cref_or_me,
+ NULL, // const VALUE *pc,
+ ec->cfp->sp, // VALUE *sp,
+ 0, // int local_size,
+ 0); // int stack_max
+
+ return tmpbuf;
+}
+
/* method dispatch */
static inline VALUE
rb_arity_error_new(int argc, int min, int max)