diff --git a/js/src/methodjit/CodeGenIncludes.h b/js/src/methodjit/CodeGenIncludes.h index 4f90a78c546c..d014e6d8a1d7 100644 --- a/js/src/methodjit/CodeGenIncludes.h +++ b/js/src/methodjit/CodeGenIncludes.h @@ -46,7 +46,7 @@ #elif defined JS_PUNBOX64 # include "PunboxAssembler.h" #else -# error "Neither JS_NUNBOX32 nor JS_PUNBOX64 is defined." +# error "Neither JS_NUNBOX32 nor JS_PUNBOX32 is defined." #endif /* Get a label for assertion purposes. Prevent #ifdef clutter. */ diff --git a/js/src/methodjit/FastArithmetic.cpp b/js/src/methodjit/FastArithmetic.cpp index ae38b05f5e1a..b16cb4486517 100644 --- a/js/src/methodjit/FastArithmetic.cpp +++ b/js/src/methodjit/FastArithmetic.cpp @@ -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.ensureValueSynced(stubcc.masm, lhs, lvr); - frame.ensureValueSynced(stubcc.masm, rhs, rvr); + frame.syncEntry(stubcc.masm, lhs, lvr); + frame.syncEntry(stubcc.masm, rhs, rvr); /* Call the stub, adjusting for the two values just pushed. */ stubcc.call(stub, frame.stackDepth() + script->nfixed + 2); diff --git a/js/src/methodjit/FastOps.cpp b/js/src/methodjit/FastOps.cpp index 69fd8ead7d62..7c835e006a7e 100644 --- a/js/src/methodjit/FastOps.cpp +++ b/js/src/methodjit/FastOps.cpp @@ -1653,11 +1653,13 @@ mjit::Compiler::jsop_stricteq(JSOp op) masm.set32(cond, frame.tempRegForType(test), Imm32(mask), result); #elif defined JS_CPU_X64 RegisterID maskReg = frame.allocReg(); - masm.move(ImmTag(known->getKnownTag()), maskReg); + 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); diff --git a/js/src/methodjit/FrameEntry.h b/js/src/methodjit/FrameEntry.h index 56a4dc72ac1a..fc189f05ea59 100644 --- a/js/src/methodjit/FrameEntry.h +++ b/js/src/methodjit/FrameEntry.h @@ -195,7 +195,6 @@ class FrameEntry FrameEntry *copyOf() const { JS_ASSERT(isCopy()); - JS_ASSERT(copy < this); return copy; } diff --git a/js/src/methodjit/FrameState-inl.h b/js/src/methodjit/FrameState-inl.h index 6a6b5917c284..54fcb45585d9 100644 --- a/js/src/methodjit/FrameState-inl.h +++ b/js/src/methodjit/FrameState-inl.h @@ -126,6 +126,20 @@ 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 { @@ -471,188 +485,33 @@ FrameState::shouldAvoidDataRemat(FrameEntry *fe) } inline void -FrameState::ensureFeSynced(const FrameEntry *fe, Assembler &masm) const +FrameState::syncType(const FrameEntry *fe, Address to, Assembler &masm) const { - Address to = addressOf(fe); - const FrameEntry *backing = fe; - if (fe->isCopy()) - backing = fe->copyOf(); - -#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::ensureTypeSynced(const FrameEntry *fe, Assembler &masm) const -{ - if (fe->type.synced()) - return; - - 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 + JS_ASSERT_IF(fe->type.synced(), + fe->isCopied() && addressOf(fe).offset != to.offset); + JS_ASSERT(fe->type.inRegister() || fe->type.isConstant()); /* Store a double's type bits, even though !isTypeKnown(). */ - if (backing->isConstant()) - masm.storeTypeTag(ImmTag(backing->getKnownTag()), to); + if (fe->isConstant()) + masm.storeTypeTag(ImmTag(fe->getKnownTag()), to); else if (fe->isTypeKnown()) - masm.storeTypeTag(ImmType(backing->getKnownType()), to); + masm.storeTypeTag(ImmType(fe->getKnownType()), to); else - masm.storeTypeTag(backing->type.reg(), to); + masm.storeTypeTag(fe->type.reg(), to); } inline void -FrameState::ensureDataSynced(const FrameEntry *fe, Assembler &masm) const +FrameState::syncData(const FrameEntry *fe, Address to, Assembler &masm) const { - if (fe->data.synced()) - return; + JS_ASSERT_IF(addressOf(fe).base == to.base && + addressOf(fe).offset == to.offset, + !fe->data.synced()); + JS_ASSERT(fe->data.inRegister() || fe->data.isConstant()); - 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); + if (fe->data.isConstant()) + masm.storePayload(ImmPayload(fe->getPayload()), 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(); + masm.storePayload(fe->data.reg(), to); } inline void @@ -666,17 +525,7 @@ FrameState::forgetType(FrameEntry *fe) if (!fe->isTypeKnown()) return; - /* - * 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); + syncType(fe, addressOf(fe), masm); fe->type.setMemory(); } @@ -1003,7 +852,11 @@ FrameState::loadDouble(FrameEntry *fe, FPRegisterID fpReg, Assembler &masm) cons return; } - ensureFeSynced(fe, masm); + if (!fe->data.synced()) + syncData(fe, addressOf(fe), masm); + if (!fe->type.synced()) + syncType(fe, addressOf(fe), masm); + masm.loadDouble(addressOf(fe), fpReg); } diff --git a/js/src/methodjit/FrameState.cpp b/js/src/methodjit/FrameState.cpp index 30d2f08d75e9..5e269810e6db 100644 --- a/js/src/methodjit/FrameState.cpp +++ b/js/src/methodjit/FrameState.cpp @@ -121,10 +121,16 @@ FrameState::evictReg(RegisterID reg) FrameEntry *fe = regstate[reg].fe(); if (regstate[reg].type() == RematInfo::TYPE) { - ensureTypeSynced(fe, masm); + if (!fe->type.synced()) { + syncType(fe, addressOf(fe), masm); + fe->type.sync(); + } fe->type.setMemory(); } else { - ensureDataSynced(fe, masm); + if (!fe->data.synced()) { + syncData(fe, addressOf(fe), masm); + fe->data.sync(); + } fe->data.setMemory(); } } @@ -435,34 +441,23 @@ FrameState::sync(Assembler &masm, Uses uses) const return; /* Sync all registers up-front. */ - Registers allRegs(Registers::AvailRegs); - while (!allRegs.empty()) { - RegisterID reg = allRegs.takeAnyReg(); + for (uint32 i = 0; i < JSC::MacroAssembler::TotalRegisters; i++) { + RegisterID reg = RegisterID(i); 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); - ensureDataSynced(fe, masm); + if (!fe->data.synced()) + syncData(fe, addressOf(fe), masm); } else { JS_ASSERT(fe->type.reg() == reg); - ensureTypeSynced(fe, masm); + if (!fe->type.synced()) + syncType(fe, addressOf(fe), masm); } -#endif } /* @@ -478,37 +473,51 @@ FrameState::sync(Assembler &masm, Uses uses) const if (!fe->isTracked()) continue; - FrameEntry *backing = fe; + Address address = addressOf(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 { - backing = fe->copyOf(); + FrameEntry *backing = fe->copyOf(); + JS_ASSERT(backing != fe); JS_ASSERT(!backing->isConstant() && !fe->isConstant()); - /* Fall back to a slower sync algorithm if load required. */ - if ((!fe->type.synced() && backing->type.inMemory()) || - (!fe->data.synced() && backing->data.inMemory())) { + /* + * 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())) { syncFancy(masm, avail, fe, bottom); return; } - } - /* 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 + 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); + } } } @@ -527,35 +536,19 @@ 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->type.inRegister() && search.hasReg(fe->type.reg())) - search.takeReg(fe->type.reg()); + if (!fe->data.synced()) { + syncData(fe, addressOf(fe), masm); + fe->data.sync(); + } } else { JS_ASSERT(fe->type.reg() == reg); - if (fe->data.inRegister() && search.hasReg(fe->data.reg())) - search.takeReg(fe->data.reg()); + if (!fe->type.synced()) { + syncType(fe, addressOf(fe), masm); + fe->type.sync(); + } } -#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; @@ -570,18 +563,31 @@ FrameState::syncAndKill(Registers kill, Uses uses, Uses ignore) if (fe >= spStop) continue; - syncFe(fe); + Address address = addressOf(fe); + FrameEntry *backing = fe; - /* 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->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(); + } } - if (fe->type.inRegister() && kill.hasReg(fe->type.reg()) && - !regstate[fe->type.reg()].isPinned()) { - forgetReg(fe->type.reg()); - fe->type.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(); + } } } @@ -663,7 +669,8 @@ FrameState::copyDataIntoReg(FrameEntry *fe, RegisterID hint) RegisterID reg = fe->data.reg(); if (reg == hint) { if (freeRegs.empty()) { - ensureDataSynced(fe, masm); + if (!fe->data.synced()) + syncData(fe, addressOf(fe), masm); fe->data.setMemory(); } else { reg = allocReg(); @@ -691,7 +698,8 @@ FrameState::copyDataIntoReg(Assembler &masm, FrameEntry *fe) if (fe->data.inRegister()) { RegisterID reg = fe->data.reg(); if (freeRegs.empty()) { - ensureDataSynced(fe, masm); + if (!fe->data.synced()) + syncData(fe, addressOf(fe), masm); fe->data.setMemory(); regstate[reg].forget(); } else { @@ -723,7 +731,8 @@ FrameState::copyTypeIntoReg(FrameEntry *fe) if (fe->type.inRegister()) { RegisterID reg = fe->type.reg(); if (freeRegs.empty()) { - ensureTypeSynced(fe, masm); + if (!fe->type.synced()) + syncType(fe, addressOf(fe), masm); fe->type.setMemory(); regstate[reg].forget(); } else { @@ -775,9 +784,13 @@ FrameState::copyEntryIntoFPReg(Assembler &masm, FrameEntry *fe, FPRegisterID fpr if (fe->isCopy()) fe = fe->copyOf(); - ensureFeSynced(fe, masm); - masm.loadDouble(addressOf(fe), fpreg); + /* 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); + masm.loadDouble(addressOf(fe), fpreg); return fpreg; } @@ -797,7 +810,8 @@ FrameState::ownRegForType(FrameEntry *fe) if (freeRegs.empty()) { /* For now... just steal the register that already exists. */ - ensureTypeSynced(backing, masm); + if (!backing->type.synced()) + syncType(backing, addressOf(backing), masm); reg = backing->type.reg(); backing->type.setMemory(); regstate[reg].forget(); @@ -840,7 +854,8 @@ FrameState::ownRegForData(FrameEntry *fe) if (freeRegs.empty()) { /* For now... just steal the register that already exists. */ - ensureDataSynced(backing, masm); + if (!backing->data.synced()) + syncData(backing, addressOf(backing), masm); reg = backing->data.reg(); backing->data.setMemory(); regstate[reg].forget(); @@ -1091,14 +1106,33 @@ FrameState::storeLocal(uint32 n, bool popGuaranteed, bool typeChange) return; /* Ensure that the local variable remains synced. */ - syncFe(local); - - if (closed) { - /* If the FE can have registers, free them before resetting. */ - if (!local->isCopy()) + 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); - local->resetSynced(); } + + if (closed) + local->resetSynced(); } void @@ -1302,7 +1336,7 @@ FrameState::unpinEntry(const ValueRemat &vr) } void -FrameState::ensureValueSynced(Assembler &masm, FrameEntry *fe, const ValueRemat &vr) +FrameState::syncEntry(Assembler &masm, FrameEntry *fe, const ValueRemat &vr) { #if defined JS_PUNBOX64 if (!vr.isDataSynced || !vr.isTypeSynced) diff --git a/js/src/methodjit/FrameState.h b/js/src/methodjit/FrameState.h index a858fcf228e5..7612662880b7 100644 --- a/js/src/methodjit/FrameState.h +++ b/js/src/methodjit/FrameState.h @@ -408,6 +408,13 @@ 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. @@ -483,7 +490,7 @@ class FrameState void unpinEntry(const ValueRemat &vr); /* Syncs fe to memory, given its state as constructed by a call to pinEntry. */ - void ensureValueSynced(Assembler &masm, FrameEntry *fe, const ValueRemat &vr); + void syncEntry(Assembler &masm, FrameEntry *fe, const ValueRemat &vr); struct BinaryAlloc { MaybeRegisterID lhsType; @@ -791,17 +798,8 @@ class FrameState void evictReg(RegisterID reg); inline FrameEntry *rawPush(); inline void addToTracker(FrameEntry *fe); - - /* 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 void syncType(const FrameEntry *fe, Address to, Assembler &masm) const; + inline void syncData(const FrameEntry *fe, Address to, Assembler &masm) const; inline FrameEntry *getLocal(uint32 slot); inline void forgetAllRegs(FrameEntry *fe); inline void swapInTracker(FrameEntry *lhs, FrameEntry *rhs); diff --git a/js/src/methodjit/PunboxAssembler.h b/js/src/methodjit/PunboxAssembler.h index 3e8f29bc3ae1..0fae0464db09 100644 --- a/js/src/methodjit/PunboxAssembler.h +++ b/js/src/methodjit/PunboxAssembler.h @@ -131,8 +131,8 @@ class Assembler : public BaseAssembler } void loadValueAsComponents(const Value &val, RegisterID type, RegisterID payload) { - move(Imm64(val.asRawBits() & JSVAL_TAG_MASK), type); - move(Imm64(val.asRawBits() & JSVAL_PAYLOAD_MASK), payload); + move(Imm64(val.asRawBits() & 0xFFFF800000000000), type); + move(Imm64(val.asRawBits() & 0x00007FFFFFFFFFFF), payload); } template