Title: [287301] trunk/Source/_javascript_Core
Revision
287301
Author
[email protected]
Date
2021-12-21 00:33:18 -0800 (Tue, 21 Dec 2021)

Log Message

[JSC][ARMv7] Minor code size improvements
https://bugs.webkit.org/show_bug.cgi?id=234387

Patch by Geza Lore <[email protected]> on 2021-12-21
Reviewed by Yusuke Suzuki.

A few mew code size improvements to ARMv7/Thumb-2

- Use ldrd/strd in mode places (via AssemblyHelpers:loadValue
and AssemblyHelpers::storeValue)

- Use BIC immediate instruction instead of AND where appropriate

- Use a 2-byte ADDS instead of a 4-byte CMN when possible. This
applies very often as it handles testing JSValue tags.

- Use addressTempRegister in branch32

Overall saving of about 3.5% code size on JetStream2, according to
--dumpLinkBufferStats.

* assembler/ARMv7Assembler.h:
(JSC::ARMv7Assembler::bic):
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::and32):
(JSC::MacroAssemblerARMv7::storePair32):
(JSC::MacroAssemblerARMv7::compare32AndSetFlags):
(JSC::MacroAssemblerARMv7::branch32):
* assembler/MacroAssemblerMIPS.h:
(JSC::MacroAssemblerMIPS::storePair32):
* bytecode/AccessCase.cpp:
(JSC::AccessCase::generateImpl):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::compileExit):
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::fillJSValue):
(JSC::DFG::SpeculativeJIT::emitCall):
(JSC::DFG::SpeculativeJIT::compileGetByVal):
(JSC::DFG::SpeculativeJIT::compile):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::storeValue):
* jit/JITOpcodes.cpp:
(JSC::JIT::emit_op_mov):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (287300 => 287301)


--- trunk/Source/_javascript_Core/ChangeLog	2021-12-21 08:28:56 UTC (rev 287300)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-12-21 08:33:18 UTC (rev 287301)
@@ -1,3 +1,48 @@
+2021-12-21  Geza Lore  <[email protected]>
+
+        [JSC][ARMv7] Minor code size improvements
+        https://bugs.webkit.org/show_bug.cgi?id=234387
+
+        Reviewed by Yusuke Suzuki.
+
+        A few mew code size improvements to ARMv7/Thumb-2
+
+        - Use ldrd/strd in mode places (via AssemblyHelpers:loadValue
+        and AssemblyHelpers::storeValue)
+
+        - Use BIC immediate instruction instead of AND where appropriate
+
+        - Use a 2-byte ADDS instead of a 4-byte CMN when possible. This
+        applies very often as it handles testing JSValue tags.
+
+        - Use addressTempRegister in branch32
+
+        Overall saving of about 3.5% code size on JetStream2, according to
+        --dumpLinkBufferStats.
+
+        * assembler/ARMv7Assembler.h:
+        (JSC::ARMv7Assembler::bic):
+        * assembler/MacroAssemblerARMv7.h:
+        (JSC::MacroAssemblerARMv7::and32):
+        (JSC::MacroAssemblerARMv7::storePair32):
+        (JSC::MacroAssemblerARMv7::compare32AndSetFlags):
+        (JSC::MacroAssemblerARMv7::branch32):
+        * assembler/MacroAssemblerMIPS.h:
+        (JSC::MacroAssemblerMIPS::storePair32):
+        * bytecode/AccessCase.cpp:
+        (JSC::AccessCase::generateImpl):
+        * dfg/DFGOSRExit.cpp:
+        (JSC::DFG::OSRExit::compileExit):
+        * dfg/DFGSpeculativeJIT32_64.cpp:
+        (JSC::DFG::SpeculativeJIT::fillJSValue):
+        (JSC::DFG::SpeculativeJIT::emitCall):
+        (JSC::DFG::SpeculativeJIT::compileGetByVal):
+        (JSC::DFG::SpeculativeJIT::compile):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::storeValue):
+        * jit/JITOpcodes.cpp:
+        (JSC::JIT::emit_op_mov):
+
 2021-12-19  Ross Kirsling  <[email protected]>
 
         [JSC] OpPow should have a "small int exponent" fast path at lower tiers

