-
Notifications
You must be signed in to change notification settings - Fork 5.5k
ZJIT: Codegen for NewHash #14059
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
ZJIT: Codegen for NewHash #14059
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the very fast PR! On the right track -- needs some more work.
Also I wonder if this failure is related:
|
Not sure.. I can not reproduce at my mahcine. |
yeah it's related.. I need to understand intended behavior. |
❌ Tests Failed✖️no tests failed ✔️62296 tests passed(2 flakes) |
@tekknolagi Thank for the review explain many things :) I've updated the PR! |
Except for @k0kubun 's feedback I think this looks great! Bulk insert is a good idea. (Kokubun, do you think the frame setup bit is ok?) |
Yeah, it's a non-leaf instruction, so it makes sense that we set PC/SP and spill locals/stack slots (for now). Filed #14100 to define a helper for sharing the logic. When there's no element to insert, it's probably leaf (while it does trigger GC). I think we can skip the SP update and spills in that case. We still have to set PC for allocation tracing. |
There are some test failures that are not immediately clear what's going on. I can try and take a look tomorrow or the day after. Frustrating :/ Probably something small |
zjit/src/codegen.rs
Outdated
} | ||
|
||
for (i, pair) in pairs.iter().enumerate() { | ||
let stack_opnd = Opnd::mem(64, SP, i as i32 * SIZEOF_VALUE_I32); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems unsafe. rb_hash_bulk_insert
calls hash functions, which may not be leaf (hence you're calling gen_prepare_non_leaf_call
).
Your code here is writing above the VM stack stop, so if anything is pushed to the VM stack, the content of the array in the argument gets clobbered. Because it's not leaf, it could call another method, and at that point things will be pushed to the VM stack.
But you can't bump the cfp->sp
to protect them because it would miss the point of gen_prepare_non_leaf_call
(part of the dumped stack should be a valid array usable for rb_hash_bulk_insert
currently, but we'd want to optimize it away later anyway), which makes it safe for the interpreter to take over the stack as is.
So I think we need to use the C stack here. Bump NATIVE_STACK_PTR, use memory operands based off of NATIVE_BASE_PTR
(because NATIVE_STACK_PTR
can be moved by the backend), and restore NATIVE_STACK_PTR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I remembered we never update the SP
register, so I guess I misread it a bit. But then it writes to random locations in the VM stack that already have spilled stack slots, so it can still corrupt the state for the interpreter in the wrong way. As suggested above, we should write to the C stack.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to pair on this this week or next @corona10 ! Sorry it's been a bit of a rollercoaster
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Another thing we can do to chunk the work is to add a new PR that just handles |
Yeah, let's start with simple stuff first. (I was also pretty busy with other stuff, but happy to start pair with you too :)) |
I wonder if you are running into a manifestation of https://bugs.ruby-lang.org/issues/14201 that #14205 fixes |
Maybe it is worth rebasing PR once you merge it. |
Feel free to also cherry-pick |
Now that the PR is merged, let's try rebasing from the latest master then? We can't merge a PR with a failing ZJIT test, which is relatively stable these days. |
This is my first contribution to ZJIT. I started by handling
NewHash
, and also noticed that more complex cases likeHashDup
andSend
should be handled as well. These might be optimizable into other opcodes.I'm sure my mentor @tekknolagi will take a look :)