RESOLVED FIXED 245468
A live node becomes undefined in OSR Exit.
https://bugs.webkit.org/show_bug.cgi?id=245468
Summary A live node becomes undefined in OSR Exit.
EntryHi
Reported 2022-09-21 01:48:32 PDT
function main() { const v75 = {}; v75.__proto__ = Object; Object.defineProperty(Object, 117982949, {}); let v119 = 0; while (v119 < 10) { function v121() { for (let v130 = 0; v130 < 100; v130++) {} const v142 = [2.1, NaN]; print(v142[0]) // wrongly print undefined } v121() v119++; } } noDFG(main); noFTL(main); main(); With the above script as input to JSC, run JSC with the following parameters: ./jsc test.js --useConcurrentJIT=0 --jitPolicyScale=0.001 v142[0] should be 2.1. But after OSRExit, v142[0] becomes undefined. The problem may be in CompileNewArray in DFGSpeculativeJIT. 2.1 is used (operand.use()) and NaN causes bailout. The use count of 2.1 is 0. So OSRExit wrongly thinks 2.1 is dead and put an undefined into the call frame.
Attachments
Patch (6.16 KB, patch)
2022-10-10 15:34 PDT, David Degazio
no flags
Patch (6.12 KB, patch)
2022-10-10 16:01 PDT, David Degazio
d_degazio: commit-queue-
Radar WebKit Bug Importer
Comment 1 2022-09-28 01:49:18 PDT
David Degazio
Comment 2 2022-10-10 15:34:33 PDT
David Degazio
Comment 3 2022-10-10 15:48:34 PDT
Elaborating on the explanation: in SpeculativeJIT::compileNewArray, in specifically the slow path (reached when we have invalidated the isHavingABadTime watchpoint), we explicitly use() each operand after we write it to the buffer: > case ALL_ARRAY_STORAGE_INDEXING_TYPES: { > JSValueOperand operand(this, use, ManualOperandSpeculation); > JSValueRegs operandRegs = operand.jsValueRegs(); > if (hasInt32(node->indexingType())) { > DFG_TYPE_CHECK( > operandRegs, use, SpecInt32Only, > m_jit.branchIfNotInt32(operandRegs)); > } > m_jit.storeValue(operandRegs, buffer + operandIdx); > operand.use(); > break; > } This is an optimization to avoid spilling operands unnecessarily when we call the new-array operation further down, by manually managing the node lifetimes. If a later operand fails the DFG_TYPE_CHECK, however, we may OSRExit. At that point, the exit information will be collected after earlier operands were used, potentially leaving it dead, resulting in the undefined value we see in this bug. This patch resolves the issue by doing two separate passes - first, we traverse the operands and emit the necessary type checks; second, we traverse the operands again and write them to the buffer. In this scheme, we generate the exit information prior to using any of the operands, so they should all remain live during this period.
Yusuke Suzuki
Comment 4 2022-10-10 15:54:06 PDT
Comment on attachment 462916 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=462916&action=review r=me > Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:9694 > + for (unsigned operandIdx = 0; operandIdx < node->numChildren(); ++operandIdx) { > + Edge use = m_graph.m_varArgChildren[node->firstChild() + operandIdx]; > + JSValueOperand operand(this, use, ManualOperandSpeculation); > + JSValueRegs operandRegs = operand.jsValueRegs(); > + if (hasInt32(node->indexingType())) { > + DFG_TYPE_CHECK( > + operandRegs, use, SpecInt32Only, > + m_jit.branchIfNotInt32(operandRegs)); > + } > + } Let's put it under `if (hasInt32(node->indexingType()))` And remove inner `if (hasInt32(node->indexingType()))`.
David Degazio
Comment 5 2022-10-10 16:01:16 PDT
Yusuke Suzuki
Comment 6 2022-10-10 18:30:42 PDT
Comment on attachment 462917 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=462917&action=review > Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:9657 > case ALL_DOUBLE_INDEXING_TYPES: { In WebKit coding style, `case` is aligned to `switch`. > Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:9684 > case ALL_INT32_INDEXING_TYPES: > case ALL_CONTIGUOUS_INDEXING_TYPES: > case ALL_ARRAY_STORAGE_INDEXING_TYPES: { Ditto.
Yusuke Suzuki
Comment 7 2022-10-10 18:31:16 PDT
Comment on attachment 462917 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=462917&action=review > Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp:9704 > default: Ditto.
Mark Lam
Comment 8 2022-11-11 15:53:04 PST
Mark Lam
Comment 9 2022-11-11 16:14:37 PST
*** Bug 246307 has been marked as a duplicate of this bug. ***
Mark Lam
Comment 10 2022-11-12 09:37:50 PST
Comment on attachment 462917 [details] Patch Let's land this via the github PR.
EWS
Comment 11 2022-11-12 14:55:14 PST
Committed 256611@main (104b2a1546ed): <https://commits.webkit.org/256611@main> Reviewed commits have been landed. Closing PR #5211 and removing active labels.
Note You need to log in before you can comment on or make changes to this bug.