Ignore:
Timestamp:
Oct 27, 2021, 8:34:42 AM (4 years ago)
Author:
[email protected]
Message:

[JSC][32bit] Fix CSR restore on DFG tail calls, add extra register on ARMv7
https://bugs.webkit.org/show_bug.cgi?id=230622

Patch by Geza Lore <Geza Lore> on 2021-10-27
Reviewed by Keith Miller.

This re-introduces the patch reverted by
https://trac.webkit.org/changeset/284911/webkit
with the C_LOOP interpreter now fixed.

The only difference between the original patch and this version is in
LowLevelInterpreter32_64.asm and LowLevelInterpreter64.asm, which
need the PC base (PB) register restored on C_LOOP on return from a
call, as C_LOOP does not seem to handle this as a proper callee save
register (CSR). On non C_LOOP builds, the CSR restore mechanism takes
care of this, so removed the superfluous instructions.

--- Original ChangeLog ---

This patch does two things:

  1. Adds an extra callee save register (CSR) to be available to DFG on

ARMv7. To do this properly required the following:

  1. Implements the necessary shuffling in CallFrameShuffler on 32-bit

architectures that is required to restore CSRs properly after a tail
call on these architectures. This also fixes the remaining failures in
the 32-bit build of the unlinked baseline JIT.

  • bytecode/ValueRecovery.cpp:

(JSC::ValueRecovery::dumpInContext const):

  • bytecode/ValueRecovery.h:

(JSC::ValueRecovery::calleeSaveRegDisplacedInJSStack):
(JSC::ValueRecovery::isInJSStack const):
(JSC::ValueRecovery::dataFormat const):
(JSC::ValueRecovery::withLocalsOffset const):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::emitCall):

  • jit/CachedRecovery.cpp:

(JSC::CachedRecovery::loadsIntoGPR const):

  • jit/CallFrameShuffleData.cpp:

(JSC::CallFrameShuffleData::setupCalleeSaveRegisters):

  • jit/CallFrameShuffleData.h:
  • jit/CallFrameShuffler.cpp:

(JSC::CallFrameShuffler::CallFrameShuffler):

  • jit/CallFrameShuffler.h:

(JSC::CallFrameShuffler::snapshot const):
(JSC::CallFrameShuffler::addNew):

  • jit/CallFrameShuffler32_64.cpp:

(JSC::CallFrameShuffler::emitLoad):
(JSC::CallFrameShuffler::emitDisplace):

  • jit/GPRInfo.h:

(JSC::GPRInfo::toRegister):
(JSC::GPRInfo::toIndex):

  • jit/RegisterSet.cpp:

(JSC::RegisterSet::dfgCalleeSaveRegisters):

  • llint/LowLevelInterpreter32_64.asm:
  • llint/LowLevelInterpreter64.asm:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/jit/CallFrameShuffleData.cpp

    r284911 r284923  
    3434namespace JSC {
    3535
    36 #if USE(JSVALUE64)
    37 
    3836void CallFrameShuffleData::setupCalleeSaveRegisters(CodeBlock* codeBlock)
    3937{
     
    5048            continue;
    5149
    52         VirtualRegister saveSlot { entry.offsetAsIndex() };
     50        int saveSlotIndexInCPURegisters = entry.offsetAsIndex();
     51
     52#if USE(JSVALUE64)
     53        // CPU registers are the same size as virtual registers
     54        VirtualRegister saveSlot { saveSlotIndexInCPURegisters };
    5355        registers[entry.reg()]
    5456            = ValueRecovery::displacedInJSStack(saveSlot, DataFormatJS);
     57#elif USE(JSVALUE32_64)
     58        // On 32-bit architectures, 2 callee saved registers may be packed into the same slot
     59        static_assert(!PayloadOffset || !TagOffset);
     60        static_assert(PayloadOffset == 4 || TagOffset == 4);
     61        bool inTag = (saveSlotIndexInCPURegisters & 1) == !!TagOffset;
     62        if (saveSlotIndexInCPURegisters < 0)
     63            saveSlotIndexInCPURegisters -= 1; // Round towards -inf
     64        VirtualRegister saveSlot { saveSlotIndexInCPURegisters / 2 };
     65        registers[entry.reg()]
     66            = ValueRecovery::calleeSaveRegDisplacedInJSStack(saveSlot, inTag);
     67#endif
    5568    }
    5669
     
    6275            continue;
    6376
     77#if USE(JSVALUE64)
    6478        registers[reg] = ValueRecovery::inRegister(reg, DataFormatJS);
     79#elif USE(JSVALUE32_64)
     80        registers[reg] = ValueRecovery::inRegister(reg, DataFormatInt32);
     81#endif
    6582    }
    6683}
    67 
    68 #endif // USE(JSVALUE64)
    6984
    7085} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.