diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc index 5cb1bd3603..df17b6f864 100644 --- a/src/arm/codegen-arm.cc +++ b/src/arm/codegen-arm.cc @@ -1222,7 +1222,21 @@ void CodeGenerator::SmiOperation(Token::Value op, case Token::SHR: case Token::SAR: { ASSERT(!reversed); - TypeInfo result = TypeInfo::Integer32(); + TypeInfo result = + (op == Token::SAR) ? TypeInfo::Integer32() : TypeInfo::Number(); + if (!reversed) { + if (op == Token::SHR) { + if (int_value >= 2) { + result = TypeInfo::Smi(); + } else if (int_value >= 1) { + result = TypeInfo::Integer32(); + } + } else { + if (int_value >= 1) { + result = TypeInfo::Smi(); + } + } + } Register scratch = VirtualFrame::scratch0(); Register scratch2 = VirtualFrame::scratch1(); int shift_value = int_value & 0x1f; // least significant 5 bits diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index 25ad52de6b..cc89cc7db5 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -1250,7 +1250,7 @@ void DeferredInlineBinaryOperation::GenerateNonSmiInput() { if (left_info_.IsSmi()) { // Right is a heap object. __ JumpIfNotNumber(right_, right_info_, entry_label()); - __ ConvertToInt32(right_, right_, dst_, left_info_, entry_label()); + __ ConvertToInt32(right_, right_, dst_, right_info_, entry_label()); __ mov(dst_, Operand(left_)); __ SmiUntag(dst_); } else if (right_info_.IsSmi()) { @@ -1270,11 +1270,11 @@ void DeferredInlineBinaryOperation::GenerateNonSmiInput() { // Both were heap objects. __ rcl(right_, 1); // Put tag back. __ JumpIfNotNumber(right_, right_info_, entry_label()); - __ ConvertToInt32(right_, right_, no_reg, left_info_, entry_label()); + __ ConvertToInt32(right_, right_, no_reg, right_info_, entry_label()); __ jmp(&got_both); __ bind(&only_right_is_heap_object); __ JumpIfNotNumber(right_, right_info_, entry_label()); - __ ConvertToInt32(right_, right_, no_reg, left_info_, entry_label()); + __ ConvertToInt32(right_, right_, no_reg, right_info_, entry_label()); __ bind(&got_both); } } @@ -1940,6 +1940,7 @@ Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr, // Use a fresh answer register to avoid spilling the left operand. answer = allocator_->Allocate(); ASSERT(answer.is_valid()); + DeferredInlineBinaryOperation* deferred = new DeferredInlineBinaryOperation(op, answer.reg(), @@ -4605,10 +4606,11 @@ void CodeGenerator::VisitForInStatement(ForInStatement* node) { // loop. edx: i'th entry of the enum cache (or string there of) frame_->EmitPush(ebx); { Reference each(this, node->each()); - // Loading a reference may leave the frame in an unspilled state. - frame_->SpillAll(); if (!each.is_illegal()) { if (each.size() > 0) { + // Loading a reference may leave the frame in an unspilled state. + frame_->SpillAll(); + // Get the value (under the reference on the stack) from memory. frame_->EmitPush(frame_->ElementAt(each.size())); each.SetValue(NOT_CONST_INIT); frame_->Drop(2); diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc index 66ec04facb..24538461ff 100644 --- a/src/ia32/macro-assembler-ia32.cc +++ b/src/ia32/macro-assembler-ia32.cc @@ -1549,12 +1549,10 @@ void MacroAssembler::ConvertToInt32(Register dst, if (scratch.is(no_reg)) scratch = dst; cvttsd2si(scratch, FieldOperand(source, HeapNumber::kValueOffset)); cmp(scratch, 0x80000000u); - if (push_pop || dst.is(source)) { + if (push_pop) { j(not_equal, &done); - if (push_pop) { - pop(dst); - jmp(on_not_int32); - } + pop(dst); + jmp(on_not_int32); } else { j(equal, on_not_int32); } diff --git a/src/type-info.h b/src/type-info.h index 91ecab8f5b..f588e56112 100644 --- a/src/type-info.h +++ b/src/type-info.h @@ -54,7 +54,7 @@ class TypeInfo { static inline TypeInfo Primitive(); // We know it's a number of some sort. static inline TypeInfo Number(); - // We know it's signed or unsigned 32 bit integer. + // We know it's signed 32 bit integer. static inline TypeInfo Integer32(); // We know it's a Smi. static inline TypeInfo Smi(); @@ -113,19 +113,15 @@ class TypeInfo { } - // Integer32 is an integer that can be represented as either a signed - // 32-bit integer or as an unsigned 32-bit integer. It has to be - // in the range [-2^31, 2^32 - 1]. We also have to check for negative 0 - // as it is not an Integer32. + // Integer32 is an integer that can be represented as a signed + // 32-bit integer. It has to be in the range [-2^31, 2^31 - 1]. + // We also have to check for negative 0 as it is not an Integer32. static inline bool IsInt32Double(double value) { const DoubleRepresentation minus_zero(-0.0); DoubleRepresentation rep(value); if (rep.bits == minus_zero.bits) return false; - if (value >= kMinInt && value <= kMaxUInt32) { - if (value <= kMaxInt && value == static_cast(value)) { - return true; - } - if (value == static_cast(value)) return true; + if (value >= kMinInt && value <= kMaxInt) { + if (value == static_cast(value)) return true; } return false; } diff --git a/test/mjsunit/bitops-info.js b/test/mjsunit/bitops-info.js new file mode 100644 index 0000000000..4660fdf96b --- /dev/null +++ b/test/mjsunit/bitops-info.js @@ -0,0 +1,77 @@ +// Copyright 2010 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +function non_int32() { + return 2600822924; // It's not a signed Int32. +} + +function hidden_smi() { + return 46512102; // It's a Smi +} + +function hidden_int32() { + return 1600822924; // It's a signed Int32. +} + + +function f() { + var x = non_int32(); // Not a constant. + var y = hidden_smi(); // Not a constant. + var z = hidden_int32(); + assertEquals(46512102 & 2600822924, 46512102 & x, "1"); + assertEquals(1600822924 & 2600822924, 1600822924 & x, "2"); + assertEquals(2600822924 & 2600822924, 2600822924 & x, "3"); + assertEquals(46512102 & 46512102, 46512102 & y, "4"); + assertEquals(1600822924 & 46512102, 1600822924 & y, "5"); + assertEquals(2600822924 & 46512102, 2600822924 & y, "6"); + assertEquals(46512102 & 1600822924, 46512102 & z, "7"); + assertEquals(1600822924 & 1600822924, 1600822924 & z, "8"); + assertEquals(2600822924 & 1600822924, 2600822924 & z, "9"); + assertEquals(46512102 & 2600822924, y & x, "10"); + assertEquals(1600822924 & 2600822924, z & x, "11"); + + assertEquals(46512102 & 2600822924, x & 46512102, "1rev"); + assertEquals(1600822924 & 2600822924, x & 1600822924, "2rev"); + assertEquals(2600822924 & 2600822924, x & 2600822924, "3rev"); + assertEquals(46512102 & 46512102, y & 46512102, "4rev"); + assertEquals(1600822924 & 46512102, y & 1600822924, "5rev"); + assertEquals(2600822924 & 46512102, y & 2600822924, "6rev"); + assertEquals(46512102 & 1600822924, z & 46512102, "7rev"); + assertEquals(1600822924 & 1600822924, z & 1600822924, "8rev"); + assertEquals(2600822924 & 1600822924, z & 2600822924, "9rev"); + assertEquals(46512102 & 2600822924, x & y, "10rev"); + assertEquals(1600822924 & 2600822924, x & z, "11rev"); + + assertEquals(2600822924 & 2600822924, x & x, "xx"); + assertEquals(y, y & y, "yy"); + assertEquals(z, z & z, "zz"); +} + + +for (var i = 0; i < 5; i++) { + f(); +}