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));