From 81916b1763f53eca62abaf7f99d5bbd11fe5c8d9 Mon Sep 17 00:00:00 2001 From: "erik.corry@gmail.com" Date: Tue, 21 Feb 2012 09:11:35 +0000 Subject: [PATCH] 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 --- src/x64/assembler-x64.cc | 2 ++ src/x64/lithium-codegen-x64.cc | 22 +++++++++++++++------- src/x64/lithium-gap-resolver-x64.cc | 5 +++-- src/x64/macro-assembler-x64.cc | 8 ++++++++ src/x64/macro-assembler-x64.h | 4 ++++ 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc index 9ce1af8..5397cd5 100644 --- a/src/x64/assembler-x64.cc +++ b/src/x64/assembler-x64.cc @@ -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); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 9f64931..7bde564 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -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())); } diff --git a/src/x64/lithium-gap-resolver-x64.cc b/src/x64/lithium-gap-resolver-x64.cc index bf5d31d..877ea8c 100644 --- a/src/x64/lithium-gap-resolver-x64.cc +++ b/src/x64/lithium-gap-resolver-x64.cc @@ -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); diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index c070fb2..3ee3aad 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -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"); diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h index aff496f..94b8584 100644 --- a/src/x64/macro-assembler-x64.h +++ b/src/x64/macro-assembler-x64.h @@ -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); -- 2.7.4