RESOLVED FIXED206611
[ARMv7][JIT] Implement checkpoint support
https://bugs.webkit.org/show_bug.cgi?id=206611
Summary [ARMv7][JIT] Implement checkpoint support
Caio Lima
Reported 2020-01-22 13:52:49 PST
...
Attachments
WIP - Patch (4.27 KB, patch)
2020-01-22 14:26 PST, Caio Lima
no flags
Patch (6.62 KB, patch)
2020-01-22 16:48 PST, Caio Lima
no flags
Patch (9.29 KB, patch)
2020-01-23 05:22 PST, Caio Lima
no flags
Patch (10.47 KB, patch)
2020-01-23 14:25 PST, Caio Lima
no flags
Patch (10.58 KB, patch)
2020-01-24 03:56 PST, Caio Lima
no flags
Patch (10.61 KB, patch)
2020-01-24 10:03 PST, Caio Lima
no flags
Caio Lima
Comment 1 2020-01-22 14:26:23 PST
Created attachment 388469 [details] WIP - Patch This patch depends on patch uploaded on https://bugs.webkit.org/show_bug.cgi?id=206603 to fix build of JIT on 32-bit ports.
Caio Lima
Comment 2 2020-01-22 16:48:18 PST
Caio Lima
Comment 3 2020-01-23 05:22:13 PST
Yusuke Suzuki
Comment 4 2020-01-23 06:19:17 PST
Comment on attachment 388535 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388535&action=review Added comment. > Source/JavaScriptCore/dfg/DFGOSREntry.cpp:310 > +#if USE(JSVALUE64) Let's avoid adding `USE(JSVALUE64)` / `USE(JSVALUE32_64)` as much as possible when adding a new code. Use headerSizeInRegisters's number instead. And we are also using `pivot` in the code above. Why is it OK?
Caio Lima
Comment 5 2020-01-23 06:59:56 PST
Comment on attachment 388535 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388535&action=review >> Source/JavaScriptCore/dfg/DFGOSREntry.cpp:310 >> +#if USE(JSVALUE64) > > Let's avoid adding `USE(JSVALUE64)` / `USE(JSVALUE32_64)` as much as possible when adding a new code. Use headerSizeInRegisters's number instead. > And we are also using `pivot` in the code above. Why is it OK? I'll update as requested, but I think current math for 32-bits is not correct yet. The usage of `pivot` before is fine because it will copy the entire CallFrame after the first 16-bytes of scratch. The problem is that on 32-bits, due to sizeof(intptr_t) == 4, the operation `bitwise_cast<intptr_t*>(pivot - 1) + currentEntry.offsetAsIndex())` will clobber the last 4-bytes of pivot[-1](that points to ReturnPC) when offsetAsIndex is 1, while it will properly place value on pivot[0] on 64-bits. What we need to do is to place callee-save registers starting at pivot[0]. I'm illustrating below how we would like to have pivot populated on each architecture. 64-bits pivot[-5] = ArgumentCountIncludingThis pivot[-4] = Callee pivot[-3] = CodeBlock pivot[-2] = ReturnPC pivot[-1] = callerFrame pivot[0] = csr0 ... On 32-bits it needs to be pivot[-4] = ArgumentCountIncludingThis pivot[-3] = Callee pivot[-2] = CodeBlock pivot[-1] = CallerFrameAndReturnPC pivot[0] = csr0/csr1 ... Current code is leaving a hole of 4-bytes on `pivot[0]`.
Caio Lima
Comment 6 2020-01-23 14:25:44 PST
Yusuke Suzuki
Comment 7 2020-01-24 01:45:48 PST
Comment on attachment 388590 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388590&action=review Looks good, but put r- since I found some nits. > Source/JavaScriptCore/dfg/DFGOSREntry.cpp:310 > + if (sizeof(intptr_t) == 8) This is not correct. In ARM64_32, we are using two 8 bytes slots for callFrame and PC while `sizeof(intptr_t) == 4`. See comment in CallFrame.h. > Source/JavaScriptCore/dfg/DFGOSRExit.cpp:615 > + case InPair: This only exists for 32_64. So, let's write #if USE(JSVALUE32_64) case InPair: #endif instead of using `#else` of `#if USE(JSVALUE64)`. > Source/JavaScriptCore/dfg/DFGOSRExit.cpp:634 > +#endif > + case BooleanDisplacedInJSStack: > + case CellDisplacedInJSStack: > case DisplacedInJSStack: { > sideState->tmps[i] = reinterpret_cast<JSValue*>(tmpScratch)[i + tmpOffset]; > break; > } > +#if USE(JSVALUE32_64) > + case UnboxedCellInGPR: { > + EncodedValueDescriptor* valueDescriptor = bitwise_cast<EncodedValueDescriptor*>(tmpScratch + i + tmpOffset); > + sideState->tmps[i] = JSValue(JSValue::CellTag, valueDescriptor->asBits.payload); > + break; > + } > + > + case UnboxedBooleanInGPR: { > + sideState->tmps[i] = jsBoolean(static_cast<bool>(tmpScratch[i + tmpOffset])); > + break; > + } > +#endif Having the same entries switched by `ifdef` is hard to read. Let's write it in a simpler way, like this. case UnboxedCellInGPR: { #if USE(JSVALUE64) sideState->tmps[i] = reinterpret_cast<JSValue*>(tmpScratch)[i + tmpOffset]; #else EncodedValueDescriptor* valueDescriptor = bitwise_cast<EncodedValueDescriptor*>(tmpScratch + i + tmpOffset); sideState->tmps[i] = JSValue(JSValue::CellTag, valueDescriptor->asBits.payload); #endif break; }
Caio Lima
Comment 8 2020-01-24 03:56:19 PST
Caio Lima
Comment 9 2020-01-24 04:42:49 PST
Comment on attachment 388590 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388590&action=review Thank you very much for the review. >> Source/JavaScriptCore/dfg/DFGOSREntry.cpp:310 >> + if (sizeof(intptr_t) == 8) > > This is not correct. In ARM64_32, we are using two 8 bytes slots for callFrame and PC while `sizeof(intptr_t) == 4`. See comment in CallFrame.h. I see. I was not aware of this architecture until now. Do we use JIT on ARM64_32? I'm changing this condition to check CallFrame::headerSizeInSlots, but none of those operations will work properly on ARM64_32. >> Source/JavaScriptCore/dfg/DFGOSRExit.cpp:615 >> + case InPair: > > This only exists for 32_64. So, let's write > > #if USE(JSVALUE32_64) > case InPair: > #endif > > instead of using `#else` of `#if USE(JSVALUE64)`. Done. >> Source/JavaScriptCore/dfg/DFGOSRExit.cpp:634 >> +#endif > > Having the same entries switched by `ifdef` is hard to read. Let's write it in a simpler way, like this. > > case UnboxedCellInGPR: { > #if USE(JSVALUE64) > sideState->tmps[i] = reinterpret_cast<JSValue*>(tmpScratch)[i + tmpOffset]; > #else > EncodedValueDescriptor* valueDescriptor = bitwise_cast<EncodedValueDescriptor*>(tmpScratch + i + tmpOffset); > sideState->tmps[i] = JSValue(JSValue::CellTag, valueDescriptor->asBits.payload); > #endif > break; > } Done.
Yusuke Suzuki
Comment 10 2020-01-24 05:13:34 PST
Comment on attachment 388590 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388590&action=review >>> Source/JavaScriptCore/dfg/DFGOSREntry.cpp:310 >>> + if (sizeof(intptr_t) == 8) >> >> This is not correct. In ARM64_32, we are using two 8 bytes slots for callFrame and PC while `sizeof(intptr_t) == 4`. See comment in CallFrame.h. > > I see. I was not aware of this architecture until now. Do we use JIT on ARM64_32? I'm changing this condition to check CallFrame::headerSizeInSlots, but none of those operations will work properly on ARM64_32. We are not using JIT for ARM64_32 while we are using LLInt. But we are aware of this architecture and I don't think using `sizeof(intptr_t)` here is a good idea.
Yusuke Suzuki
Comment 11 2020-01-24 05:19:25 PST
Comment on attachment 388671 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388671&action=review r=me with nits. > Source/JavaScriptCore/dfg/DFGOSREntry.cpp:310 > + if (CallFrame::headerSizeInRegisters == 5) Let's use if constexpr (CallFrame::CallerFrameAndPC::sizeInRegisters == 2) { } else { } Since CallerFrameAndPC is the problematic part. > Source/JavaScriptCore/jit/GPRInfo.h:536 > + static constexpr unsigned numberOfRegisters = 9; Nice.
Caio Lima
Comment 12 2020-01-24 05:20:16 PST
(In reply to Yusuke Suzuki from comment #10) > Comment on attachment 388590 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=388590&action=review > > >>> Source/JavaScriptCore/dfg/DFGOSREntry.cpp:310 > >>> + if (sizeof(intptr_t) == 8) > >> > >> This is not correct. In ARM64_32, we are using two 8 bytes slots for callFrame and PC while `sizeof(intptr_t) == 4`. See comment in CallFrame.h. > > > > I see. I was not aware of this architecture until now. Do we use JIT on ARM64_32? I'm changing this condition to check CallFrame::headerSizeInSlots, but none of those operations will work properly on ARM64_32. > > We are not using JIT for ARM64_32 while we are using LLInt. But we are aware > of this architecture and I don't think using `sizeof(intptr_t)` here is a > good idea. Thanks for the heads up and I agree. I updated the patch to use `headerSizeInRegisters` instead and placed some assertions there as well. BTW< I saw the comment in CallFrame.h before, but my understanding was that caller frame and return pc together uses 8 bytes (like it is on ARMv7 and MIPS). Maybe we should change it to `arm64_32 expects caller frame and return pc to use 8 bytes each`.
Caio Lima
Comment 13 2020-01-24 10:03:55 PST
Caio Lima
Comment 14 2020-01-24 11:09:07 PST
Comment on attachment 388671 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=388671&action=review Thanks again for the review. >> Source/JavaScriptCore/dfg/DFGOSREntry.cpp:310 >> + if (CallFrame::headerSizeInRegisters == 5) > > Let's use > > if constexpr (CallFrame::CallerFrameAndPC::sizeInRegisters == 2) { > } else { > } > > Since CallerFrameAndPC is the problematic part. Done.
WebKit Commit Bot
Comment 15 2020-01-24 12:26:53 PST
Comment on attachment 388706 [details] Patch Clearing flags on attachment: 388706 Committed r255088: <https://trac.webkit.org/changeset/255088>
WebKit Commit Bot
Comment 16 2020-01-24 12:26:55 PST
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 17 2020-01-24 12:27:13 PST
Note You need to log in before you can comment on or make changes to this bug.