diff options
author | Alan Wu <[email protected]> | 2025-02-14 20:16:52 -0500 |
---|---|---|
committer | Takashi Kokubun <[email protected]> | 2025-04-18 21:52:58 +0900 |
commit | 3e49f3304d6a42edded0d571bd45ffdf846ffd9b (patch) | |
tree | 8a2434c2cfe87ff02624ec5b3e52bc16cdc25903 /doc | |
parent | b6e4b37c442692253b572e2b8da4cc8cb007296a (diff) |
remove duplicate yarv_frames.md
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13131
Diffstat (limited to 'doc')
-rw-r--r-- | doc/yarv_frame_layout.md | 20 | ||||
-rw-r--r-- | doc/yarv_frames.md | 77 |
2 files changed, 7 insertions, 90 deletions
diff --git a/doc/yarv_frame_layout.md b/doc/yarv_frame_layout.md index fc1bb39298..ea8ad013cf 100644 --- a/doc/yarv_frame_layout.md +++ b/doc/yarv_frame_layout.md @@ -1,11 +1,11 @@ # YARV Frame Layout -This document is an introduction to the layout of the VM stack as calls happen. -The code holds the ultimate truth for this subject, so beware that this -document can become stale. +This document is an introduction to what happens on the VM stack as the VM +services calls. The code holds the ultimate truth for this subject, so beware +that this document can become stale. We'll walk through the following program, with explanation at selected points -in execution and abridged instruction sequence disassembly listings: +in execution and abridged disassembly listings: ```ruby def foo(x, y) @@ -58,7 +58,7 @@ When accessing variables in the immediate scope, where `level=0`, it's essentially `val = cfp->ep[-idx];`. Note that this EP-relative index has a different basis the index that comes -after "@" in disassembly listings. The `@` index is relative to the 0th local +after "@" in disassembly listings. The "@" index is relative to the 0th local (`x` in this case). ## Q&A @@ -73,11 +73,5 @@ A: Not all calls put the `self` in the callee on the stack. Two Q: Why have `cfp->ep` when it seems that everything is below `cfp->sp`? -A: In the example, EP points to the stack, but it can also point to the GC heap. - Blocks can capture and evacuate their environment to the heap. - - - - - - +A: In the example, `cfp->ep` points to the stack, but it can also point to the + GC heap. Blocks can capture and evacuate their environment to the heap. diff --git a/doc/yarv_frames.md b/doc/yarv_frames.md deleted file mode 100644 index ea8ad013cf..0000000000 --- a/doc/yarv_frames.md +++ /dev/null @@ -1,77 +0,0 @@ -# YARV Frame Layout - -This document is an introduction to what happens on the VM stack as the VM -services calls. The code holds the ultimate truth for this subject, so beware -that this document can become stale. - -We'll walk through the following program, with explanation at selected points -in execution and abridged disassembly listings: - -```ruby -def foo(x, y) - z = x.casecmp(y) -end - -foo(:one, :two) -``` - -First, after arguments are evaluated and right before the `send` to `foo`: - -``` - ┌────────────┐ - putself │ :two │ - putobject :one 0x2 ├────────────┤ - putobject :two │ :one │ -► send <:foo, argc:2> 0x1 ├────────────┤ - leave │ self │ - 0x0 └────────────┘ -``` - -The `put*` instructions have pushed 3 items onto the stack. It's now time to -add a new control frame for `foo`. The following is the shape of the stack -after one instruction in `foo`: - -``` - cfp->sp=0x8 at this point. - 0x8 ┌────────────┐◄──Stack space for temporaries - │ :one │ live above the environment. - 0x7 ├────────────┤ - getlocal x@0 │ < flags > │ foo's rb_control_frame_t -► getlocal y@1 0x6 ├────────────┤◄──has cfp->ep=0x6 - send <:casecmp, argc:1> │ <no block> │ - dup 0x5 ├────────────┤ The flags, block, and CME triple - setlocal z@2 │ <CME: foo> │ (VM_ENV_DATA_SIZE) form an - leave 0x4 ├────────────┤ environment. They can be used to - │ z (nil) │ figure out what local variables - 0x3 ├────────────┤ are below them. - │ :two │ - 0x2 ├────────────┤ Notice how the arguments, now - │ :one │ locals, never moved. This layout - 0x1 ├────────────┤ allows for argument transfer - │ self │ without copying. - 0x0 └────────────┘ -``` - -Given that locals have lower address than `cfp->ep`, it makes sense then that -`getlocal` in `insns.def` has `val = *(vm_get_ep(GET_EP(), level) - idx);`. -When accessing variables in the immediate scope, where `level=0`, it's -essentially `val = cfp->ep[-idx];`. - -Note that this EP-relative index has a different basis the index that comes -after "@" in disassembly listings. The "@" index is relative to the 0th local -(`x` in this case). - -## Q&A - -Q: It seems that the receiver is always at an offset relative to EP, - like locals. Couldn't we use EP to access it instead of using `cfp->self`? - -A: Not all calls put the `self` in the callee on the stack. Two - examples are `Proc#call`, where the receiver is the Proc object, but `self` - inside the callee is `Proc#receiver`, and `yield`, where the receiver isn't - pushed onto the stack before the arguments. - -Q: Why have `cfp->ep` when it seems that everything is below `cfp->sp`? - -A: In the example, `cfp->ep` points to the stack, but it can also point to the - GC heap. Blocks can capture and evacuate their environment to the heap. |