Modified: trunk/Source/_javascript_Core/assembler/ARMv7Assembler.h (287300 => 287301)


--- trunk/Source/_javascript_Core/assembler/ARMv7Assembler.h	2021-12-21 08:28:56 UTC (rev 287300)
+++ trunk/Source/_javascript_Core/assembler/ARMv7Assembler.h	2021-12-21 08:33:18 UTC (rev 287301)
@@ -609,6 +609,7 @@
         OP_B_T4a        = 0xF000,
         OP_AND_imm_T1   = 0xF000,
         OP_TST_imm      = 0xF010,
+        OP_BIC_imm_T1   = 0xF020,
         OP_ORR_imm_T1   = 0xF040,
         OP_MOV_imm_T2   = 0xF040,
         OP_MVN_imm      = 0xF060,
@@ -932,6 +933,14 @@
         return m_formatter.label();
     }
 
+    ALWAYS_INLINE void bic(RegisterID rd, RegisterID rn, ARMThumbImmediate imm)
+    {
+        ASSERT(!BadReg(rd));
+        ASSERT(!BadReg(rn));
+        ASSERT(imm.isEncodedImm());
+        m_formatter.twoWordOp5i6Imm4Reg4EncodedImm(OP_BIC_imm_T1, rn, rd, imm);
+    }
+
     void bkpt(uint8_t imm = 0)
     {
         m_formatter.oneWordOp8Imm8(OP_BKPT, imm);

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h (287300 => 287301)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2021-12-21 08:28:56 UTC (rev 287300)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerARMv7.h	2021-12-21 08:33:18 UTC (rev 287301)
@@ -279,12 +279,19 @@
     void and32(TrustedImm32 imm, RegisterID src, RegisterID dest)
     {
         ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm.m_value);
-        if (armImm.isValid())
+        if (armImm.isValid()) {
             m_assembler.ARM_and(dest, src, armImm);
-        else {
-            move(imm, dataTempRegister);
-            m_assembler.ARM_and(dest, src, dataTempRegister);
+            return;
         }
+
+        armImm = ARMThumbImmediate::makeEncodedImm(~imm.m_value);
+        if (armImm.isValid()) {
+            m_assembler.bic(dest, src, armImm);
+            return;
+        }
+
+        move(imm, dataTempRegister);
+        m_assembler.ARM_and(dest, src, dataTempRegister);
     }
 
     void and32(RegisterID src, RegisterID dest)
@@ -1026,6 +1033,12 @@
         storePair32(src1, src2, Address(dataTempRegister, address.offset));
     }
 
