From 07f68ec357f0593e8881567c6696ec6191d3ee70 Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Fri, 23 Apr 2010 08:05:13 +0000 Subject: [PATCH] Compute static type information for remaining expression types on x64 platform. Review URL: http://codereview.chromium.org/1751008 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4481 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/codegen-ia32.cc | 16 +++--- src/x64/codegen-x64.cc | 114 +++++++++++++++++++++------------------ 2 files changed, 71 insertions(+), 59 deletions(-) diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index 95dbcd4b25..66a1774e8d 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -7047,6 +7047,12 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { (node->expression()->AsBinaryOperation() != NULL && node->expression()->AsBinaryOperation()->ResultOverwriteAllowed()); switch (op) { + case Token::NOT: + case Token::DELETE: + case Token::TYPEOF: + UNREACHABLE(); // handled above + break; + case Token::SUB: { GenericUnaryOpStub stub(Token::SUB, overwrite); Result operand = frame_->Pop(); @@ -7087,11 +7093,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { __ not_(answer.reg()); continue_label.Bind(&answer); - if (operand_info.IsInteger32()) { - answer.set_type_info(TypeInfo::Integer32()); - } else { - answer.set_type_info(TypeInfo::Number()); - } + answer.set_type_info(TypeInfo::Integer32()); frame_->Push(&answer); } break; @@ -7121,8 +7123,6 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { break; } default: - // NOT, DELETE, TYPEOF, and VOID are handled outside the - // switch. UNREACHABLE(); } } @@ -7333,7 +7333,7 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) { __ setcc(overflow, tmp.reg()); __ or_(Operand(tmp.reg()), new_value.reg()); __ test(tmp.reg(), Immediate(kSmiTagMask)); - tmp.Unuse(); + tmp.Unusec(); deferred->Branch(not_zero); } else { // Otherwise we test separately for overflow and smi tag. diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc index 4fac89afed..9ce58212dc 100644 --- a/src/x64/codegen-x64.cc +++ b/src/x64/codegen-x64.cc @@ -3117,6 +3117,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { GenericUnaryOpStub stub(Token::SUB, overwrite); Result operand = frame_->Pop(); Result answer = frame_->CallStub(&stub, &operand); + answer.set_type_info(TypeInfo::Number()); frame_->Push(&answer); break; } @@ -3140,6 +3141,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { frame_->Spill(answer.reg()); __ SmiNot(answer.reg(), answer.reg()); continue_label.Bind(&answer); + answer.set_type_info(TypeInfo::Smi()); frame_->Push(&answer); break; } @@ -3148,6 +3150,7 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { // Smi check. JumpTarget continue_label; Result operand = frame_->Pop(); + TypeInfo operand_info = operand.type_info(); operand.ToRegister(); Condition is_smi = masm_->CheckSmi(operand.reg()); continue_label.Branch(is_smi, &operand); @@ -3156,10 +3159,16 @@ void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) { CALL_FUNCTION, 1); continue_label.Bind(&answer); + if (operand_info.IsSmi()) { + answer.set_type_info(TypeInfo::Smi()); + } else if (operand_info.IsInteger32()) { + answer.set_type_info(TypeInfo::Integer32()); + } else { + answer.set_type_info(TypeInfo::Number()); + } frame_->Push(&answer); break; } - default: UNREACHABLE(); } @@ -5720,6 +5729,57 @@ void DeferredInlineBinaryOperation::Generate() { } +static TypeInfo CalculateTypeInfo(TypeInfo operands_type, + Token::Value op, + const Result& right, + const Result& left) { + // Set TypeInfo of result according to the operation performed. + // We rely on the fact that smis have a 32 bit payload on x64. + STATIC_ASSERT(kSmiValueSize == 32); + switch (op) { + case Token::COMMA: + return right.type_info(); + case Token::OR: + case Token::AND: + // Result type can be either of the two input types. + return operands_type; + case Token::BIT_OR: + case Token::BIT_XOR: + case Token::BIT_AND: + // Result is always a smi. + return TypeInfo::Smi(); + case Token::SAR: + case Token::SHL: + // Result is always a smi. + return TypeInfo::Smi(); + case Token::SHR: + // Result of x >>> y is always a smi if masked y >= 1, otherwise a number. + return (right.is_constant() && right.handle()->IsSmi() + && (Smi::cast(*right.handle())->value() & 0x1F) >= 1) + ? TypeInfo::Smi() + : TypeInfo::Number(); + case Token::ADD: + if (operands_type.IsNumber()) { + return TypeInfo::Number(); + } else if (left.type_info().IsString() || right.type_info().IsString()) { + return TypeInfo::String(); + } else { + return TypeInfo::Unknown(); + } + case Token::SUB: + case Token::MUL: + case Token::DIV: + case Token::MOD: + // Result is always a number. + return TypeInfo::Number(); + default: + UNREACHABLE(); + } + UNREACHABLE(); + return TypeInfo::Unknown(); +} + + void CodeGenerator::GenericBinaryOperation(Token::Value op, StaticType* type, OverwriteMode overwrite_mode) { @@ -5785,6 +5845,8 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, TypeInfo operands_type = TypeInfo::Combine(left.type_info(), right.type_info()); + TypeInfo result_type = CalculateTypeInfo(operands_type, op, right, left); + Result answer; if (left_is_non_smi_constant || right_is_non_smi_constant) { GenericBinaryOpStub stub(op, @@ -5815,56 +5877,6 @@ void CodeGenerator::GenericBinaryOperation(Token::Value op, } } - // Set TypeInfo of result according to the operation performed. - // We rely on the fact that smis have a 32 bit payload on x64. - ASSERT(kSmiValueSize == 32); - TypeInfo result_type = TypeInfo::Unknown(); - switch (op) { - case Token::COMMA: - result_type = right.type_info(); - break; - case Token::OR: - case Token::AND: - // Result type can be either of the two input types. - result_type = operands_type; - break; - case Token::BIT_OR: - case Token::BIT_XOR: - case Token::BIT_AND: - // Result is always a smi. - result_type = TypeInfo::Smi(); - break; - case Token::SAR: - case Token::SHL: - // Result is always a smi. - result_type = TypeInfo::Smi(); - break; - case Token::SHR: - // Result of x >>> y is always a smi if masked y >= 1, otherwise a number. - result_type = (right.is_constant() && right.handle()->IsSmi() - && (Smi::cast(*right.handle())->value() & 0x1F) >= 1) - ? TypeInfo::Smi() - : TypeInfo::Number(); - break; - case Token::ADD: - if (operands_type.IsNumber()) { - result_type = TypeInfo::Number(); - } else if (operands_type.IsString()) { - result_type = TypeInfo::String(); - } else { - result_type = TypeInfo::Unknown(); - } - break; - case Token::SUB: - case Token::MUL: - case Token::DIV: - case Token::MOD: - // Result is always a number. - result_type = TypeInfo::Number(); - break; - default: - UNREACHABLE(); - } answer.set_type_info(result_type); frame_->Push(&answer); }