From: fschneider@chromium.org Date: Wed, 17 Mar 2010 09:49:03 +0000 (+0000) Subject: Fix bug in propagation of type information into registers. X-Git-Tag: upstream/4.7.83~22229 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=3ca93673411505f7cdaef871edd1f77cd50459cd;p=platform%2Fupstream%2Fv8.git Fix bug in propagation of type information into registers. The number type information of results has to be also copied when calling ToRegister with a fixed register as destination. Also fix an unbound label and a missing CpuFeatures scope. Review URL: http://codereview.chromium.org/987003 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4155 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index 07cd555..b0793b6 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -1578,6 +1578,7 @@ Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, // if right is a smi we make a fast case if left is either a smi // or a heapnumber. if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) { + CpuFeatures::Scope use_sse2(SSE2); __ mov(answer.reg(), left->reg()); // Fast case - both are actually smis. if (!left->number_info().IsSmi()) { @@ -1608,6 +1609,7 @@ Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, __ SmiUntag(answer.reg()); } + __ bind(&do_op); __ SmiUntag(ecx); // Perform the operation. switch (op) { @@ -6652,7 +6654,6 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { break; } frame_->Push(&value); - } else { Load(node->expression()); bool overwrite = @@ -6663,38 +6664,58 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { GenericUnaryOpStub stub(Token::SUB, overwrite); Result operand = frame_->Pop(); Result answer = frame_->CallStub(&stub, &operand); + answer.set_number_info(NumberInfo::Number()); frame_->Push(&answer); break; } - case Token::BIT_NOT: { // Smi check. JumpTarget smi_label; JumpTarget continue_label; Result operand = frame_->Pop(); + NumberInfo operand_info = operand.number_info(); operand.ToRegister(); - __ test(operand.reg(), Immediate(kSmiTagMask)); - smi_label.Branch(zero, &operand, taken); - - GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); - Result answer = frame_->CallStub(&stub, &operand); - continue_label.Jump(&answer); - - smi_label.Bind(&answer); - answer.ToRegister(); - frame_->Spill(answer.reg()); - __ not_(answer.reg()); - __ and_(answer.reg(), ~kSmiTagMask); // Remove inverted smi-tag. - - continue_label.Bind(&answer); - frame_->Push(&answer); + if (operand_info.IsSmi()) { + if (FLAG_debug_code) { + __ AbortIfNotSmi(operand.reg(), "Operand not a smi."); + } + frame_->Spill(operand.reg()); + // Set smi tag bit. It will be reset by the not operation. + __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); + __ not_(operand.reg()); + Result answer = operand; + answer.set_number_info(NumberInfo::Smi()); + frame_->Push(&answer); + } else { + __ test(operand.reg(), Immediate(kSmiTagMask)); + smi_label.Branch(zero, &operand, taken); + + GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); + Result answer = frame_->CallStub(&stub, &operand); + continue_label.Jump(&answer); + + smi_label.Bind(&answer); + answer.ToRegister(); + frame_->Spill(answer.reg()); + // Set smi tag bit. It will be reset by the not operation. + __ lea(answer.reg(), Operand(answer.reg(), kSmiTagMask)); + __ not_(answer.reg()); + + continue_label.Bind(&answer); + if (operand_info.IsInteger32()) { + answer.set_number_info(NumberInfo::Integer32()); + } else { + answer.set_number_info(NumberInfo::Number()); + } + frame_->Push(&answer); + } break; } - case Token::ADD: { // Smi check. JumpTarget continue_label; Result operand = frame_->Pop(); + NumberInfo operand_info = operand.number_info(); operand.ToRegister(); __ test(operand.reg(), Immediate(kSmiTagMask)); continue_label.Branch(zero, &operand, taken); @@ -6704,10 +6725,16 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { CALL_FUNCTION, 1); continue_label.Bind(&answer); + if (operand_info.IsSmi()) { + answer.set_number_info(NumberInfo::Smi()); + } else if (operand_info.IsInteger32()) { + answer.set_number_info(NumberInfo::Integer32()); + } else { + answer.set_number_info(NumberInfo::Number()); + } frame_->Push(&answer); break; } - default: // NOT, DELETE, TYPEOF, and VOID are handled outside the // switch. diff --git a/src/ia32/register-allocator-ia32.cc b/src/ia32/register-allocator-ia32.cc index f04390e..0129314 100644 --- a/src/ia32/register-allocator-ia32.cc +++ b/src/ia32/register-allocator-ia32.cc @@ -122,6 +122,7 @@ void Result::ToRegister(Register target) { } } } + fresh.set_number_info(number_info()); fresh.set_untagged_int32(is_untagged_int32()); *this = fresh; } else if (is_register() && reg().is(target)) { diff --git a/src/x64/register-allocator-x64.cc b/src/x64/register-allocator-x64.cc index d4a47e8..9dc97b8 100644 --- a/src/x64/register-allocator-x64.cc +++ b/src/x64/register-allocator-x64.cc @@ -44,6 +44,7 @@ void Result::ToRegister() { ASSERT(fresh.is_valid()); CodeGeneratorScope::Current()->masm()->Move(fresh.reg(), handle()); // This result becomes a copy of the fresh one. + fresh.set_number_info(number_info()); *this = fresh; } ASSERT(is_register()); @@ -61,6 +62,7 @@ void Result::ToRegister(Register target) { ASSERT(is_constant()); CodeGeneratorScope::Current()->masm()->Move(fresh.reg(), handle()); } + fresh.set_number_info(number_info()); *this = fresh; } else if (is_register() && reg().is(target)) { ASSERT(CodeGeneratorScope::Current()->has_valid_frame());