+    void storePair32(RegisterID src1, RegisterID src2, const void* address)
+    {
+        move(TrustedImmPtr(address), addressTempRegister);
+        storePair32(src1, src2, addressTempRegister);
+    }
+
     // Possibly clobbers src, but not on this architecture.
     void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2)
     {
@@ -1587,15 +1600,25 @@
     {
         int32_t imm = right.m_value;
         ARMThumbImmediate armImm = ARMThumbImmediate::makeEncodedImm(imm);
-        if (armImm.isValid())
+        if (armImm.isValid()) {
             m_assembler.cmp(left, armImm);
-        else if ((armImm = ARMThumbImmediate::makeEncodedImm(-imm)).isValid())
+            return;
+        }
+
+        armImm = ARMThumbImmediate::makeEncodedImm(-imm);
+        if (armImm.isValid()) {
+            if (!(left & 8) && armImm.isUInt3() && (left != addressTempRegister)) {
+                // This is common enough to warrant a special case to save 2 bytes
+                m_assembler.add_S(addressTempRegister, left, armImm);
+                return;
+            }
             m_assembler.cmn(left, armImm);
-        else {
-            RegisterID scratch = bestTempRegister(left);
-            move(TrustedImm32(imm), scratch);
-            m_assembler.cmp(left, scratch);
+            return;
         }
+
+        RegisterID scratch = bestTempRegister(left);
+        move(TrustedImm32(imm), scratch);
+        m_assembler.cmp(left, scratch);
     }
 
     void add32Impl(TrustedImm32 imm, Address address, bool updateFlags = false)
@@ -1679,11 +1702,11 @@
     Jump branch32(RelationalCondition cond, RegisterID left, RegisterID right)
     {
         if (left == ARMRegisters::sp) {
-            move(left, dataTempRegister);
-            m_assembler.cmp(dataTempRegister, right);
+            move(left, addressTempRegister);
+            m_assembler.cmp(addressTempRegister, right);
         } else if (right == ARMRegisters::sp) {
-            move(right, dataTempRegister);
-            m_assembler.cmp(left, dataTempRegister);
+            move(right, addressTempRegister);
+            m_assembler.cmp(left, addressTempRegister);
         } else
             m_assembler.cmp(left, right);
         return Jump(makeBranch(cond));

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h (287300 => 287301)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h	2021-12-21 08:28:56 UTC (rev 287300)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerMIPS.h	2021-12-21 08:33:18 UTC (rev 287301)
@@ -1665,6 +1665,12 @@
         store32(src2, address.withOffset(4));
     }
 
+    void storePair32(RegisterID src1, RegisterID src2, const void* address)
+    {
+        move(TrustedImmPtr(address), addrTempRegister);
+        storePair32(src1, src2, addrTempRegister);
+    }
+
     // Floating-point operations:
 
     static bool supportsFloatingPoint()

Modified: trunk/Source/_javascript_Core/bytecode/AccessCase.cpp (287300 => 287301)


--- trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2021-12-21 08:28:56 UTC (rev 287300)
+++ trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2021-12-21 08:33:18 UTC (rev 287301)
@@ -1920,13 +1920,15 @@
                 CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset)), loadedValueGPR);
 #else
             if (m_type == Load || m_type == GetGetter) {
+                jit.loadValue(
+                    CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset)),
+                    JSValueRegs { valueRegs.tagGPR(), loadedValueGPR });
+
+            } else {
                 jit.load32(
-                    CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + TagOffset),
-                    valueRegs.tagGPR());
+                    CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + PayloadOffset),
+                    loadedValueGPR);
             }
-            jit.load32(
-                CCallHelpers::Address(storageGPR, offsetRelativeToBase(m_offset) + PayloadOffset),
-                loadedValueGPR);
 #endif
         }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp (287300 => 287301)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2021-12-21 08:28:56 UTC (rev 287300)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2021-12-21 08:33:18 UTC (rev 287301)
@@ -523,12 +523,7 @@
             break;
             
         case InPair:
-            jit.store32(
-                recovery.tagGPR(),
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag);
-            jit.store32(
-                recovery.payloadGPR(),
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload);
+            jit.storeValue(recovery.jsValueRegs(), scratch + index);
             break;
 #endif
 
@@ -579,24 +574,10 @@
 #if USE(JSVALUE64)
         case CellDisplacedInJSStack:
         case BooleanDisplacedInJSStack:
-            jit.load64(AssemblyHelpers::addressFor(recovery.virtualRegister()), GPRInfo::regT0);
-            jit.store64(GPRInfo::regT0, scratch + index);
+#endif
+            jit.loadValue(AssemblyHelpers::addressFor(recovery.virtualRegister()), JSRInfo::jsRegT10);
+            jit.storeValue(JSRInfo::jsRegT10, scratch + index);
             break;
-#else
-            jit.load32(
-                AssemblyHelpers::tagFor(recovery.virtualRegister()),
-                GPRInfo::regT0);
-            jit.load32(
-                AssemblyHelpers::payloadFor(recovery.virtualRegister()),
-                GPRInfo::regT1);
-            jit.store32(
-                GPRInfo::regT0,
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag);
-            jit.store32(
-                GPRInfo::regT1,
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload);
-            break;
-#endif
 
         case Constant: {
 #if USE(JSVALUE64)
@@ -607,12 +588,7 @@
             }
 #else // not USE(JSVALUE64)
             UNUSED_VARIABLE(firstTmpToRestoreEarly);
-            jit.store32(
-                AssemblyHelpers::TrustedImm32(recovery.constant().tag()),
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag);
-            jit.store32(
-                AssemblyHelpers::TrustedImm32(recovery.constant().payload()),
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload);
+            jit.storeValue(recovery.constant(), scratch + index, JSRInfo::jsRegT10);
 #endif
             break;
         }
