Skip to content
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

Disable OpHelperReg optimisation for Coroutines #6706

Closed
wants to merge 1 commit into from

Conversation

rhuanjl
Copy link
Collaborator

@rhuanjl rhuanjl commented Apr 18, 2021

The book keeping for the OpHelperReg optimisation does not always work across yield/await points resulting in potential undefined behaviour.

Disable this optimisation within Coroutines (Generator, Async and AsyncGenerator functions) until/unless a fix can be found.

Additionally the code to spill RAX + RCX/EAX + ECX before GeneratorBailIn was broken - fix it (wrong condition check).

And a little tidy up/removing unused parameters.

Fix: #6704
Fix: #6691

Comment on lines -5205 to -5207
const BVSparse<JitArenaAllocator>& byteCodeUpwardExposedUses,
const BVSparse<JitArenaAllocator>& upwardExposedUses,
const CapturedValues& capturedValues,
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These parameters weren't used

bailInInstr->capturedValues,
insertionPoint
);
Assert(!this->func->IsStackArgsEnabled());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Assert had gone adrift from the comment that explained it - therefore moved upwards.

@@ -4974,16 +4968,6 @@ LinearScan::GeneratorBailIn::~GeneratorBailIn()
JitAdelete(this->func->m_alloc, this->bailInSymbols);
}

void LinearScan::GeneratorBailIn::SpillRegsForBailIn()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function was called from inside the always false condition above. Aside from introducing segfaults, analysis of the logic shows it's unnecessary.

The purpose of this function was to free RAX and RCX (or EAX and ECX) before a GeneratorBailIn as the logic will use those two registers - BUT - the way the BailIn code works it restores whatever was in RAX and RCX before the Yield/Await as its last step, so freeing them serves no purpose.

#ifdef DBG
else
{
labelInstr->AsLabelInstr()->m_noHelperAssert = true;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's an assertion to check that helper blocks are being set correctly - with this optimisation disabled it would fire incorrectly, setting this debug only property disables it.

@rhuanjl rhuanjl closed this Apr 18, 2021
@rhuanjl rhuanjl reopened this Apr 19, 2021
@rhuanjl rhuanjl force-pushed the gen_scope_slots branch 2 times, most recently from 1e4632d to 28968e1 Compare April 19, 2021 10:00
@rhuanjl rhuanjl closed this Apr 19, 2021
@rhuanjl rhuanjl reopened this Apr 19, 2021
@@ -3339,7 +3339,7 @@ LinearScan::KillImplicitRegs(IR::Instr *instr)
return;
}

if (instr->m_opcode == Js::OpCode::Yield)
if (instr->m_opcode == Js::OpCode::GeneratorBailInLabel)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OpCode Yield is removed earlier in the jitting process and replaced with a number of operations - the one we're looking for here is the GeneratorBailInLabel.

@rhuanjl
Copy link
Collaborator Author

rhuanjl commented Apr 19, 2021

I thought I had this one... back to the drawing board. (The x64 vs x86 differences on this case are a total pain).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Invalid Memory Access in GetScriptContext Invalid memory access in GetEntryPoint
1 participant