RESOLVED FIXED 234476
[JSC][32bit] Fix regexp crash on ARMv7
https://bugs.webkit.org/show_bug.cgi?id=234476
Summary [JSC][32bit] Fix regexp crash on ARMv7
Mikhail R. Gadelha
Reported 2021-12-18 06:50:19 PST
[JSC][32bit] Fix regexp crash when building on ARMv7 using gcc 10.2.1
Attachments
Patch (8.82 KB, patch)
2021-12-18 06:56 PST, Mikhail R. Gadelha
no flags
Patch (7.75 KB, patch)
2021-12-20 20:07 PST, Mikhail R. Gadelha
no flags
Patch (10.69 KB, patch)
2021-12-21 09:59 PST, Mikhail R. Gadelha
no flags
Patch (21.36 KB, patch)
2022-01-05 12:38 PST, Mikhail R. Gadelha
ews-feeder: commit-queue-
Patch (22.14 KB, patch)
2022-01-05 12:58 PST, Mikhail R. Gadelha
ews-feeder: commit-queue-
Patch (22.87 KB, patch)
2022-01-05 13:10 PST, Mikhail R. Gadelha
ews-feeder: commit-queue-
Patch (23.02 KB, patch)
2022-01-05 13:24 PST, Mikhail R. Gadelha
no flags
Patch (23.39 KB, patch)
2022-01-05 15:11 PST, Mikhail R. Gadelha
no flags
Patch (22.26 KB, patch)
2022-01-07 14:56 PST, Mikhail R. Gadelha
no flags
Patch (22.52 KB, patch)
2022-01-08 13:11 PST, Mikhail R. Gadelha
no flags
Patch (22.16 KB, patch)
2022-01-08 13:41 PST, Mikhail R. Gadelha
ews-feeder: commit-queue-
Patch (28.71 KB, patch)
2022-01-08 15:41 PST, Mikhail R. Gadelha
no flags
Patch (30.80 KB, patch)
2022-01-10 10:21 PST, Mikhail R. Gadelha
no flags
Patch (30.85 KB, patch)
2022-01-10 12:21 PST, Mikhail R. Gadelha
no flags
Patch (30.81 KB, patch)
2022-01-11 06:06 PST, Mikhail R. Gadelha
no flags
Patch (24.55 KB, patch)
2022-01-11 06:57 PST, Mikhail R. Gadelha
no flags
Patch (26.02 KB, patch)
2022-01-11 08:05 PST, Mikhail R. Gadelha
no flags
Patch (32.01 KB, patch)
2022-01-11 10:53 PST, Mikhail R. Gadelha
no flags
Patch (31.93 KB, patch)
2022-01-11 12:14 PST, Mikhail R. Gadelha
ews-feeder: commit-queue-
Patch (26.74 KB, patch)
2022-01-11 14:22 PST, Mikhail R. Gadelha
no flags
Patch (26.40 KB, patch)
2022-01-11 15:40 PST, Mikhail R. Gadelha
no flags
Patch (33.13 KB, patch)
2022-01-12 05:36 PST, Mikhail R. Gadelha
no flags
Patch (32.46 KB, patch)
2022-01-12 10:52 PST, Mikhail R. Gadelha
no flags
Patch (32.83 KB, patch)
2022-01-12 11:13 PST, Mikhail R. Gadelha
no flags
Patch (32.99 KB, patch)
2022-01-13 07:53 PST, Mikhail R. Gadelha
no flags
Patch (33.48 KB, patch)
2022-01-13 09:14 PST, Mikhail R. Gadelha
no flags
Patch (33.54 KB, patch)
2022-01-13 12:10 PST, Mikhail R. Gadelha
no flags
Patch (33.55 KB, patch)
2022-01-13 14:15 PST, Mikhail R. Gadelha
no flags
Patch (33.57 KB, patch)
2022-01-14 11:47 PST, Mikhail R. Gadelha
no flags
Patch (29.82 KB, patch)
2022-01-14 12:36 PST, Mikhail R. Gadelha
no flags
Patch (28.30 KB, patch)
2022-01-17 12:44 PST, Mikhail R. Gadelha
no flags
Patch (28.73 KB, patch)
2022-01-18 16:43 PST, Mikhail R. Gadelha
no flags
Patch (28.38 KB, patch)
2022-01-19 10:53 PST, Mikhail R. Gadelha
no flags
Patch (30.14 KB, patch)
2022-01-24 09:24 PST, Mikhail R. Gadelha
no flags
Mikhail R. Gadelha
Comment 1 2021-12-18 06:56:44 PST
Mikhail R. Gadelha
Comment 2 2021-12-20 20:07:09 PST
Mikhail R. Gadelha
Comment 3 2021-12-21 09:59:57 PST
Yusuke Suzuki
Comment 4 2021-12-21 10:57:23 PST
Comment on attachment 447729 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=447729&action=review > Source/JavaScriptCore/yarr/YarrJIT.cpp:4204 > + m_jit.loadPtr(MacroAssembler::Address(MacroAssembler::stackPointerRegister, m_arg5OnStackOffset), matchingContext); Instead, can we use `CCallHelpers::calculatePokeOffset` to compute the right offset without computing it per architecture in YarrJIT? > Source/JavaScriptCore/yarr/YarrJIT.cpp:4685 > + unsigned m_arg5OnStackOffset = 0; For default field initializer, use `{ 0 }` instead of ` = 0`.
Radar WebKit Bug Importer
Comment 5 2021-12-25 06:51:16 PST
Mikhail R. Gadelha
Comment 6 2022-01-05 12:38:09 PST
Mikhail R. Gadelha
Comment 7 2022-01-05 12:58:27 PST
Mikhail R. Gadelha
Comment 8 2022-01-05 13:10:39 PST
Mikhail R. Gadelha
Comment 9 2022-01-05 13:24:15 PST
Mikhail R. Gadelha
Comment 10 2022-01-05 15:11:29 PST
Mikhail R. Gadelha
Comment 11 2022-01-07 14:56:22 PST
Mikhail R. Gadelha
Comment 12 2022-01-08 13:11:23 PST
Mikhail R. Gadelha
Comment 13 2022-01-08 13:41:35 PST
Mikhail R. Gadelha
Comment 14 2022-01-08 15:41:37 PST
Mikhail R. Gadelha
Comment 15 2022-01-10 10:21:49 PST
Mikhail R. Gadelha
Comment 16 2022-01-10 12:21:56 PST
Mikhail R. Gadelha
Comment 17 2022-01-11 06:06:46 PST
Mikhail R. Gadelha
Comment 18 2022-01-11 06:57:29 PST
Mikhail R. Gadelha
Comment 19 2022-01-11 08:05:40 PST
Mikhail R. Gadelha
Comment 20 2022-01-11 10:53:57 PST
Mikhail R. Gadelha
Comment 21 2022-01-11 12:14:09 PST
Mikhail R. Gadelha
Comment 22 2022-01-11 14:22:02 PST
Mikhail R. Gadelha
Comment 23 2022-01-11 15:40:21 PST
Mikhail R. Gadelha
Comment 24 2022-01-12 05:36:31 PST
Mikhail R. Gadelha
Comment 25 2022-01-12 10:52:53 PST
Mikhail R. Gadelha
Comment 26 2022-01-12 11:13:06 PST
Mikhail R. Gadelha
Comment 27 2022-01-13 07:53:54 PST
Geza Lore
Comment 28 2022-01-13 08:00:44 PST
Comment on attachment 449060 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=449060&action=review > Source/JavaScriptCore/jit/CCallHelpers.h:1001 > + constexpr GPRReg loadArgumentFromStack(GPRReg scratchGPR) This function is not constexpr (it calls `loadPtr` which is not constexpr), nor does it need to be constexpr. Same applies to 'getArgumentGPR' > Source/JavaScriptCore/jit/CCallHelpers.h:1037 > + constexpr GPRReg getArgumentGPR(GPRReg scratchGPR = GPRReg::InvalidGPRReg) Like loadArgumentFromStack, this function is not constexpr, nor does it need to be.
Mikhail R. Gadelha
Comment 29 2022-01-13 09:14:20 PST
Darin Adler
Comment 30 2022-01-13 10:28:58 PST
Comment on attachment 449068 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=449068&action=review Some coding style comments: not intended to be a complete review, although the patch generally looks good > Source/JavaScriptCore/jit/CCallHelpers.h:996 > +private: > + Normally we’d omit that blank line. > Source/JavaScriptCore/jit/CCallHelpers.h:1001 > + GPRReg loadArgumentFromStack(unsigned ArgNum, GPRReg scratchGPR) When ArgNum is just a function argument rather than a template argument, I suggest we use the traditional lowercased "argumentNumber", or "argNum" if the local tradition in this code is to use abbreviations rather than words (WebKit style generally is to prefer words). But also, why are we using a function argument rather than template argument here? Is there a good reason to mix styles like this? > Source/JavaScriptCore/jit/CCallHelpers.h:1018 > + constexpr int returnAdressOffset = 2; "address" is misspelled here > Source/JavaScriptCore/jit/CCallHelpers.h:1023 > + const int returnTypeOffset = sizeof(RESULT_TYPE) >= 8; > + const int offset = ArgNum - NUMBER_OF_ARGUMENT_REGISTERS + POKE_ARGUMENT_OFFSET + returnAdressOffset + returnTypeOffset; > +#else > + const int offset = ArgNum - NUMBER_OF_ARGUMENT_REGISTERS + POKE_ARGUMENT_OFFSET + returnAdressOffset; constexpr please But also, maybe we should define a returnTypeOffset of 0 for non-Windows-X86 rather than repeating the entire offset expression twice. > Source/JavaScriptCore/jit/CCallHelpers.h:1032 > +public: > + Here, we’d omit the blank line. > Source/JavaScriptCore/jit/CCallHelpers.h:1039 > + ASSERT(ArgNum <= 255, "C++ standard forbis functions with more than 256 arguments"); "forbids" Is misspelled here > Source/JavaScriptCore/runtime/RegExpInlines.h:149 > + Yarr::MatchingContextHolder regExpContext(vm, /* usesPatternContextBuffer: */ false, this, matchFrom); These comments are needed because we are not following the usual WebKit convention of using an enumeration for an argument like this where we often pass a constant value. That style is typically pretty easy to follow, although it does make the non-constant-value call sites a little wordy. > Source/JavaScriptCore/yarr/YarrJIT.h:276 > public: > + No blank line in a case like this. > Source/JavaScriptCore/yarr/YarrJIT.h:280 > + using YarrJITCode8 = SlowPathReturnType (*)(const LChar* input, UCPURegister start, UCPURegister length, int* output, MatchingContextHolder* matchingContext) YARR_CALL; > + using YarrJITCode16 = SlowPathReturnType (*)(const UChar* input, UCPURegister start, UCPURegister length, int* output, MatchingContextHolder* matchingContext) YARR_CALL; > + using YarrJITCodeMatchOnly8 = SlowPathReturnType (*)(const LChar* input, UCPURegister start, UCPURegister length, void*, MatchingContextHolder* matchingContext) YARR_CALL; > + using YarrJITCodeMatchOnly16 = SlowPathReturnType (*)(const UChar* input, UCPURegister start, UCPURegister length, void*, MatchingContextHolder* matchingContext) YARR_CALL; I suggests omitting the matchingContext argument name here since WebKit coding style tells us to do that when the type makes them unambiguous. > Source/JavaScriptCore/yarr/YarrJITRegisters.h:38 > public: > + Again, no blank line here in our coding style. Also, should just delete "public" since this is a struct.
Mikhail R. Gadelha
Comment 31 2022-01-13 12:08:42 PST
Comment on attachment 449068 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=449068&action=review >> Source/JavaScriptCore/jit/CCallHelpers.h:1001 >> + GPRReg loadArgumentFromStack(unsigned ArgNum, GPRReg scratchGPR) > > When ArgNum is just a function argument rather than a template argument, I suggest we use the traditional lowercased "argumentNumber", or "argNum" if the local tradition in this code is to use abbreviations rather than words (WebKit style generally is to prefer words). > > But also, why are we using a function argument rather than template argument here? Is there a good reason to mix styles like this? In the previous patch, ArgNum was a template argument but I revert as suggested in the previous review. >> Source/JavaScriptCore/jit/CCallHelpers.h:1023 >> + const int offset = ArgNum - NUMBER_OF_ARGUMENT_REGISTERS + POKE_ARGUMENT_OFFSET + returnAdressOffset; > > constexpr please > > But also, maybe we should define a returnTypeOffset of 0 for non-Windows-X86 rather than repeating the entire offset expression twice. I'll make ArgNum a template argument otherwise the compiler won't allow this to be a constexpr (it complains that ArgNum is not a constant).
Mikhail R. Gadelha
Comment 32 2022-01-13 12:10:31 PST
Mikhail R. Gadelha
Comment 33 2022-01-13 14:15:02 PST
Darin Adler
Comment 34 2022-01-14 09:55:10 PST
Comment on attachment 449108 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=449108&action=review > Source/JavaScriptCore/jit/CCallHelpers.h:1003 > + ASSERT(ArgNum >= NUMBER_OF_ARGUMENT_REGISTERS, "Should return GPRInfo::argumentGPRX"); This can/should be a static_assert. > Source/JavaScriptCore/jit/CCallHelpers.h:1037 > + ASSERT(ArgNum <= 255, "C++ standard forbids functions with more than 256 arguments"); This can/should be a static_assert. > Source/JavaScriptCore/jit/CCallHelpers.h:1038 > + ASSERT(FunctionTraits<OperationType>::cCallArity() > ArgNum, "Function does not have enough arguments"); This can/should be a static_assert.
Mikhail R. Gadelha
Comment 35 2022-01-14 11:47:42 PST
Yusuke Suzuki
Comment 36 2022-01-14 11:59:30 PST
Comment on attachment 449195 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=449195&action=review I think the updated code is breaking JITCage. Can you please do not change ARM64 / ARM64E code? > Source/JavaScriptCore/yarr/YarrJIT.cpp:-3996 > - if (!Options::useJITCage()) > - m_jit.tagReturnAddress(); This part is broken. You should not tag when JITCage is not enabled. But updated code is not following. > Source/JavaScriptCore/yarr/YarrJIT.cpp:4048 > + m_jit.untagReturnAddress(); Why is it added? > Source/JavaScriptCore/yarr/YarrJIT.cpp:4183 > + constexpr unsigned ArgNum = 4; We use `argNum` (instead of `ArgNum`) for constants. > Source/JavaScriptCore/yarr/YarrJITRegisters.h:-75 > - static constexpr GPRReg supplementaryPlanesBase = ARM64Registers::x12; > - static constexpr GPRReg leadingSurrogateTag = ARM64Registers::x13; > - static constexpr GPRReg trailingSurrogateTag = ARM64Registers::x14; I think using register is better for code size. Please do not change this.
Mikhail R. Gadelha
Comment 37 2022-01-14 12:14:03 PST
Comment on attachment 449195 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=449195&action=review >> Source/JavaScriptCore/yarr/YarrJIT.cpp:-3996 >> - m_jit.tagReturnAddress(); > > This part is broken. You should not tag when JITCage is not enabled. But updated code is not following. I see, the problem is that emitFunctionPrologue() always calls tagReturnAddress(). I'll special-case ARM64 then and revert to the original code. >> Source/JavaScriptCore/yarr/YarrJIT.cpp:4048 >> + m_jit.untagReturnAddress(); > > Why is it added? Suggested by a colleague, I'll remove it.
Mikhail R. Gadelha
Comment 38 2022-01-14 12:36:35 PST
Yusuke Suzuki
Comment 39 2022-01-14 12:38:35 PST
Comment on attachment 449208 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=449208&action=review > Source/JavaScriptCore/yarr/YarrJIT.cpp:3963 > +#if !CPU(ARM64) > + m_jit.emitFunctionPrologue(); > +#endif Why is this change necessary? It looks like rather it is introducing complication. > Source/JavaScriptCore/yarr/YarrJIT.cpp:4062 > + m_jit.emitFunctionEpilogue(); indentation is not correct. And why do we need this modification?
Geza Lore
Comment 40 2022-01-14 12:41:31 PST
Yusuke: 'emitFunctionPrologue' always tags the return address. We did not use to use this, but getting to the stacked arguments consistently without the frame pointer setup is a pain. So we now call 'emitFunctionPrologue', always. To do the tail call when the JITCage is used, we simply untag prior to the tail call. Should have the same effect.
Mikhail R. Gadelha
Comment 41 2022-01-14 12:46:27 PST
Comment on attachment 449208 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=449208&action=review >> Source/JavaScriptCore/yarr/YarrJIT.cpp:3963 >> +#endif > > Why is this change necessary? It looks like rather it is introducing complication. We need it so the frame pointer is properly set up in a way that is independent of the arch. The function loadArgumentFromStack needs the frame pointer to be set or it will fail to load the argument.
Yusuke Suzuki
Comment 42 2022-01-14 12:49:17 PST
(In reply to Mikhail R. Gadelha from comment #41) > Comment on attachment 449208 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=449208&action=review > > >> Source/JavaScriptCore/yarr/YarrJIT.cpp:3963 > >> +#endif > > > > Why is this change necessary? It looks like rather it is introducing complication. > > We need it so the frame pointer is properly set up in a way that is > independent of the arch. The function loadArgumentFromStack needs the frame > pointer to be set or it will fail to load the argument. Why cant’ we use stack pointer here? If we count # of pushes in prologue (as suggested in https://webkit.slack.com/archives/CTV4FGWF4/p1640206561238000?thread_ts=1640112033.226400&cid=CTV4FGWF4), we can use stack pointer to get the argument.
Mikhail R. Gadelha
Comment 43 2022-01-14 13:03:19 PST
(In reply to Yusuke Suzuki from comment #42) > (In reply to Mikhail R. Gadelha from comment #41) > > Comment on attachment 449208 [details] > > Patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=449208&action=review > > > > >> Source/JavaScriptCore/yarr/YarrJIT.cpp:3963 > > >> +#endif > > > > > > Why is this change necessary? It looks like rather it is introducing complication. > > > > We need it so the frame pointer is properly set up in a way that is > > independent of the arch. The function loadArgumentFromStack needs the frame > > pointer to be set or it will fail to load the argument. > > Why cant’ we use stack pointer here? If we count # of pushes in prologue (as > suggested in > https://webkit.slack.com/archives/CTV4FGWF4/ > p1640206561238000?thread_ts=1640112033.226400&cid=CTV4FGWF4), we can use > stack pointer to get the argument. We can use it but (In reply to Yusuke Suzuki from comment #42) > (In reply to Mikhail R. Gadelha from comment #41) > > Comment on attachment 449208 [details] > > Patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=449208&action=review > > > > >> Source/JavaScriptCore/yarr/YarrJIT.cpp:3963 > > >> +#endif > > > > > > Why is this change necessary? It looks like rather it is introducing complication. > > > > We need it so the frame pointer is properly set up in a way that is > > independent of the arch. The function loadArgumentFromStack needs the frame > > pointer to be set or it will fail to load the argument. > > Why cant’ we use stack pointer here? If we count # of pushes in prologue (as > suggested in > https://webkit.slack.com/archives/CTV4FGWF4/ > p1640206561238000?thread_ts=1640112033.226400&cid=CTV4FGWF4), we can use > stack pointer to get the argument. It just (In reply to Yusuke Suzuki from comment #42) > (In reply to Mikhail R. Gadelha from comment #41) > > Comment on attachment 449208 [details] > > Patch > > > > View in context: > > https://bugs.webkit.org/attachment.cgi?id=449208&action=review > > > > >> Source/JavaScriptCore/yarr/YarrJIT.cpp:3963 > > >> +#endif > > > > > > Why is this change necessary? It looks like rather it is introducing complication. > > > > We need it so the frame pointer is properly set up in a way that is > > independent of the arch. The function loadArgumentFromStack needs the frame > > pointer to be set or it will fail to load the argument. > > Why cant’ we use stack pointer here? If we count # of pushes in prologue (as > suggested in > https://webkit.slack.com/archives/CTV4FGWF4/ > p1640206561238000?thread_ts=1640112033.226400&cid=CTV4FGWF4), we can use > stack pointer to get the argument. We can but the current approach seems more robust because we have an arch-independent way of getting what we want: we simply need to set up frame pointer in the function prologue. The patch that counts the pushes looks worse IMHO (ignore the code not in generateEnter()): https://bugs.webkit.org/attachment.cgi?id=448434&action=review
Yusuke Suzuki
Comment 44 2022-01-14 13:11:20 PST
(In reply to Mikhail R. Gadelha from comment #43) > > We can but the current approach seems more robust because we have an > arch-independent way of getting what we want: we simply need to set up frame > pointer in the function prologue. > > The patch that counts the pushes looks worse IMHO (ignore the code not in > generateEnter()): > https://bugs.webkit.org/attachment.cgi?id=448434&action=review But this is adding unnecessary tagging and untagging, which can affect on, 1. machine code generation size 2. performance since RegExp code is tiny. So, even it is more robust, I don't think this is OK since it hurts performance.
Yusuke Suzuki
Comment 45 2022-01-15 13:26:23 PST
Comment on attachment 449208 [details] Patch So, since this is regressing ARM64 code, putting r-.
Mikhail R. Gadelha
Comment 46 2022-01-17 12:44:52 PST
Mikhail R. Gadelha
Comment 47 2022-01-18 16:43:11 PST
Mikhail R. Gadelha
Comment 48 2022-01-19 10:53:04 PST
Yusuke Suzuki
Comment 49 2022-01-21 20:15:28 PST
Comment on attachment 449495 [details] Patch r=me
EWS
Comment 50 2022-01-21 20:59:45 PST
Committed r288400 (246291@main): <https://commits.webkit.org/246291@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 449495 [details].
WebKit Commit Bot
Comment 51 2022-01-21 22:01:40 PST
Re-opened since this is blocked by bug 235470
Yusuke Suzuki
Comment 52 2022-01-21 22:04:51 PST
Reverted since it broke ARM64E build. According to Peng, the error is the following. /Volumes/Data/webkit/OpenSource/Source/JavaScriptCore/yarr/YarrJIT.h:335:32: error: no matching function for call to 'vmEntryToYarrJIT' return MatchResult(vmEntryToYarrJIT(input, start, length, output, &matchingContext, retagCodePtr<Yarr8BitPtrTag, YarrEntryPtrTag>(m_ref8.code().executableAddress())));
Mikhail R. Gadelha
Comment 53 2022-01-24 09:24:01 PST
Yusuke Suzuki
Comment 54 2022-01-24 14:49:10 PST
Comment on attachment 449825 [details] Patch r=me, nice.
EWS
Comment 55 2022-01-24 15:21:33 PST
Committed r288476 (246359@main): <https://commits.webkit.org/246359@main> All reviewed patches have been landed. Closing bug and clearing flags on attachment 449825 [details].
Note You need to log in before you can comment on or make changes to this bug.