@@ -639,13 +615,9 @@
 #else
             jit.load32(
                 AssemblyHelpers::payloadFor(recovery.virtualRegister()),
-                GPRInfo::regT0);
-            jit.store32(
-                AssemblyHelpers::TrustedImm32(JSValue::Int32Tag),
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag);
-            jit.store32(
-                GPRInfo::regT0,
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload);
+                JSRInfo::jsRegT10.payloadGPR());
+            jit.move(AssemblyHelpers::TrustedImm32(JSValue::Int32Tag), JSRInfo::jsRegT10.tagGPR());
+            jit.storeValue(JSRInfo::jsRegT10, scratch + index);
 #endif
             break;
 
@@ -659,13 +631,9 @@
         case BooleanDisplacedInJSStack:
             jit.load32(
                 AssemblyHelpers::payloadFor(recovery.virtualRegister()),
-                GPRInfo::regT0);
-            jit.store32(
-                AssemblyHelpers::TrustedImm32(JSValue::BooleanTag),
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag);
-            jit.store32(
-                GPRInfo::regT0,
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload);
+                JSRInfo::jsRegT10.payloadGPR());
+            jit.move(AssemblyHelpers::TrustedImm32(JSValue::BooleanTag), JSRInfo::jsRegT10.tagGPR());
+            jit.storeValue(JSRInfo::jsRegT10, scratch + index);
             break;
 
         case UnboxedCellInGPR:
@@ -677,13 +645,9 @@
         case CellDisplacedInJSStack:
             jit.load32(
                 AssemblyHelpers::payloadFor(recovery.virtualRegister()),
-                GPRInfo::regT0);
-            jit.store32(
-                AssemblyHelpers::TrustedImm32(JSValue::CellTag),
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag);
-            jit.store32(
-                GPRInfo::regT0,
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload);
+                JSRInfo::jsRegT10.payloadGPR());
+            jit.move(AssemblyHelpers::TrustedImm32(JSValue::CellTag), JSRInfo::jsRegT10.tagGPR());
+            jit.storeValue(JSRInfo::jsRegT10, scratch + index);
             break;
 #endif
 
@@ -848,18 +812,8 @@
             break;
 #else // not USE(JSVALUE64)
         case InPair:
