Make sure that top bits are zero when storing untagged 32 bit values

in 64 bit spill slots.
Review URL: https://chromiumcodereview.appspot.com/9378006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10774 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
erik.corry@gmail.com 2012-02-21 09:11:35 +00:00
parent 93802f79e5
commit 81916b1763
5 changed files with 32 additions and 9 deletions

View File

@ -1640,6 +1640,8 @@ void Assembler::movsxlq(Register dst, const Operand& src) {
void Assembler::movzxbq(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
// 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
// there is no need to make this a 64 bit operation.
emit_optional_rex_32(dst, src);
emit(0x0F);
emit(0xB6);

View File

@ -3239,17 +3239,25 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
if (instr->index()->IsConstantOperand()) {
if (instr->length()->IsRegister()) {
__ cmpq(ToRegister(instr->length()),
if (instr->length()->IsRegister()) {
Register reg = ToRegister(instr->length());
if (FLAG_debug_code) {
__ AbortIfNotZeroExtended(reg);
}
if (instr->index()->IsConstantOperand()) {
__ cmpq(reg,
Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
} else {
__ cmpq(ToOperand(instr->length()),
Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
Register reg2 = ToRegister(instr->index());
if (FLAG_debug_code) {
__ AbortIfNotZeroExtended(reg2);
}
__ cmpq(reg, reg2);
}
} else {
if (instr->length()->IsRegister()) {
__ cmpq(ToRegister(instr->length()), ToRegister(instr->index()));
if (instr->index()->IsConstantOperand()) {
__ cmpq(ToOperand(instr->length()),
Immediate(ToInteger32(LConstantOperand::cast(instr->index()))));
} else {
__ cmpq(ToOperand(instr->length()), ToRegister(instr->index()));
}

View File

@ -204,8 +204,9 @@ void LGapResolver::EmitMove(int index) {
ASSERT(destination->IsStackSlot());
Operand dst = cgen_->ToOperand(destination);
if (cgen_->IsInteger32Constant(constant_source)) {
// Allow top 32 bits of an untagged Integer32 to be arbitrary.
__ movl(dst, Immediate(cgen_->ToInteger32(constant_source)));
// Zero top 32 bits of a 64 bit spill slot that holds a 32 bit untagged
// value.
__ movq(dst, Immediate(cgen_->ToInteger32(constant_source)));
} else {
__ LoadObject(kScratchRegister, cgen_->ToHandle(constant_source));
__ movq(dst, kScratchRegister);

View File

@ -2852,6 +2852,14 @@ void MacroAssembler::AbortIfNotSmi(const Operand& object) {
}
void MacroAssembler::AbortIfNotZeroExtended(Register int32_register) {
ASSERT(!int32_register.is(kScratchRegister));
movq(kScratchRegister, 0x100000000l, RelocInfo::NONE);
cmpq(kScratchRegister, int32_register);
Assert(above_equal, "32 bit value in register is not zero-extended");
}
void MacroAssembler::AbortIfNotString(Register object) {
testb(object, Immediate(kSmiTagMask));
Assert(not_equal, "Operand is not a string");

View File

@ -949,6 +949,10 @@ class MacroAssembler: public Assembler {
void AbortIfNotSmi(Register object);
void AbortIfNotSmi(const Operand& object);
// Abort execution if a 64 bit register containing a 32 bit payload does not
// have zeros in the top 32 bits.
void AbortIfNotZeroExtended(Register reg);
// Abort execution if argument is a string. Used in debug code.
void AbortIfNotString(Register object);