Make sure that top bits are zero when storing untagged 32 bit values
authorerik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 21 Feb 2012 09:11:35 +0000 (09:11 +0000)
committererik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 21 Feb 2012 09:11:35 +0000 (09:11 +0000)
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
src/x64/lithium-codegen-x64.cc
src/x64/lithium-gap-resolver-x64.cc
src/x64/macro-assembler-x64.cc
src/x64/macro-assembler-x64.h

index 9ce1af8..5397cd5 100644 (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);
index 9f64931..7bde564 100644 (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()));
     }
index bf5d31d..877ea8c 100644 (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);
index c070fb2..3ee3aad 100644 (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");
index aff496f..94b8584 100644 (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);