-            jit.load32(
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.tag,
-                GPRInfo::regT0);
-            jit.load32(
-                &bitwise_cast<EncodedValueDescriptor*>(scratch + index)->asBits.payload,
-                GPRInfo::regT1);
-            jit.store32(
-                GPRInfo::regT0,
-                AssemblyHelpers::tagFor(operand));
-            jit.store32(
-                GPRInfo::regT1,
-                AssemblyHelpers::payloadFor(operand));
+            jit.loadValue(scratch + index, JSRInfo::jsRegT10);
+            jit.storeValue(JSRInfo::jsRegT10, AssemblyHelpers::addressFor(operand));
             break;
 #endif // USE(JSVALUE64)
 

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (287300 => 287301)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2021-12-21 08:28:56 UTC (rev 287300)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp	2021-12-21 08:33:18 UTC (rev 287301)
@@ -64,10 +64,10 @@
 
     switch (info.registerFormat()) {
     case DataFormatNone: {
+        payloadGPR = allocate();
+        tagGPR = allocate();
 
         if (edge->hasConstant()) {
-            tagGPR = allocate();
-            payloadGPR = allocate();
             JSValue value = edge->asJSValue();
             m_jit.move(Imm32(value.tag()), tagGPR);
             m_jit.move(Imm32(value.payload()), payloadGPR);
@@ -77,26 +77,26 @@
         } else {
             DataFormat spillFormat = info.spillFormat();
             ASSERT(spillFormat != DataFormatNone && spillFormat != DataFormatStorage);
-            tagGPR = allocate();
-            payloadGPR = allocate();
             switch (spillFormat) {
             case DataFormatInt32:
                 m_jit.move(TrustedImm32(JSValue::Int32Tag), tagGPR);
+                m_jit.load32(JITCompiler::payloadFor(virtualRegister), payloadGPR);
                 spillFormat = DataFormatJSInt32; // This will be used as the new register format.
                 break;
             case DataFormatCell:
                 m_jit.move(TrustedImm32(JSValue::CellTag), tagGPR);
+                m_jit.load32(JITCompiler::payloadFor(virtualRegister), payloadGPR);
                 spillFormat = DataFormatJSCell; // This will be used as the new register format.
                 break;
             case DataFormatBoolean:
                 m_jit.move(TrustedImm32(JSValue::BooleanTag), tagGPR);
+                m_jit.load32(JITCompiler::payloadFor(virtualRegister), payloadGPR);
                 spillFormat = DataFormatJSBoolean; // This will be used as the new register format.
                 break;
             default:
-                m_jit.load32(JITCompiler::tagFor(virtualRegister), tagGPR);
+                m_jit.loadValue(JITCompiler::addressFor(virtualRegister), JSValueRegs { tagGPR, payloadGPR });
                 break;
             }
-            m_jit.load32(JITCompiler::payloadFor(virtualRegister), payloadGPR);
             m_gprs.retain(tagGPR, virtualRegister, SpillOrderSpilled);
             m_gprs.retain(payloadGPR, virtualRegister, SpillOrderSpilled);
             info.fillJSValue(*m_stream, tagGPR, payloadGPR, spillFormat == DataFormatJSDouble ? DataFormatJS : spillFormat);
@@ -688,13 +688,11 @@
 
         // Now set up the "this" argument.
         JSValueOperand thisArgument(this, node->child2());
-        GPRReg thisArgumentTagGPR = thisArgument.tagGPR();
-        GPRReg thisArgumentPayloadGPR = thisArgument.payloadGPR();
+        JSValueRegs thisArgumentRegs = thisArgument.jsValueRegs();
         thisArgument.use();
         
-        m_jit.store32(thisArgumentTagGPR, JITCompiler::calleeArgumentTagSlot(0));
-        m_jit.store32(thisArgumentPayloadGPR, JITCompiler::calleeArgumentPayloadSlot(0));
-    } else {        
+        m_jit.storeValue(thisArgumentRegs, JITCompiler::calleeArgumentSlot(0));
+    } else {
         // The call instruction's first child is either the function (normal call) or the
         // receiver (method call). subsequent children are the arguments.
         numPassedArgs = node->numChildren() - 1;
@@ -750,12 +748,10 @@
             for (unsigned i = 0; i < numPassedArgs; i++) {
                 Edge argEdge = m_jit.graph().m_varArgChildren[node->firstChild() + 1 + i];
                 JSValueOperand arg(this, argEdge);
-                GPRReg argTagGPR = arg.tagGPR();
-                GPRReg argPayloadGPR = arg.payloadGPR();
+                JSValueRegs argRegs = arg.jsValueRegs();
                 use(argEdge);
-            
-                m_jit.store32(argTagGPR, m_jit.calleeArgumentTagSlot(i));
-                m_jit.store32(argPayloadGPR, m_jit.calleeArgumentPayloadSlot(i));
+
+                m_jit.storeValue(argRegs, m_jit.calleeArgumentSlot(i));
             }
             
             for (unsigned i = numPassedArgs; i < numAllocatedArgs; ++i)
@@ -767,10 +763,11 @@
         JSValueOperand callee(this, calleeEdge);
         calleeTagGPR = callee.tagGPR();
         calleePayloadGPR = callee.payloadGPR();
+        JSValueRegs calleRegs = callee.jsValueRegs();
         use(calleeEdge);
-        m_jit.store32(calleePayloadGPR, m_jit.calleeFramePayloadSlot(CallFrameSlot::callee));
-        m_jit.store32(calleeTagGPR, m_jit.calleeFrameTagSlot(CallFrameSlot::callee));
 
+        m_jit.storeValue(calleRegs, m_jit.calleeFrameSlot(CallFrameSlot::callee));
+
         if (!isTail)
             flushRegisters();
     }
@@ -827,8 +824,7 @@
         
         // This is the part where we meant to make a normal call. Oops.
         m_jit.addPtr(TrustedImm32(requiredBytes), JITCompiler::stackPointerRegister);
-        m_jit.load32(JITCompiler::calleeFrameSlot(CallFrameSlot::callee).withOffset(PayloadOffset), GPRInfo::regT0);
-        m_jit.load32(JITCompiler::calleeFrameSlot(CallFrameSlot::callee).withOffset(TagOffset), GPRInfo::regT1);
+        m_jit.loadValue(JITCompiler::calleeFrameSlot(CallFrameSlot::callee), JSValueRegs { GPRInfo::regT1, GPRInfo::regT0 });
         m_jit.emitVirtualCall(vm(), globalObject, info);
         
         done.link(&m_jit);
@@ -1906,18 +1902,12 @@
             }
 
             ASSERT(format == DataFormatJS);
-            m_jit.load32(
-                MacroAssembler::BaseIndex(
-                    storageReg, propertyReg, MacroAssembler::TimesEight, TagOffset),
-                resultRegs.tagGPR());
-            m_jit.load32(
-                MacroAssembler::BaseIndex(
-                    storageReg, propertyReg, MacroAssembler::TimesEight, PayloadOffset),
-                resultRegs.payloadGPR());
+            m_jit.loadValue(
+                MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesEight),
+                resultRegs);
             if (node->arrayMode().isInBoundsSaneChain()) {
                 JITCompiler::Jump notHole = m_jit.branchIfNotEmpty(resultRegs.tagGPR());
-                m_jit.move(TrustedImm32(JSValue::UndefinedTag), resultRegs.tagGPR());
-                m_jit.move(TrustedImm32(0), resultRegs.payloadGPR());
+                m_jit.moveTrustedValue(jsUndefined(), resultRegs);
                 notHole.link(&m_jit);
             } else {
                 speculationCheck(
@@ -2203,18 +2193,16 @@
         }
             
         case FlushedJSValue: {
-            GPRTemporary result(this);
-            GPRTemporary tag(this);
-            m_jit.load32(JITCompiler::payloadFor(node->machineLocal()), result.gpr());
-            m_jit.load32(JITCompiler::tagFor(node->machineLocal()), tag.gpr());
-            
+            JSValueRegsTemporary result(this);
+            m_jit.loadValue(JITCompiler::addressFor(node->machineLocal()), result.regs());
+
             // Like jsValueResult, but don't useChildren - our children are phi nodes,
             // and don't represent values within this dataflow with virtual registers.
             VirtualRegister virtualRegister = node->virtualRegister();
-            m_gprs.retain(result.gpr(), virtualRegister, SpillOrderJS);
-            m_gprs.retain(tag.gpr(), virtualRegister, SpillOrderJS);
+            m_gprs.retain(result.regs().payloadGPR(), virtualRegister, SpillOrderJS);
+            m_gprs.retain(result.regs().tagGPR(), virtualRegister, SpillOrderJS);
             
-            generationInfoFromVirtualRegister(virtualRegister).initJSValue(node, node->refCount(), tag.gpr(), result.gpr(), DataFormatJS);
+            generationInfoFromVirtualRegister(virtualRegister).initJSValue(node, node->refCount(), result.regs().tagGPR(), result.regs().payloadGPR(), DataFormatJS);
             break;
         }
             
@@ -2275,8 +2263,8 @@
             
         case FlushedJSValue: {
             JSValueOperand value(this, node->child1());
-            m_jit.store32(value.payloadGPR(), JITCompiler::payloadFor(node->machineLocal()));
-            m_jit.store32(value.tagGPR(), JITCompiler::tagFor(node->machineLocal()));
+            JSValueRegs valueRegs = value.jsValueRegs();
+            m_jit.storeValue(valueRegs, JITCompiler::addressFor(node->machineLocal()));
             noResult(node);
             recordSetLocal(dataFormatFor(node->variableAccessData()->flushFormat()));
             break;
@@ -2787,12 +2775,9 @@
                 tempFPR);
             MacroAssembler::Jump slowCase = m_jit.branchIfNaN(tempFPR);
             JSValue nan = JSValue(JSValue::EncodeAsDouble, PNaN);
-            m_jit.store32(
-                MacroAssembler::TrustedImm32(nan.u.asBits.tag),
-                MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.tag)));
-            m_jit.store32(
-                MacroAssembler::TrustedImm32(nan.u.asBits.payload),
-                MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight, OBJECT_OFFSETOF(JSValue, u.asBits.payload)));
+            m_jit.storeTrustedValue(
+                nan,
+                MacroAssembler::BaseIndex(storageGPR, valuePayloadGPR, MacroAssembler::TimesEight));
             boxDouble(tempFPR, valueTagGPR, valuePayloadGPR);
 
             addSlowPathGenerator(
@@ -2821,10 +2806,9 @@
             m_jit.sub32(TrustedImm32(1), storageLengthGPR);
         
             MacroAssembler::Jump slowCase = m_jit.branch32(MacroAssembler::AboveOrEqual, storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::vectorLengthOffset()));
