From bcaea997d88df7384443f8e1a925418bf66dfd1e Mon Sep 17 00:00:00 2001 From: "plind44@gmail.com" Date: Tue, 17 Sep 2013 19:40:43 +0000 Subject: [PATCH] MIPS: Tweak StoreKeyed. Port r16771 (536eb66) Original commit message: Avoid corrupting its input in some cases. BUG=none TEST=test/mjsunit/lithium/StoreKeyed*.js R=plind44@gmail.com Review URL: https://codereview.chromium.org/23537053 Patch from Balazs Kilvady . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16779 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/lithium-codegen-mips.cc | 52 ++++++++++++++++++++++------------------ src/mips/lithium-mips.cc | 32 ++++++++++++------------- 2 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index a50fe5a..42701b9 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -4232,20 +4232,25 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { + Register address = scratch0(); FPURegister value(ToDoubleRegister(instr->value())); if (key_is_constant) { - __ Addu(scratch0(), external_pointer, constant_key << - element_size_shift); + if (constant_key != 0) { + __ Addu(address, external_pointer, + Operand(constant_key << element_size_shift)); + } else { + address = external_pointer; + } } else { - __ sll(scratch0(), key, shift_size); - __ Addu(scratch0(), scratch0(), external_pointer); + __ sll(address, key, shift_size); + __ Addu(address, external_pointer, address); } if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { __ cvt_s_d(double_scratch0(), value); - __ swc1(double_scratch0(), MemOperand(scratch0(), additional_offset)); + __ swc1(double_scratch0(), MemOperand(address, additional_offset)); } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS - __ sdc1(value, MemOperand(scratch0(), additional_offset)); + __ sdc1(value, MemOperand(address, additional_offset)); } } else { Register value(ToRegister(instr->value())); @@ -4287,33 +4292,29 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { DoubleRegister value = ToDoubleRegister(instr->value()); Register elements = ToRegister(instr->elements()); - Register key = no_reg; Register scratch = scratch0(); + DoubleRegister double_scratch = double_scratch0(); bool key_is_constant = instr->key()->IsConstantOperand(); - int constant_key = 0; - Label not_nan; + Label not_nan, done; // Calculate the effective address of the slot in the array to store the // double value. + int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); if (key_is_constant) { - constant_key = ToInteger32(LConstantOperand::cast(instr->key())); + int constant_key = ToInteger32(LConstantOperand::cast(instr->key())); if (constant_key & 0xF0000000) { Abort(kArrayIndexConstantValueTooBig); } + __ Addu(scratch, elements, + Operand((constant_key << element_size_shift) + + FixedDoubleArray::kHeaderSize - kHeapObjectTag)); } else { - key = ToRegister(instr->key()); - } - int element_size_shift = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS); - int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) - ? (element_size_shift - kSmiTagSize) : element_size_shift; - if (key_is_constant) { - __ Addu(scratch, elements, Operand((constant_key << element_size_shift) + - FixedDoubleArray::kHeaderSize - kHeapObjectTag)); - } else { - __ sll(scratch, key, shift_size); - __ Addu(scratch, elements, Operand(scratch)); - __ Addu(scratch, scratch, + int shift_size = (instr->hydrogen()->key()->representation().IsSmi()) + ? (element_size_shift - kSmiTagSize) : element_size_shift; + __ Addu(scratch, elements, Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); + __ sll(at, ToRegister(instr->key()), shift_size); + __ Addu(scratch, scratch, at); } if (instr->NeedsCanonicalization()) { @@ -4324,12 +4325,17 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { // Only load canonical NaN if the comparison above set the overflow. __ bind(&is_nan); - __ Move(value, FixedDoubleArray::canonical_not_the_hole_nan_as_double()); + __ Move(double_scratch, + FixedDoubleArray::canonical_not_the_hole_nan_as_double()); + __ sdc1(double_scratch, MemOperand(scratch, instr->additional_index() << + element_size_shift)); + __ Branch(&done); } __ bind(¬_nan); __ sdc1(value, MemOperand(scratch, instr->additional_index() << element_size_shift)); + __ bind(&done); } diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index ad3b854..a7319ae 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -2125,8 +2125,6 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { - ElementsKind elements_kind = instr->elements_kind(); - if (!instr->is_external()) { ASSERT(instr->elements()->representation().IsTagged()); bool needs_write_barrier = instr->NeedsWriteBarrier(); @@ -2137,14 +2135,18 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { if (instr->value()->representation().IsDouble()) { object = UseRegisterAtStart(instr->elements()); key = UseRegisterOrConstantAtStart(instr->key()); - val = UseTempRegister(instr->value()); + val = UseRegister(instr->value()); } else { ASSERT(instr->value()->representation().IsSmiOrTagged()); - object = UseTempRegister(instr->elements()); - val = needs_write_barrier ? UseTempRegister(instr->value()) - : UseRegisterAtStart(instr->value()); - key = needs_write_barrier ? UseTempRegister(instr->key()) - : UseRegisterOrConstantAtStart(instr->key()); + if (needs_write_barrier) { + object = UseTempRegister(instr->elements()); + val = UseTempRegister(instr->value()); + key = UseTempRegister(instr->key()); + } else { + object = UseRegisterAtStart(instr->elements()); + val = UseRegisterAtStart(instr->value()); + key = UseRegisterOrConstantAtStart(instr->key()); + } } return new(zone()) LStoreKeyed(object, key, val); @@ -2152,17 +2154,13 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { ASSERT( (instr->value()->representation().IsInteger32() && - (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && - (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || + (instr->elements_kind() != EXTERNAL_FLOAT_ELEMENTS) && + (instr->elements_kind() != EXTERNAL_DOUBLE_ELEMENTS)) || (instr->value()->representation().IsDouble() && - ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || - (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); + ((instr->elements_kind() == EXTERNAL_FLOAT_ELEMENTS) || + (instr->elements_kind() == EXTERNAL_DOUBLE_ELEMENTS)))); ASSERT(instr->elements()->representation().IsExternal()); - bool val_is_temp_register = - elements_kind == EXTERNAL_PIXEL_ELEMENTS || - elements_kind == EXTERNAL_FLOAT_ELEMENTS; - LOperand* val = val_is_temp_register ? UseTempRegister(instr->value()) - : UseRegister(instr->value()); + LOperand* val = UseRegister(instr->value()); LOperand* key = UseRegisterOrConstantAtStart(instr->key()); LOperand* external_pointer = UseRegister(instr->elements()); -- 2.7.4