зеркало из https://github.com/mozilla/pjs.git
Faster x64 Syncing. b=598839, r=dvander.
This commit is contained in:
Родитель
3e6a7c4147
Коммит
ec609ce9f8
|
@ -46,7 +46,7 @@
|
|||
#elif defined JS_PUNBOX64
|
||||
# include "PunboxAssembler.h"
|
||||
#else
|
||||
# error "Neither JS_NUNBOX32 nor JS_PUNBOX32 is defined."
|
||||
# error "Neither JS_NUNBOX32 nor JS_PUNBOX64 is defined."
|
||||
#endif
|
||||
|
||||
/* Get a label for assertion purposes. Prevent #ifdef clutter. */
|
||||
|
|
|
@ -1008,8 +1008,8 @@ mjit::Compiler::jsop_equality_int_string(JSOp op, BoolStub stub, jsbytecode *tar
|
|||
JaegerSpew(JSpew_Insns, " ---- BEGIN STUB CALL CODE ---- \n");
|
||||
|
||||
/* The lhs/rhs need to be synced in the stub call path. */
|
||||
frame.syncEntry(stubcc.masm, lhs, lvr);
|
||||
frame.syncEntry(stubcc.masm, rhs, rvr);
|
||||
frame.ensureValueSynced(stubcc.masm, lhs, lvr);
|
||||
frame.ensureValueSynced(stubcc.masm, rhs, rvr);
|
||||
|
||||
/* Call the stub, adjusting for the two values just pushed. */
|
||||
stubcc.call(stub, frame.stackDepth() + script->nfixed + 2);
|
||||
|
|
|
@ -1643,13 +1643,11 @@ mjit::Compiler::jsop_stricteq(JSOp op)
|
|||
masm.set32(cond, frame.tempRegForType(test), Imm32(mask), result);
|
||||
#elif defined JS_CPU_X64
|
||||
RegisterID maskReg = frame.allocReg();
|
||||
frame.pinReg(maskReg);
|
||||
|
||||
masm.move(ImmTag(known->getKnownTag()), maskReg);
|
||||
|
||||
RegisterID r = frame.tempRegForType(test);
|
||||
masm.setPtr(cond, r, maskReg, result);
|
||||
|
||||
frame.unpinReg(maskReg);
|
||||
frame.freeReg(maskReg);
|
||||
#endif
|
||||
frame.popn(2);
|
||||
|
|
|
@ -195,6 +195,7 @@ class FrameEntry
|
|||
|
||||
FrameEntry *copyOf() const {
|
||||
JS_ASSERT(isCopy());
|
||||
JS_ASSERT(copy < this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
|
|
@ -126,20 +126,6 @@ FrameState::allocReg(FrameEntry *fe, RematInfo::RematType type)
|
|||
return reg;
|
||||
}
|
||||
|
||||
inline void
|
||||
FrameState::emitLoadTypeTag(FrameEntry *fe, RegisterID reg) const
|
||||
{
|
||||
emitLoadTypeTag(this->masm, fe, reg);
|
||||
}
|
||||
|
||||
inline void
|
||||
FrameState::emitLoadTypeTag(Assembler &masm, FrameEntry *fe, RegisterID reg) const
|
||||
{
|
||||
if (fe->isCopy())
|
||||
fe = fe->copyOf();
|
||||
masm.loadTypeTag(addressOf(fe), reg);
|
||||
}
|
||||
|
||||
inline void
|
||||
FrameState::convertInt32ToDouble(Assembler &masm, FrameEntry *fe, FPRegisterID fpreg) const
|
||||
{
|
||||
|
@ -485,33 +471,188 @@ FrameState::shouldAvoidDataRemat(FrameEntry *fe)
|
|||
}
|
||||
|
||||
inline void
|
||||
FrameState::syncType(const FrameEntry *fe, Address to, Assembler &masm) const
|
||||
FrameState::ensureFeSynced(const FrameEntry *fe, Assembler &masm) const
|
||||
{
|
||||
JS_ASSERT_IF(fe->type.synced(),
|
||||
fe->isCopied() && addressOf(fe).offset != to.offset);
|
||||
JS_ASSERT(fe->type.inRegister() || fe->type.isConstant());
|
||||
Address to = addressOf(fe);
|
||||
const FrameEntry *backing = fe;
|
||||
if (fe->isCopy())
|
||||
backing = fe->copyOf();
|
||||
|
||||
/* Store a double's type bits, even though !isTypeKnown(). */
|
||||
if (fe->isConstant())
|
||||
masm.storeTypeTag(ImmTag(fe->getKnownTag()), to);
|
||||
else if (fe->isTypeKnown())
|
||||
masm.storeTypeTag(ImmType(fe->getKnownType()), to);
|
||||
else
|
||||
masm.storeTypeTag(fe->type.reg(), to);
|
||||
#if defined JS_PUNBOX64
|
||||
/* If we can, sync the type and data in one go. */
|
||||
if (!fe->data.synced() && !fe->type.synced()) {
|
||||
if (backing->isConstant())
|
||||
masm.storeValue(backing->getValue(), to);
|
||||
else if (backing->isTypeKnown())
|
||||
masm.storeValueFromComponents(ImmType(backing->getKnownType()), backing->data.reg(), to);
|
||||
else
|
||||
masm.storeValueFromComponents(backing->type.reg(), backing->data.reg(), to);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On x86_64, only one of the following two calls will have output,
|
||||
* and a load will only occur if necessary.
|
||||
*/
|
||||
ensureDataSynced(fe, masm);
|
||||
ensureTypeSynced(fe, masm);
|
||||
}
|
||||
|
||||
inline void
|
||||
FrameState::syncData(const FrameEntry *fe, Address to, Assembler &masm) const
|
||||
FrameState::ensureTypeSynced(const FrameEntry *fe, Assembler &masm) const
|
||||
{
|
||||
JS_ASSERT_IF(addressOf(fe).base == to.base &&
|
||||
addressOf(fe).offset == to.offset,
|
||||
!fe->data.synced());
|
||||
JS_ASSERT(fe->data.inRegister() || fe->data.isConstant());
|
||||
if (fe->type.synced())
|
||||
return;
|
||||
|
||||
if (fe->data.isConstant())
|
||||
masm.storePayload(ImmPayload(fe->getPayload()), to);
|
||||
Address to = addressOf(fe);
|
||||
const FrameEntry *backing = fe;
|
||||
if (fe->isCopy())
|
||||
backing = fe->copyOf();
|
||||
|
||||
#if defined JS_PUNBOX64
|
||||
/* Attempt to store the entire Value, to prevent a load. */
|
||||
if (backing->isConstant()) {
|
||||
masm.storeValue(backing->getValue(), to);
|
||||
return;
|
||||
}
|
||||
|
||||
if (backing->data.inRegister()) {
|
||||
RegisterID dreg = backing->data.reg();
|
||||
if (backing->isTypeKnown())
|
||||
masm.storeValueFromComponents(ImmType(backing->getKnownType()), dreg, to);
|
||||
else
|
||||
masm.storeValueFromComponents(backing->type.reg(), dreg, to);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Store a double's type bits, even though !isTypeKnown(). */
|
||||
if (backing->isConstant())
|
||||
masm.storeTypeTag(ImmTag(backing->getKnownTag()), to);
|
||||
else if (backing->isTypeKnown())
|
||||
masm.storeTypeTag(ImmType(backing->getKnownType()), to);
|
||||
else
|
||||
masm.storePayload(fe->data.reg(), to);
|
||||
masm.storeTypeTag(backing->type.reg(), to);
|
||||
}
|
||||
|
||||
inline void
|
||||
FrameState::ensureDataSynced(const FrameEntry *fe, Assembler &masm) const
|
||||
{
|
||||
if (fe->data.synced())
|
||||
return;
|
||||
|
||||
Address to = addressOf(fe);
|
||||
const FrameEntry *backing = fe;
|
||||
if (fe->isCopy())
|
||||
backing = fe->copyOf();
|
||||
|
||||
#if defined JS_PUNBOX64
|
||||
if (backing->isConstant())
|
||||
masm.storeValue(backing->getValue(), to);
|
||||
else if (backing->isTypeKnown())
|
||||
masm.storeValueFromComponents(ImmType(backing->getKnownType()), backing->data.reg(), to);
|
||||
else if (backing->type.inRegister())
|
||||
masm.storeValueFromComponents(backing->type.reg(), backing->data.reg(), to);
|
||||
else
|
||||
masm.storePayload(backing->data.reg(), to);
|
||||
#elif defined JS_NUNBOX32
|
||||
if (backing->isConstant())
|
||||
masm.storePayload(ImmPayload(backing->getPayload()), to);
|
||||
else
|
||||
masm.storePayload(backing->data.reg(), to);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void
|
||||
FrameState::syncFe(FrameEntry *fe)
|
||||
{
|
||||
FrameEntry *backing = fe;
|
||||
if (fe->isCopy())
|
||||
backing = fe->copyOf();
|
||||
|
||||
bool needTypeReg = !fe->type.synced() && backing->type.inMemory();
|
||||
bool needDataReg = !fe->data.synced() && backing->data.inMemory();
|
||||
|
||||
#if defined JS_NUNBOX32
|
||||
/* Determine an ordering that won't spill known regs. */
|
||||
if (needTypeReg && !needDataReg) {
|
||||
syncData(fe);
|
||||
syncType(fe);
|
||||
} else {
|
||||
syncType(fe);
|
||||
syncData(fe);
|
||||
}
|
||||
#elif defined JS_PUNBOX64
|
||||
if (JS_UNLIKELY(needTypeReg && needDataReg)) {
|
||||
/* Memory-to-memory moves can only occur for copies backed by memory. */
|
||||
JS_ASSERT(backing != fe);
|
||||
|
||||
/* Use ValueReg to do a whole-Value mem-to-mem move. */
|
||||
masm.loadValue(addressOf(backing), Registers::ValueReg);
|
||||
masm.storeValue(Registers::ValueReg, addressOf(fe));
|
||||
} else {
|
||||
/* Store in case unpinning is necessary. */
|
||||
MaybeRegisterID pairReg;
|
||||
|
||||
/* Get a register if necessary, without clobbering its pair. */
|
||||
if (needTypeReg) {
|
||||
if (backing->data.inRegister()) {
|
||||
pairReg = backing->data.reg();
|
||||
pinReg(backing->data.reg());
|
||||
}
|
||||
tempRegForType(backing);
|
||||
} else if (needDataReg) {
|
||||
if (backing->type.inRegister()) {
|
||||
pairReg = backing->type.reg();
|
||||
pinReg(backing->type.reg());
|
||||
}
|
||||
tempRegForData(backing);
|
||||
}
|
||||
|
||||
ensureFeSynced(fe, masm);
|
||||
|
||||
if (pairReg.isSet())
|
||||
unpinReg(pairReg.reg());
|
||||
}
|
||||
|
||||
if (!fe->type.synced())
|
||||
fe->type.sync();
|
||||
if (!fe->data.synced())
|
||||
fe->data.sync();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void
|
||||
FrameState::syncType(FrameEntry *fe)
|
||||
{
|
||||
FrameEntry *backing = fe;
|
||||
if (fe->isCopy())
|
||||
backing = fe->copyOf();
|
||||
|
||||
if (!fe->type.synced() && backing->type.inMemory())
|
||||
tempRegForType(backing);
|
||||
|
||||
ensureTypeSynced(fe, masm);
|
||||
|
||||
if (!fe->type.synced())
|
||||
fe->type.sync();
|
||||
}
|
||||
|
||||
inline void
|
||||
FrameState::syncData(FrameEntry *fe)
|
||||
{
|
||||
FrameEntry *backing = fe;
|
||||
if (fe->isCopy())
|
||||
backing = fe->copyOf();
|
||||
|
||||
if (!fe->data.synced() && backing->data.inMemory())
|
||||
tempRegForData(backing);
|
||||
|
||||
ensureDataSynced(fe, masm);
|
||||
|
||||
if (!fe->data.synced())
|
||||
fe->data.sync();
|
||||
}
|
||||
|
||||
inline void
|
||||
|
@ -525,7 +666,17 @@ FrameState::forgetType(FrameEntry *fe)
|
|||
if (!fe->isTypeKnown())
|
||||
return;
|
||||
|
||||
syncType(fe, addressOf(fe), masm);
|
||||
/*
|
||||
* Likewise, storeLocal() may have set this FE, with a known type,
|
||||
* to be a copy of another FE, which has an unknown type.
|
||||
* Just forget the type, since the backing is used in all cases.
|
||||
*/
|
||||
if (fe->isCopy()) {
|
||||
fe->type.invalidate();
|
||||
return;
|
||||
}
|
||||
|
||||
ensureTypeSynced(fe, masm);
|
||||
fe->type.setMemory();
|
||||
}
|
||||
|
||||
|
@ -852,11 +1003,7 @@ FrameState::loadDouble(FrameEntry *fe, FPRegisterID fpReg, Assembler &masm) cons
|
|||
return;
|
||||
}
|
||||
|
||||
if (!fe->data.synced())
|
||||
syncData(fe, addressOf(fe), masm);
|
||||
if (!fe->type.synced())
|
||||
syncType(fe, addressOf(fe), masm);
|
||||
|
||||
ensureFeSynced(fe, masm);
|
||||
masm.loadDouble(addressOf(fe), fpReg);
|
||||
}
|
||||
|
||||
|
|
|
@ -121,16 +121,10 @@ FrameState::evictReg(RegisterID reg)
|
|||
FrameEntry *fe = regstate[reg].fe();
|
||||
|
||||
if (regstate[reg].type() == RematInfo::TYPE) {
|
||||
if (!fe->type.synced()) {
|
||||
syncType(fe, addressOf(fe), masm);
|
||||
fe->type.sync();
|
||||
}
|
||||
ensureTypeSynced(fe, masm);
|
||||
fe->type.setMemory();
|
||||
} else {
|
||||
if (!fe->data.synced()) {
|
||||
syncData(fe, addressOf(fe), masm);
|
||||
fe->data.sync();
|
||||
}
|
||||
ensureDataSynced(fe, masm);
|
||||
fe->data.setMemory();
|
||||
}
|
||||
}
|
||||
|
@ -441,23 +435,34 @@ FrameState::sync(Assembler &masm, Uses uses) const
|
|||
return;
|
||||
|
||||
/* Sync all registers up-front. */
|
||||
for (uint32 i = 0; i < JSC::MacroAssembler::TotalRegisters; i++) {
|
||||
RegisterID reg = RegisterID(i);
|
||||
Registers allRegs(Registers::AvailRegs);
|
||||
while (!allRegs.empty()) {
|
||||
RegisterID reg = allRegs.takeAnyReg();
|
||||
FrameEntry *fe = regstate[reg].usedBy();
|
||||
if (!fe)
|
||||
continue;
|
||||
|
||||
JS_ASSERT(fe->isTracked());
|
||||
|
||||
#if defined JS_PUNBOX64
|
||||
/* Sync entire FE to prevent loads. */
|
||||
ensureFeSynced(fe, masm);
|
||||
|
||||
/* Take the other register in the pair, if one exists. */
|
||||
if (regstate[reg].type() == RematInfo::DATA && fe->type.inRegister())
|
||||
allRegs.takeReg(fe->type.reg());
|
||||
else if (regstate[reg].type() == RematInfo::TYPE && fe->data.inRegister())
|
||||
allRegs.takeReg(fe->data.reg());
|
||||
#elif defined JS_NUNBOX32
|
||||
/* Sync register if unsynced. */
|
||||
if (regstate[reg].type() == RematInfo::DATA) {
|
||||
JS_ASSERT(fe->data.reg() == reg);
|
||||
if (!fe->data.synced())
|
||||
syncData(fe, addressOf(fe), masm);
|
||||
ensureDataSynced(fe, masm);
|
||||
} else {
|
||||
JS_ASSERT(fe->type.reg() == reg);
|
||||
if (!fe->type.synced())
|
||||
syncType(fe, addressOf(fe), masm);
|
||||
ensureTypeSynced(fe, masm);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -473,51 +478,37 @@ FrameState::sync(Assembler &masm, Uses uses) const
|
|||
if (!fe->isTracked())
|
||||
continue;
|
||||
|
||||
Address address = addressOf(fe);
|
||||
FrameEntry *backing = fe;
|
||||
|
||||
if (!fe->isCopy()) {
|
||||
/*
|
||||
* If this |fe| has registers, track them as available. They've
|
||||
* already been synced. Otherwise, see if a constant needs to be
|
||||
* synced.
|
||||
*/
|
||||
if (fe->data.inRegister())
|
||||
avail.putReg(fe->data.reg());
|
||||
else if (!fe->data.synced())
|
||||
syncData(fe, address, masm);
|
||||
|
||||
if (fe->type.inRegister())
|
||||
avail.putReg(fe->type.reg());
|
||||
else if (!fe->type.synced())
|
||||
syncType(fe, address, masm);
|
||||
} else {
|
||||
FrameEntry *backing = fe->copyOf();
|
||||
JS_ASSERT(backing != fe);
|
||||
backing = fe->copyOf();
|
||||
JS_ASSERT(!backing->isConstant() && !fe->isConstant());
|
||||
|
||||
/*
|
||||
* If the copy is backed by something not in a register, fall back
|
||||
* to a slower sync algorithm.
|
||||
*/
|
||||
if ((!fe->type.synced() && !backing->type.inRegister()) ||
|
||||
(!fe->data.synced() && !backing->data.inRegister())) {
|
||||
/* Fall back to a slower sync algorithm if load required. */
|
||||
if ((!fe->type.synced() && backing->type.inMemory()) ||
|
||||
(!fe->data.synced() && backing->data.inMemory())) {
|
||||
syncFancy(masm, avail, fe, bottom);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fe->type.synced()) {
|
||||
/* :TODO: we can do better, the type is learned for all copies. */
|
||||
if (fe->isTypeKnown()) {
|
||||
//JS_ASSERT(fe->getTypeTag() == backing->getTypeTag());
|
||||
masm.storeTypeTag(ImmType(fe->getKnownType()), address);
|
||||
} else {
|
||||
masm.storeTypeTag(backing->type.reg(), address);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fe->data.synced())
|
||||
masm.storePayload(backing->data.reg(), address);
|
||||
}
|
||||
|
||||
/* If a part still needs syncing, it is either a copy or constant. */
|
||||
#if defined JS_PUNBOX64
|
||||
/* All register-backed FEs have been entirely synced up-front. */
|
||||
if (!fe->type.inRegister() && !fe->data.inRegister())
|
||||
ensureFeSynced(fe, masm);
|
||||
#elif defined JS_NUNBOX32
|
||||
/* All components held in registers have been already synced. */
|
||||
if (!fe->data.inRegister())
|
||||
ensureDataSynced(fe, masm);
|
||||
if (!fe->type.inRegister())
|
||||
ensureTypeSynced(fe, masm);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -536,19 +527,35 @@ FrameState::syncAndKill(Registers kill, Uses uses, Uses ignore)
|
|||
|
||||
JS_ASSERT(fe->isTracked());
|
||||
|
||||
#if defined JS_PUNBOX64
|
||||
/* Don't use syncFe(), since that may clobber more registers. */
|
||||
ensureFeSynced(fe, masm);
|
||||
|
||||
if (!fe->type.synced())
|
||||
fe->type.sync();
|
||||
if (!fe->data.synced())
|
||||
fe->data.sync();
|
||||
|
||||
/* Take the other register in the pair, if one exists. */
|
||||
if (regstate[reg].type() == RematInfo::DATA) {
|
||||
JS_ASSERT(fe->data.reg() == reg);
|
||||
if (!fe->data.synced()) {
|
||||
syncData(fe, addressOf(fe), masm);
|
||||
fe->data.sync();
|
||||
}
|
||||
if (fe->type.inRegister() && search.hasReg(fe->type.reg()))
|
||||
search.takeReg(fe->type.reg());
|
||||
} else {
|
||||
JS_ASSERT(fe->type.reg() == reg);
|
||||
if (!fe->type.synced()) {
|
||||
syncType(fe, addressOf(fe), masm);
|
||||
fe->type.sync();
|
||||
}
|
||||
if (fe->data.inRegister() && search.hasReg(fe->data.reg()))
|
||||
search.takeReg(fe->data.reg());
|
||||
}
|
||||
#elif defined JS_NUNBOX32
|
||||
/* Sync this register. */
|
||||
if (regstate[reg].type() == RematInfo::DATA) {
|
||||
JS_ASSERT(fe->data.reg() == reg);
|
||||
syncData(fe);
|
||||
} else {
|
||||
JS_ASSERT(fe->type.reg() == reg);
|
||||
syncType(fe);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32 maxvisits = tracker.nentries;
|
||||
|
@ -563,31 +570,18 @@ FrameState::syncAndKill(Registers kill, Uses uses, Uses ignore)
|
|||
if (fe >= spStop)
|
||||
continue;
|
||||
|
||||
Address address = addressOf(fe);
|
||||
FrameEntry *backing = fe;
|
||||
syncFe(fe);
|
||||
|
||||
if (fe->isCopy())
|
||||
backing = fe->copyOf();
|
||||
|
||||
if (!fe->data.synced()) {
|
||||
if (backing != fe && backing->data.inMemory())
|
||||
tempRegForData(backing);
|
||||
syncData(backing, address, masm);
|
||||
fe->data.sync();
|
||||
if (fe->data.inRegister() && kill.hasReg(fe->data.reg())) {
|
||||
forgetReg(fe->data.reg());
|
||||
fe->data.setMemory();
|
||||
}
|
||||
/* Forget registers. */
|
||||
if (fe->data.inRegister() && kill.hasReg(fe->data.reg()) &&
|
||||
!regstate[fe->data.reg()].isPinned()) {
|
||||
forgetReg(fe->data.reg());
|
||||
fe->data.setMemory();
|
||||
}
|
||||
if (!fe->type.synced()) {
|
||||
if (backing != fe && backing->type.inMemory())
|
||||
tempRegForType(backing);
|
||||
syncType(backing, address, masm);
|
||||
fe->type.sync();
|
||||
if (fe->type.inRegister() && kill.hasReg(fe->type.reg())) {
|
||||
forgetReg(fe->type.reg());
|
||||
fe->type.setMemory();
|
||||
}
|
||||
if (fe->type.inRegister() && kill.hasReg(fe->type.reg()) &&
|
||||
!regstate[fe->type.reg()].isPinned()) {
|
||||
forgetReg(fe->type.reg());
|
||||
fe->type.setMemory();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -669,8 +663,7 @@ FrameState::copyDataIntoReg(FrameEntry *fe, RegisterID hint)
|
|||
RegisterID reg = fe->data.reg();
|
||||
if (reg == hint) {
|
||||
if (freeRegs.empty()) {
|
||||
if (!fe->data.synced())
|
||||
syncData(fe, addressOf(fe), masm);
|
||||
ensureDataSynced(fe, masm);
|
||||
fe->data.setMemory();
|
||||
} else {
|
||||
reg = allocReg();
|
||||
|
@ -698,8 +691,7 @@ FrameState::copyDataIntoReg(Assembler &masm, FrameEntry *fe)
|
|||
if (fe->data.inRegister()) {
|
||||
RegisterID reg = fe->data.reg();
|
||||
if (freeRegs.empty()) {
|
||||
if (!fe->data.synced())
|
||||
syncData(fe, addressOf(fe), masm);
|
||||
ensureDataSynced(fe, masm);
|
||||
fe->data.setMemory();
|
||||
regstate[reg].forget();
|
||||
} else {
|
||||
|
@ -731,8 +723,7 @@ FrameState::copyTypeIntoReg(FrameEntry *fe)
|
|||
if (fe->type.inRegister()) {
|
||||
RegisterID reg = fe->type.reg();
|
||||
if (freeRegs.empty()) {
|
||||
if (!fe->type.synced())
|
||||
syncType(fe, addressOf(fe), masm);
|
||||
ensureTypeSynced(fe, masm);
|
||||
fe->type.setMemory();
|
||||
regstate[reg].forget();
|
||||
} else {
|
||||
|
@ -784,13 +775,9 @@ FrameState::copyEntryIntoFPReg(Assembler &masm, FrameEntry *fe, FPRegisterID fpr
|
|||
if (fe->isCopy())
|
||||
fe = fe->copyOf();
|
||||
|
||||
/* The entry must be synced to memory. */
|
||||
if (!fe->data.synced())
|
||||
syncData(fe, addressOf(fe), masm);
|
||||
if (!fe->type.synced())
|
||||
syncType(fe, addressOf(fe), masm);
|
||||
|
||||
ensureFeSynced(fe, masm);
|
||||
masm.loadDouble(addressOf(fe), fpreg);
|
||||
|
||||
return fpreg;
|
||||
}
|
||||
|
||||
|
@ -810,8 +797,7 @@ FrameState::ownRegForType(FrameEntry *fe)
|
|||
|
||||
if (freeRegs.empty()) {
|
||||
/* For now... just steal the register that already exists. */
|
||||
if (!backing->type.synced())
|
||||
syncType(backing, addressOf(backing), masm);
|
||||
ensureTypeSynced(backing, masm);
|
||||
reg = backing->type.reg();
|
||||
backing->type.setMemory();
|
||||
regstate[reg].forget();
|
||||
|
@ -854,8 +840,7 @@ FrameState::ownRegForData(FrameEntry *fe)
|
|||
|
||||
if (freeRegs.empty()) {
|
||||
/* For now... just steal the register that already exists. */
|
||||
if (!backing->data.synced())
|
||||
syncData(backing, addressOf(backing), masm);
|
||||
ensureDataSynced(backing, masm);
|
||||
reg = backing->data.reg();
|
||||
backing->data.setMemory();
|
||||
regstate[reg].forget();
|
||||
|
@ -1106,33 +1091,14 @@ FrameState::storeLocal(uint32 n, bool popGuaranteed, bool typeChange)
|
|||
return;
|
||||
|
||||
/* Ensure that the local variable remains synced. */
|
||||
if (local->isCopy()) {
|
||||
FrameEntry *backing = local->copyOf();
|
||||
if (!local->data.synced()) {
|
||||
if (backing->data.inMemory())
|
||||
tempRegForData(backing);
|
||||
syncData(backing, addressOf(local), masm);
|
||||
}
|
||||
if (!local->type.synced()) {
|
||||
if (backing->type.inMemory())
|
||||
tempRegForType(backing);
|
||||
syncType(backing, addressOf(local), masm);
|
||||
}
|
||||
} else {
|
||||
if (!local->data.synced()) {
|
||||
syncData(local, addressOf(local), masm);
|
||||
local->data.sync();
|
||||
}
|
||||
if (!local->type.synced()) {
|
||||
syncType(local, addressOf(local), masm);
|
||||
local->type.sync();
|
||||
}
|
||||
if (closed)
|
||||
forgetEntry(local);
|
||||
}
|
||||
syncFe(local);
|
||||
|
||||
if (closed)
|
||||
if (closed) {
|
||||
/* If the FE can have registers, free them before resetting. */
|
||||
if (!local->isCopy())
|
||||
forgetEntry(local);
|
||||
local->resetSynced();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1336,7 +1302,7 @@ FrameState::unpinEntry(const ValueRemat &vr)
|
|||
}
|
||||
|
||||
void
|
||||
FrameState::syncEntry(Assembler &masm, FrameEntry *fe, const ValueRemat &vr)
|
||||
FrameState::ensureValueSynced(Assembler &masm, FrameEntry *fe, const ValueRemat &vr)
|
||||
{
|
||||
#if defined JS_PUNBOX64
|
||||
if (!vr.isDataSynced || !vr.isTypeSynced)
|
||||
|
|
|
@ -408,13 +408,6 @@ class FrameState
|
|||
*/
|
||||
inline RegisterID tempRegForData(FrameEntry *fe, RegisterID reg, Assembler &masm) const;
|
||||
|
||||
/*
|
||||
* Forcibly loads the type tag for the specified FrameEntry
|
||||
* into a register already marked as owning the type.
|
||||
*/
|
||||
inline void emitLoadTypeTag(FrameEntry *fe, RegisterID reg) const;
|
||||
inline void emitLoadTypeTag(Assembler &masm, FrameEntry *fe, RegisterID reg) const;
|
||||
|
||||
/*
|
||||
* Convert an integer to a double without applying
|
||||
* additional Register pressure.
|
||||
|
@ -490,7 +483,7 @@ class FrameState
|
|||
void unpinEntry(const ValueRemat &vr);
|
||||
|
||||
/* Syncs fe to memory, given its state as constructed by a call to pinEntry. */
|
||||
void syncEntry(Assembler &masm, FrameEntry *fe, const ValueRemat &vr);
|
||||
void ensureValueSynced(Assembler &masm, FrameEntry *fe, const ValueRemat &vr);
|
||||
|
||||
struct BinaryAlloc {
|
||||
MaybeRegisterID lhsType;
|
||||
|
@ -798,8 +791,17 @@ class FrameState
|
|||
void evictReg(RegisterID reg);
|
||||
inline FrameEntry *rawPush();
|
||||
inline void addToTracker(FrameEntry *fe);
|
||||
inline void syncType(const FrameEntry *fe, Address to, Assembler &masm) const;
|
||||
inline void syncData(const FrameEntry *fe, Address to, Assembler &masm) const;
|
||||
|
||||
/* Guarantee sync, but do not set any sync flag. */
|
||||
inline void ensureFeSynced(const FrameEntry *fe, Assembler &masm) const;
|
||||
inline void ensureTypeSynced(const FrameEntry *fe, Assembler &masm) const;
|
||||
inline void ensureDataSynced(const FrameEntry *fe, Assembler &masm) const;
|
||||
|
||||
/* Guarantee sync, even if register allocation is required, and set sync. */
|
||||
inline void syncFe(FrameEntry *fe);
|
||||
inline void syncType(FrameEntry *fe);
|
||||
inline void syncData(FrameEntry *fe);
|
||||
|
||||
inline FrameEntry *getLocal(uint32 slot);
|
||||
inline void forgetAllRegs(FrameEntry *fe);
|
||||
inline void swapInTracker(FrameEntry *lhs, FrameEntry *rhs);
|
||||
|
|
|
@ -132,8 +132,8 @@ class Assembler : public BaseAssembler
|
|||
}
|
||||
|
||||
void loadValueAsComponents(const Value &val, RegisterID type, RegisterID payload) {
|
||||
move(Imm64(val.asRawBits() & 0xFFFF800000000000), type);
|
||||
move(Imm64(val.asRawBits() & 0x00007FFFFFFFFFFF), payload);
|
||||
move(Imm64(val.asRawBits() & JSVAL_TAG_MASK), type);
|
||||
move(Imm64(val.asRawBits() & JSVAL_PAYLOAD_MASK), payload);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
Загрузка…
Ссылка в новой задаче