Bug 1304191 - Part 8: Stop using jsval_layout in JIT. r=jwalden

This commit is contained in:
Tooru Fujisawa 2016-10-18 16:46:01 +09:00
Родитель ab5fd27553
Коммит 58ffefe531
18 изменённых файлов: 102 добавлений и 124 удалений

Просмотреть файл

@ -570,6 +570,21 @@ class Value
}
public:
/*** JIT-only interfaces to interact with and create raw Values ***/
#if defined(JS_NUNBOX32)
PayloadType toNunboxPayload() const {
return data.s.payload.i32;
}
JSValueTag toNunboxTag() const {
return data.s.tag;
}
#elif defined(JS_PUNBOX64)
const void* bitsAsPunboxPointer() const {
return reinterpret_cast<void*>(data.asBits);
}
#endif
/*** Value type queries ***/
/*
@ -797,6 +812,11 @@ class Value
#endif
}
js::gc::Cell* toMarkablePointer() const {
MOZ_ASSERT(isMarkable());
return toGCThing();
}
GCCellPtr toGCCellPtr() const {
return GCCellPtr(toGCThing(), traceKind());
}

Просмотреть файл

@ -8443,7 +8443,7 @@ StoreUnboxedPointer(MacroAssembler& masm, T address, MIRType type, const LAlloca
if (value->isConstant()) {
Value v = value->toConstant()->toJSValue();
if (v.isMarkable()) {
masm.storePtr(ImmGCPtr(v.toGCThing()), address);
masm.storePtr(ImmGCPtr(v.toMarkablePointer()), address);
} else {
MOZ_ASSERT(v.isNull());
masm.storePtr(ImmWord(0), address);

Просмотреть файл

@ -1069,17 +1069,16 @@ MarkIonJSFrame(JSTracer* trc, const JitFrameIterator& frame)
#ifdef JS_NUNBOX32
LAllocation type, payload;
while (safepoint.getNunboxSlot(&type, &payload)) {
jsval_layout layout;
layout.s.tag = (JSValueTag)ReadAllocation(frame, &type);
layout.s.payload.uintptr = ReadAllocation(frame, &payload);
JSValueTag tag = JSValueTag(ReadAllocation(frame, &type));
uintptr_t rawPayload = ReadAllocation(frame, &payload);
Value v = IMPL_TO_JSVAL(layout);
Value v = Value::fromTagAndPayload(tag, rawPayload);
TraceRoot(trc, &v, "ion-torn-value");
if (v != IMPL_TO_JSVAL(layout)) {
if (v != Value::fromTagAndPayload(tag, rawPayload)) {
// GC moved the value, replace the stored payload.
layout = JSVAL_TO_IMPL(v);
WriteAllocation(frame, &payload, layout.s.payload.uintptr);
rawPayload = *v.payloadUIntPtr();
WriteAllocation(frame, &payload, rawPayload);
}
}
#endif
@ -1829,48 +1828,36 @@ SnapshotIterator::allocationValue(const RValueAllocation& alloc, ReadMethod rm)
#if defined(JS_NUNBOX32)
case RValueAllocation::UNTYPED_REG_REG:
{
jsval_layout layout;
layout.s.tag = (JSValueTag) fromRegister(alloc.reg());
layout.s.payload.word = fromRegister(alloc.reg2());
return IMPL_TO_JSVAL(layout);
return Value::fromTagAndPayload(JSValueTag(fromRegister(alloc.reg())),
fromRegister(alloc.reg2()));
}
case RValueAllocation::UNTYPED_REG_STACK:
{
jsval_layout layout;
layout.s.tag = (JSValueTag) fromRegister(alloc.reg());
layout.s.payload.word = fromStack(alloc.stackOffset2());
return IMPL_TO_JSVAL(layout);
return Value::fromTagAndPayload(JSValueTag(fromRegister(alloc.reg())),
fromStack(alloc.stackOffset2()));
}
case RValueAllocation::UNTYPED_STACK_REG:
{
jsval_layout layout;
layout.s.tag = (JSValueTag) fromStack(alloc.stackOffset());
layout.s.payload.word = fromRegister(alloc.reg2());
return IMPL_TO_JSVAL(layout);
return Value::fromTagAndPayload(JSValueTag(fromStack(alloc.stackOffset())),
fromRegister(alloc.reg2()));
}
case RValueAllocation::UNTYPED_STACK_STACK:
{
jsval_layout layout;
layout.s.tag = (JSValueTag) fromStack(alloc.stackOffset());
layout.s.payload.word = fromStack(alloc.stackOffset2());
return IMPL_TO_JSVAL(layout);
return Value::fromTagAndPayload(JSValueTag(fromStack(alloc.stackOffset())),
fromStack(alloc.stackOffset2()));
}
#elif defined(JS_PUNBOX64)
case RValueAllocation::UNTYPED_REG:
{
jsval_layout layout;
layout.asBits = fromRegister(alloc.reg());
return IMPL_TO_JSVAL(layout);
return Value::fromRawBits(fromRegister(alloc.reg()));
}
case RValueAllocation::UNTYPED_STACK:
{
jsval_layout layout;
layout.asBits = fromStack(alloc.stackOffset());
return IMPL_TO_JSVAL(layout);
return Value::fromRawBits(fromStack(alloc.stackOffset()));
}
#endif

Просмотреть файл

@ -2662,7 +2662,7 @@ IsNonNurseryConstant(MDefinition* def)
if (!def->isConstant())
return false;
Value v = def->toConstant()->toJSValue();
return !v.isMarkable() || !IsInsideNursery(v.toGCThing());
return !v.isMarkable() || !IsInsideNursery(v.toMarkablePointer());
}
void

Просмотреть файл

@ -972,15 +972,13 @@ MacroAssembler::fillSlotsWithConstantValue(Address base, Register temp,
#ifdef JS_NUNBOX32
// We only have a single spare register, so do the initialization as two
// strided writes of the tag and body.
jsval_layout jv = JSVAL_TO_IMPL(v);
Address addr = base;
move32(Imm32(jv.s.payload.i32), temp);
move32(Imm32(v.toNunboxPayload()), temp);
for (unsigned i = start; i < end; ++i, addr.offset += sizeof(GCPtrValue))
store32(temp, ToPayload(addr));
addr = base;
move32(Imm32(jv.s.tag), temp);
move32(Imm32(v.toNunboxTag()), temp);
for (unsigned i = start; i < end; ++i, addr.offset += sizeof(GCPtrValue))
store32(temp, ToType(addr));
#else

Просмотреть файл

@ -3269,12 +3269,11 @@ MacroAssemblerARMCompat::extractTag(const BaseIndex& address, Register scratch)
void
MacroAssemblerARMCompat::moveValue(const Value& val, Register type, Register data)
{
jsval_layout jv = JSVAL_TO_IMPL(val);
ma_mov(Imm32(jv.s.tag), type);
ma_mov(Imm32(val.toNunboxTag()), type);
if (val.isMarkable())
ma_mov(ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())), data);
ma_mov(ImmGCPtr(val.toMarkablePointer()), data);
else
ma_mov(Imm32(jv.s.payload.i32), data);
ma_mov(Imm32(val.toNunboxPayload()), data);
}
void
@ -3447,11 +3446,10 @@ MacroAssemblerARMCompat::storePayload(const Value& val, const Address& dest)
ScratchRegisterScope scratch(asMasm());
SecondScratchRegisterScope scratch2(asMasm());
jsval_layout jv = JSVAL_TO_IMPL(val);
if (val.isMarkable())
ma_mov(ImmGCPtr((gc::Cell*)jv.s.payload.ptr), scratch);
ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch);
else
ma_mov(Imm32(jv.s.payload.i32), scratch);
ma_mov(Imm32(val.toNunboxPayload()), scratch);
ma_str(scratch, ToPayload(dest), scratch2);
}
@ -3470,11 +3468,10 @@ MacroAssemblerARMCompat::storePayload(const Value& val, const BaseIndex& dest)
ScratchRegisterScope scratch(asMasm());
SecondScratchRegisterScope scratch2(asMasm());
jsval_layout jv = JSVAL_TO_IMPL(val);
if (val.isMarkable())
ma_mov(ImmGCPtr((gc::Cell*)jv.s.payload.ptr), scratch);
ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch);
else
ma_mov(Imm32(jv.s.payload.i32), scratch);
ma_mov(Imm32(val.toNunboxPayload()), scratch);
// If NUNBOX32_PAYLOAD_OFFSET is not zero, the memory operand [base + index
// << shift + imm] cannot be encoded into a single instruction, and cannot
@ -5302,12 +5299,11 @@ MacroAssembler::branchTestValue(Condition cond, const ValueOperand& lhs,
// equal, short circuit false (NotEqual).
ScratchRegisterScope scratch(*this);
jsval_layout jv = JSVAL_TO_IMPL(rhs);
if (rhs.isMarkable())
ma_cmp(lhs.payloadReg(), ImmGCPtr(reinterpret_cast<gc::Cell*>(rhs.toGCThing())), scratch);
ma_cmp(lhs.payloadReg(), ImmGCPtr(rhs.toMarkablePointer()), scratch);
else
ma_cmp(lhs.payloadReg(), Imm32(jv.s.payload.i32), scratch);
ma_cmp(lhs.typeReg(), Imm32(jv.s.tag), scratch, Equal);
ma_cmp(lhs.payloadReg(), Imm32(rhs.toNunboxPayload()), scratch);
ma_cmp(lhs.typeReg(), Imm32(rhs.toNunboxTag()), scratch, Equal);
ma_b(label, cond);
}

Просмотреть файл

@ -913,19 +913,17 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
ScratchRegisterScope scratch(asMasm());
SecondScratchRegisterScope scratch2(asMasm());
jsval_layout jv = JSVAL_TO_IMPL(val);
ma_mov(Imm32(jv.s.tag), scratch);
ma_mov(Imm32(val.toNunboxTag()), scratch);
ma_str(scratch, ToType(dest), scratch2);
if (val.isMarkable())
ma_mov(ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())), scratch);
ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch);
else
ma_mov(Imm32(jv.s.payload.i32), scratch);
ma_mov(Imm32(val.toNunboxPayload()), scratch);
ma_str(scratch, ToPayload(dest), scratch2);
}
void storeValue(const Value& val, BaseIndex dest) {
ScratchRegisterScope scratch(asMasm());
SecondScratchRegisterScope scratch2(asMasm());
jsval_layout jv = JSVAL_TO_IMPL(val);
int32_t typeoffset = dest.offset + NUNBOX32_TYPE_OFFSET;
int32_t payloadoffset = dest.offset + NUNBOX32_PAYLOAD_OFFSET;
@ -934,11 +932,11 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
// Store the type.
if (typeoffset < 4096 && typeoffset > -4096) {
ma_mov(Imm32(jv.s.tag), scratch2);
ma_mov(Imm32(val.toNunboxTag()), scratch2);
ma_str(scratch2, DTRAddr(scratch, DtrOffImm(typeoffset)));
} else {
ma_add(Imm32(typeoffset), scratch, scratch2);
ma_mov(Imm32(jv.s.tag), scratch2);
ma_mov(Imm32(val.toNunboxTag()), scratch2);
ma_str(scratch2, DTRAddr(scratch, DtrOffImm(0)));
// Restore scratch for the payload store.
ma_alu(dest.base, lsl(dest.index, dest.scale), scratch, OpAdd);
@ -947,16 +945,16 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
// Store the payload, marking if necessary.
if (payloadoffset < 4096 && payloadoffset > -4096) {
if (val.isMarkable())
ma_mov(ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())), scratch2);
ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch2);
else
ma_mov(Imm32(jv.s.payload.i32), scratch2);
ma_mov(Imm32(val.toNunboxPayload()), scratch2);
ma_str(scratch2, DTRAddr(scratch, DtrOffImm(payloadoffset)));
} else {
ma_add(Imm32(payloadoffset), scratch, scratch2);
if (val.isMarkable())
ma_mov(ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())), scratch2);
ma_mov(ImmGCPtr(val.toMarkablePointer()), scratch2);
else
ma_mov(Imm32(jv.s.payload.i32), scratch2);
ma_mov(Imm32(val.toNunboxPayload()), scratch2);
ma_str(scratch2, DTRAddr(scratch, DtrOffImm(0)));
}
}
@ -978,12 +976,11 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
void pushValue(ValueOperand val);
void popValue(ValueOperand val);
void pushValue(const Value& val) {
jsval_layout jv = JSVAL_TO_IMPL(val);
push(Imm32(jv.s.tag));
push(Imm32(val.toNunboxTag()));
if (val.isMarkable())
push(ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())));
push(ImmGCPtr(val.toMarkablePointer()));
else
push(Imm32(jv.s.payload.i32));
push(Imm32(val.toNunboxPayload()));
}
void pushValue(JSValueType type, Register reg) {
push(ImmTag(JSVAL_TYPE_TO_TAG(type)));

Просмотреть файл

@ -564,14 +564,12 @@ TraceDataRelocations(JSTracer* trc, uint8_t* buffer, CompactBufferReader& reader
// All pointers on AArch64 will have the top bits cleared.
// If those bits are not cleared, this must be a Value.
if (literal >> JSVAL_TAG_SHIFT) {
jsval_layout layout;
layout.asBits = literal;
Value v = IMPL_TO_JSVAL(layout);
Value v = Value::fromRawBits(literal);
TraceManuallyBarrieredEdge(trc, &v, "ion-masm-value");
if (*literalAddr != JSVAL_TO_IMPL(v).asBits) {
if (*literalAddr != v.asRawBits()) {
// Only update the code if the value changed, because the code
// is not writable if we're not moving objects.
*literalAddr = JSVAL_TO_IMPL(v).asBits;
*literalAddr = v.asRawBits();
}
// TODO: When we can, flush caches here if a pointer was moved.

Просмотреть файл

@ -306,9 +306,8 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
void pushValue(const Value& val) {
vixl::UseScratchRegisterScope temps(this);
const Register scratch = temps.AcquireX().asUnsized();
jsval_layout jv = JSVAL_TO_IMPL(val);
if (val.isMarkable()) {
BufferOffset load = movePatchablePtr(ImmPtr((void*)jv.asBits), scratch);
BufferOffset load = movePatchablePtr(ImmPtr(val.bitsAsPunboxPointer()), scratch);
writeDataRelocation(val, load);
push(scratch);
} else {
@ -351,7 +350,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
}
void moveValue(const Value& val, Register dest) {
if (val.isMarkable()) {
BufferOffset load = movePatchablePtr(ImmPtr((void*)val.asRawBits()), dest);
BufferOffset load = movePatchablePtr(ImmPtr(val.bitsAsPunboxPointer()), dest);
writeDataRelocation(val, load);
} else {
movePtr(ImmWord(val.asRawBits()), dest);
@ -1849,7 +1848,7 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
}
void writeDataRelocation(const Value& val, BufferOffset load) {
if (val.isMarkable()) {
gc::Cell* cell = reinterpret_cast<gc::Cell*>(val.toGCThing());
gc::Cell* cell = val.toMarkablePointer();
if (cell && gc::IsInsideNursery(cell))
embedsNurseryPointers_ = true;
dataRelocations_.writeUnsigned(load.getOffset());

Просмотреть файл

@ -1521,18 +1521,16 @@ MacroAssemblerMIPSCompat::extractTag(const BaseIndex& address, Register scratch)
uint32_t
MacroAssemblerMIPSCompat::getType(const Value& val)
{
jsval_layout jv = JSVAL_TO_IMPL(val);
return jv.s.tag;
return val.toNunboxTag();
}
void
MacroAssemblerMIPSCompat::moveData(const Value& val, Register data)
{
jsval_layout jv = JSVAL_TO_IMPL(val);
if (val.isMarkable())
ma_li(data, ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())));
ma_li(data, ImmGCPtr(val.toMarkablePointer()));
else
ma_li(data, Imm32(jv.s.payload.i32));
ma_li(data, Imm32(val.toNunboxPayload()));
}
void

Просмотреть файл

@ -479,12 +479,11 @@ class MacroAssemblerMIPSCompat : public MacroAssemblerMIPS
void pushValue(ValueOperand val);
void popValue(ValueOperand val);
void pushValue(const Value& val) {
jsval_layout jv = JSVAL_TO_IMPL(val);
push(Imm32(jv.s.tag));
push(Imm32(val.toNunboxTag()));
if (val.isMarkable())
push(ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())));
push(ImmGCPtr(val.toMarkablePointer()));
else
push(Imm32(jv.s.payload.i32));
push(Imm32(val.toNunboxPayload()));
}
void pushValue(JSValueType type, Register reg) {
push(ImmTag(JSVAL_TYPE_TO_TAG(type)));

Просмотреть файл

@ -175,11 +175,9 @@ TraceOneDataRelocation(JSTracer* trc, Instruction* inst)
// are not cleared, this must be a Value.
uintptr_t word = reinterpret_cast<uintptr_t>(ptr);
if (word >> JSVAL_TAG_SHIFT) {
jsval_layout layout;
layout.asBits = word;
Value v = IMPL_TO_JSVAL(layout);
Value v = Value::fromRawBits(word);
TraceManuallyBarrieredEdge(trc, &v, "ion-masm-value");
ptr = (void*)JSVAL_TO_IMPL(v).asBits;
ptr = v.bitsAsPunboxPointer();
} else {
// No barrier needed since these are constants.
TraceManuallyBarrieredGenericPointerEdge(trc, reinterpret_cast<gc::Cell**>(&ptr),

Просмотреть файл

@ -1746,9 +1746,8 @@ MacroAssemblerMIPS64Compat::extractTag(const BaseIndex& address, Register scratc
void
MacroAssemblerMIPS64Compat::moveValue(const Value& val, Register dest)
{
jsval_layout jv = JSVAL_TO_IMPL(val);
writeDataRelocation(val);
movWithPatch(ImmWord(jv.asBits), dest);
movWithPatch(ImmWord(val.asRawBits()), dest);
}
void
@ -1886,12 +1885,11 @@ MacroAssemblerMIPS64Compat::storeValue(JSValueType type, Register reg, Address d
void
MacroAssemblerMIPS64Compat::storeValue(const Value& val, Address dest)
{
jsval_layout jv = JSVAL_TO_IMPL(val);
if (val.isMarkable()) {
writeDataRelocation(val);
movWithPatch(ImmWord(jv.asBits), SecondScratchReg);
movWithPatch(ImmWord(val.asRawBits()), SecondScratchReg);
} else {
ma_li(SecondScratchReg, ImmWord(jv.asBits));
ma_li(SecondScratchReg, ImmWord(val.asRawBits()));
}
storePtr(SecondScratchReg, Address(dest.base, dest.offset));
}

Просмотреть файл

@ -222,7 +222,7 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
void writeDataRelocation(const Value& val) {
if (val.isMarkable()) {
gc::Cell* cell = reinterpret_cast<gc::Cell *>(val.toGCThing());
gc::Cell* cell = val.toMarkablePointer();
if (cell && gc::IsInsideNursery(cell))
embedsNurseryPointers_ = true;
dataRelocations_.writeUnsigned(currentOffset());

Просмотреть файл

@ -59,7 +59,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
/////////////////////////////////////////////////////////////////
void writeDataRelocation(const Value& val) {
if (val.isMarkable()) {
gc::Cell* cell = reinterpret_cast<gc::Cell*>(val.toGCThing());
gc::Cell* cell = val.toMarkablePointer();
if (cell && gc::IsInsideNursery(cell))
embedsNurseryPointers_ = true;
dataRelocations_.writeUnsigned(masm.currentOffset());
@ -132,12 +132,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
template <typename T>
void storeValue(const Value& val, const T& dest) {
ScratchRegisterScope scratch(asMasm());
jsval_layout jv = JSVAL_TO_IMPL(val);
if (val.isMarkable()) {
movWithPatch(ImmWord(jv.asBits), scratch);
movWithPatch(ImmWord(val.asRawBits()), scratch);
writeDataRelocation(val);
} else {
mov(ImmWord(jv.asBits), scratch);
mov(ImmWord(val.asRawBits()), scratch);
}
movq(scratch, Operand(dest));
}
@ -172,14 +171,13 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
pop(val.valueReg());
}
void pushValue(const Value& val) {
jsval_layout jv = JSVAL_TO_IMPL(val);
if (val.isMarkable()) {
ScratchRegisterScope scratch(asMasm());
movWithPatch(ImmWord(jv.asBits), scratch);
movWithPatch(ImmWord(val.asRawBits()), scratch);
writeDataRelocation(val);
push(scratch);
} else {
push(ImmWord(jv.asBits));
push(ImmWord(val.asRawBits()));
}
}
void pushValue(JSValueType type, Register reg) {
@ -192,8 +190,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
}
void moveValue(const Value& val, Register dest) {
jsval_layout jv = JSVAL_TO_IMPL(val);
movWithPatch(ImmWord(jv.asBits), dest);
movWithPatch(ImmWord(val.asRawBits()), dest);
writeDataRelocation(val);
}
void moveValue(const Value& src, const ValueOperand& dest) {

Просмотреть файл

@ -58,14 +58,12 @@ TraceDataRelocations(JSTracer* trc, uint8_t* buffer, CompactBufferReader& reader
// are not cleared, this must be a Value.
uintptr_t word = reinterpret_cast<uintptr_t>(ptr);
if (word >> JSVAL_TAG_SHIFT) {
jsval_layout layout;
layout.asBits = word;
Value v = IMPL_TO_JSVAL(layout);
Value v = Value::fromRawBits(word);
TraceManuallyBarrieredEdge(trc, &v, "jit-masm-value");
if (word != JSVAL_TO_IMPL(v).asBits) {
if (word != v.asRawBits()) {
// Only update the code if the Value changed, because the code
// is not writable if we're not moving objects.
X86Encoding::SetPointer(buffer + offset, (void*)JSVAL_TO_IMPL(v).asBits);
X86Encoding::SetPointer(buffer + offset, v.bitsAsPunboxPointer());
}
continue;
}

Просмотреть файл

@ -503,24 +503,23 @@ MacroAssembler::branchTestValue(Condition cond, const ValueOperand& lhs,
const Value& rhs, Label* label)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
jsval_layout jv = JSVAL_TO_IMPL(rhs);
if (rhs.isMarkable())
cmpPtr(lhs.payloadReg(), ImmGCPtr(reinterpret_cast<gc::Cell*>(rhs.toGCThing())));
cmpPtr(lhs.payloadReg(), ImmGCPtr(rhs.toMarkablePointer()));
else
cmpPtr(lhs.payloadReg(), ImmWord(jv.s.payload.i32));
cmpPtr(lhs.payloadReg(), ImmWord(rhs.toNunboxPayload()));
if (cond == Equal) {
Label done;
j(NotEqual, &done);
{
cmp32(lhs.typeReg(), Imm32(jv.s.tag));
cmp32(lhs.typeReg(), Imm32(rhs.toNunboxTag()));
j(Equal, label);
}
bind(&done);
} else {
j(NotEqual, label);
cmp32(lhs.typeReg(), Imm32(jv.s.tag));
cmp32(lhs.typeReg(), Imm32(rhs.toNunboxTag()));
j(NotEqual, label);
}
}

Просмотреть файл

@ -93,12 +93,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
return ToType(Operand(base)).toAddress();
}
void moveValue(const Value& val, Register type, Register data) {
jsval_layout jv = JSVAL_TO_IMPL(val);
movl(Imm32(jv.s.tag), type);
movl(Imm32(val.toNunboxTag()), type);
if (val.isMarkable())
movl(ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())), data);
movl(ImmGCPtr(val.toMarkablePointer()), data);
else
movl(Imm32(jv.s.payload.i32), data);
movl(Imm32(val.toNunboxPayload()), data);
}
void moveValue(const Value& val, const ValueOperand& dest) {
moveValue(val, dest.typeReg(), dest.payloadReg());
@ -143,8 +142,7 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
}
template <typename T>
void storeValue(const Value& val, const T& dest) {
jsval_layout jv = JSVAL_TO_IMPL(val);
storeTypeTag(ImmTag(jv.s.tag), Operand(dest));
storeTypeTag(ImmTag(val.toNunboxTag()), Operand(dest));
storePayload(val, Operand(dest));
}
void storeValue(ValueOperand val, BaseIndex dest) {
@ -214,12 +212,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
pop(val.typeReg());
}
void pushValue(const Value& val) {
jsval_layout jv = JSVAL_TO_IMPL(val);
push(Imm32(jv.s.tag));
push(Imm32(val.toNunboxTag()));
if (val.isMarkable())
push(ImmGCPtr(reinterpret_cast<gc::Cell*>(val.toGCThing())));
push(ImmGCPtr(val.toMarkablePointer()));
else
push(Imm32(jv.s.payload.i32));
push(Imm32(val.toNunboxPayload()));
}
void pushValue(JSValueType type, Register reg) {
push(ImmTag(JSVAL_TYPE_TO_TAG(type)));
@ -238,11 +235,10 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
pop(dest.high);
}
void storePayload(const Value& val, Operand dest) {
jsval_layout jv = JSVAL_TO_IMPL(val);
if (val.isMarkable())
movl(ImmGCPtr((gc::Cell*)jv.s.payload.ptr), ToPayload(dest));
movl(ImmGCPtr(val.toMarkablePointer()), ToPayload(dest));
else
movl(Imm32(jv.s.payload.i32), ToPayload(dest));
movl(Imm32(val.toNunboxPayload()), ToPayload(dest));
}
void storePayload(Register src, Operand dest) {
movl(src, ToPayload(dest));