+
+            m_jit.loadValue(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset()), JSValueRegs { valueTagGPR, valuePayloadGPR });
         
-            m_jit.load32(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), valueTagGPR);
-            m_jit.load32(MacroAssembler::BaseIndex(storageGPR, storageLengthGPR, MacroAssembler::TimesEight, ArrayStorage::vectorOffset() + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), valuePayloadGPR);
-        
             m_jit.store32(storageLengthGPR, MacroAssembler::Address(storageGPR, ArrayStorage::lengthOffset()));
 
             setUndefinedCases.append(m_jit.branchIfEmpty(valueTagGPR));

Modified: trunk/Source/_javascript_Core/jit/AssemblyHelpers.h (287300 => 287301)


--- trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2021-12-21 08:28:56 UTC (rev 287300)
+++ trunk/Source/_javascript_Core/jit/AssemblyHelpers.h	2021-12-21 08:33:18 UTC (rev 287301)
@@ -184,8 +184,8 @@
 #if USE(JSVALUE64)
         store64(regs.gpr(), address);
 #else
-        store32(regs.payloadGPR(), bitwise_cast<void*>(bitwise_cast<uintptr_t>(address) + PayloadOffset));
-        store32(regs.tagGPR(), bitwise_cast<void*>(bitwise_cast<uintptr_t>(address) + TagOffset));
+        static_assert(!PayloadOffset && TagOffset == 4, "Assumes little-endian system");
+        storePair32(regs.payloadGPR(), regs.tagGPR(), address);
 #endif
     }
 
@@ -262,16 +262,27 @@
 #endif
     }
 
-    void storeValue(JSValue value, Address address)
+    void storeValue(JSValue value, Address address, JSValueRegs tmpJSR)
     {
 #if USE(JSVALUE64)
+        UNUSED_PARAM(tmpJSR);
         store64(Imm64(JSValue::encode(value)), address);
 #elif USE(JSVALUE32_64)
-        store32(Imm32(value.tag()), address.withOffset(TagOffset));
-        store32(Imm32(value.payload()), address.withOffset(PayloadOffset));
+        // Can implement this without the tmpJSR, but using it yields denser code.
+        moveValue(value, tmpJSR);
+        storeValue(tmpJSR, address);
 #endif
     }
 
+#if USE(JSVALUE32_64)
+    void storeValue(JSValue value, void* address, JSValueRegs tmpJSR)
+    {
+        // Can implement this without the tmpJSR, but using it yields denser code.
+        moveValue(value, tmpJSR);
+        storeValue(tmpJSR, address);
+    }
+#endif
+
     void storeTrustedValue(JSValue value, Address address)
     {
 #if USE(JSVALUE64)

Modified: trunk/Source/_javascript_Core/jit/JITOpcodes.cpp (287300 => 287301)


--- trunk/Source/_javascript_Core/jit/JITOpcodes.cpp	2021-12-21 08:28:56 UTC (rev 287300)
+++ trunk/Source/_javascript_Core/jit/JITOpcodes.cpp	2021-12-21 08:33:18 UTC (rev 287301)
@@ -53,7 +53,7 @@
 
     if (src.isConstant()) {
         if (m_profiledCodeBlock->isConstantOwnedByUnlinkedCodeBlock(src)) {
-            storeValue(m_unlinkedCodeBlock->getConstant(src), addressFor(dst));
+            storeValue(m_unlinkedCodeBlock->getConstant(src), addressFor(dst), jsRegT10);
         } else {
             loadCodeBlockConstant(src, jsRegT10);
             storeValue(jsRegT10, addressFor(dst));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to