Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: src/x64/codegen-x64.cc

Issue 1751008: Compute static type information for remaining expression types on x64 platfor... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 3099 matching lines...) Expand 10 before | Expand all | Expand 10 after
3110 case Token::NOT: 3110 case Token::NOT:
3111 case Token::DELETE: 3111 case Token::DELETE:
3112 case Token::TYPEOF: 3112 case Token::TYPEOF:
3113 UNREACHABLE(); // handled above 3113 UNREACHABLE(); // handled above
3114 break; 3114 break;
3115 3115
3116 case Token::SUB: { 3116 case Token::SUB: {
3117 GenericUnaryOpStub stub(Token::SUB, overwrite); 3117 GenericUnaryOpStub stub(Token::SUB, overwrite);
3118 Result operand = frame_->Pop(); 3118 Result operand = frame_->Pop();
3119 Result answer = frame_->CallStub(&stub, &operand); 3119 Result answer = frame_->CallStub(&stub, &operand);
3120 answer.set_type_info(TypeInfo::Number());
3120 frame_->Push(&answer); 3121 frame_->Push(&answer);
3121 break; 3122 break;
3122 } 3123 }
3123 3124
3124 case Token::BIT_NOT: { 3125 case Token::BIT_NOT: {
3125 // Smi check. 3126 // Smi check.
3126 JumpTarget smi_label; 3127 JumpTarget smi_label;
3127 JumpTarget continue_label; 3128 JumpTarget continue_label;
3128 Result operand = frame_->Pop(); 3129 Result operand = frame_->Pop();
3129 operand.ToRegister(); 3130 operand.ToRegister();
3130 3131
3131 Condition is_smi = masm_->CheckSmi(operand.reg()); 3132 Condition is_smi = masm_->CheckSmi(operand.reg());
3132 smi_label.Branch(is_smi, &operand); 3133 smi_label.Branch(is_smi, &operand);
3133 3134
3134 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite); 3135 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
3135 Result answer = frame_->CallStub(&stub, &operand); 3136 Result answer = frame_->CallStub(&stub, &operand);
3136 continue_label.Jump(&answer); 3137 continue_label.Jump(&answer);
3137 3138
3138 smi_label.Bind(&answer); 3139 smi_label.Bind(&answer);
3139 answer.ToRegister(); 3140 answer.ToRegister();
3140 frame_->Spill(answer.reg()); 3141 frame_->Spill(answer.reg());
3141 __ SmiNot(answer.reg(), answer.reg()); 3142 __ SmiNot(answer.reg(), answer.reg());
3142 continue_label.Bind(&answer); 3143 continue_label.Bind(&answer);
3144 answer.set_type_info(TypeInfo::Smi());
3143 frame_->Push(&answer); 3145 frame_->Push(&answer);
3144 break; 3146 break;
3145 } 3147 }
3146 3148
3147 case Token::ADD: { 3149 case Token::ADD: {
3148 // Smi check. 3150 // Smi check.
3149 JumpTarget continue_label; 3151 JumpTarget continue_label;
3150 Result operand = frame_->Pop(); 3152 Result operand = frame_->Pop();
3153 TypeInfo operand_info = operand.type_info();
3151 operand.ToRegister(); 3154 operand.ToRegister();
3152 Condition is_smi = masm_->CheckSmi(operand.reg()); 3155 Condition is_smi = masm_->CheckSmi(operand.reg());
3153 continue_label.Branch(is_smi, &operand); 3156 continue_label.Branch(is_smi, &operand);
3154 frame_->Push(&operand); 3157 frame_->Push(&operand);
3155 Result answer = frame_->InvokeBuiltin(Builtins::TO_NUMBER, 3158 Result answer = frame_->InvokeBuiltin(Builtins::TO_NUMBER,
3156 CALL_FUNCTION, 1); 3159 CALL_FUNCTION, 1);
3157 3160
3158 continue_label.Bind(&answer); 3161 continue_label.Bind(&answer);
3162 if (operand_info.IsSmi()) {
3163 answer.set_type_info(TypeInfo::Smi());
3164 } else if (operand_info.IsInteger32()) {
3165 answer.set_type_info(TypeInfo::Integer32());
3166 } else {
3167 answer.set_type_info(TypeInfo::Number());
3168 }
3159 frame_->Push(&answer); 3169 frame_->Push(&answer);
3160 break; 3170 break;
3161 } 3171 }
3162
3163 default: 3172 default:
3164 UNREACHABLE(); 3173 UNREACHABLE();
3165 } 3174 }
3166 } 3175 }
3167 } 3176 }
3168 3177
3169 3178
3170 // The value in dst was optimistically incremented or decremented. 3179 // The value in dst was optimistically incremented or decremented.
3171 // The result overflowed or was not smi tagged. Call into the runtime 3180 // The result overflowed or was not smi tagged. Call into the runtime
3172 // to convert the argument to a number, and call the specialized add 3181 // to convert the argument to a number, and call the specialized add
(...skipping 2540 matching lines...) Expand 10 before | Expand all | Expand 10 after
5713 }; 5722 };
5714 5723
5715 5724
5716 void DeferredInlineBinaryOperation::Generate() { 5725 void DeferredInlineBinaryOperation::Generate() {
5717 GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB); 5726 GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB);
5718 stub.GenerateCall(masm_, left_, right_); 5727 stub.GenerateCall(masm_, left_, right_);
5719 if (!dst_.is(rax)) __ movq(dst_, rax); 5728 if (!dst_.is(rax)) __ movq(dst_, rax);
5720 } 5729 }
5721 5730
5722 5731
5732 static TypeInfo CalculateTypeInfo(TypeInfo operands_type,
5733 Token::Value op,
5734 const Result& right,
5735 const Result& left) {
5736 // Set TypeInfo of result according to the operation performed.
5737 // We rely on the fact that smis have a 32 bit payload on x64.
5738 STATIC_ASSERT(kSmiValueSize == 32);
5739 switch (op) {
5740 case Token::COMMA:
5741 return right.type_info();
5742 case Token::OR:
5743 case Token::AND:
5744 // Result type can be either of the two input types.
5745 return operands_type;
5746 case Token::BIT_OR:
5747 case Token::BIT_XOR:
5748 case Token::BIT_AND:
5749 // Result is always a smi.
5750 return TypeInfo::Smi();
5751 case Token::SAR:
5752 case Token::SHL:
5753 // Result is always a smi.
5754 return TypeInfo::Smi();
5755 case Token::SHR:
5756 // Result of x >>> y is always a smi if masked y >= 1, otherwise a number.
5757 return (right.is_constant() && right.handle()->IsSmi()
5758 && (Smi::cast(*right.handle())->value() & 0x1F) >= 1)
5759 ? TypeInfo::Smi()
5760 : TypeInfo::Number();
5761 case Token::ADD:
5762 if (operands_type.IsNumber()) {
5763 return TypeInfo::Number();
5764 } else if (left.type_info().IsString() || right.type_info().IsString()) {
5765 return TypeInfo::String();
5766 } else {
5767 return TypeInfo::Unknown();
5768 }
5769 case Token::SUB:
5770 case Token::MUL:
5771 case Token::DIV:
5772 case Token::MOD:
5773 // Result is always a number.
5774 return TypeInfo::Number();
5775 default:
5776 UNREACHABLE();
5777 }
5778 UNREACHABLE();
5779 return TypeInfo::Unknown();
5780 }
5781
5782
5723 void CodeGenerator::GenericBinaryOperation(Token::Value op, 5783 void CodeGenerator::GenericBinaryOperation(Token::Value op,
5724 StaticType* type, 5784 StaticType* type,
5725 OverwriteMode overwrite_mode) { 5785 OverwriteMode overwrite_mode) {
5726 Comment cmnt(masm_, "[ BinaryOperation"); 5786 Comment cmnt(masm_, "[ BinaryOperation");
5727 Comment cmnt_token(masm_, Token::String(op)); 5787 Comment cmnt_token(masm_, Token::String(op));
5728 5788
5729 if (op == Token::COMMA) { 5789 if (op == Token::COMMA) {
5730 // Simply discard left value. 5790 // Simply discard left value.
5731 frame_->Nip(1); 5791 frame_->Nip(1);
5732 return; 5792 return;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
5778 // Compute the constant result at compile time, and leave it on the frame. 5838 // Compute the constant result at compile time, and leave it on the frame.
5779 int left_int = Smi::cast(*left.handle())->value(); 5839 int left_int = Smi::cast(*left.handle())->value();
5780 int right_int = Smi::cast(*right.handle())->value(); 5840 int right_int = Smi::cast(*right.handle())->value();
5781 if (FoldConstantSmis(op, left_int, right_int)) return; 5841 if (FoldConstantSmis(op, left_int, right_int)) return;
5782 } 5842 }
5783 5843
5784 // Get number type of left and right sub-expressions. 5844 // Get number type of left and right sub-expressions.
5785 TypeInfo operands_type = 5845 TypeInfo operands_type =
5786 TypeInfo::Combine(left.type_info(), right.type_info()); 5846 TypeInfo::Combine(left.type_info(), right.type_info());
5787 5847
5848 TypeInfo result_type = CalculateTypeInfo(operands_type, op, right, left);
5849
5788 Result answer; 5850 Result answer;
5789 if (left_is_non_smi_constant || right_is_non_smi_constant) { 5851 if (left_is_non_smi_constant || right_is_non_smi_constant) {
5790 GenericBinaryOpStub stub(op, 5852 GenericBinaryOpStub stub(op,
5791 overwrite_mode, 5853 overwrite_mode,
5792 NO_SMI_CODE_IN_STUB, 5854 NO_SMI_CODE_IN_STUB,
5793 operands_type); 5855 operands_type);
5794 answer = stub.GenerateCall(masm_, frame_, &left, &right); 5856 answer = stub.GenerateCall(masm_, frame_, &left, &right);
5795 } else if (right_is_smi_constant) { 5857 } else if (right_is_smi_constant) {
5796 answer = ConstantSmiBinaryOperation(op, &left, right.handle(), 5858 answer = ConstantSmiBinaryOperation(op, &left, right.handle(),
5797 type, false, overwrite_mode); 5859 type, false, overwrite_mode);
(...skipping 10 matching lines...) Expand all
5808 answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode); 5870 answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode);
5809 } else { 5871 } else {
5810 GenericBinaryOpStub stub(op, 5872 GenericBinaryOpStub stub(op,
5811 overwrite_mode, 5873 overwrite_mode,
5812 NO_GENERIC_BINARY_FLAGS, 5874 NO_GENERIC_BINARY_FLAGS,
5813 operands_type); 5875 operands_type);
5814 answer = stub.GenerateCall(masm_, frame_, &left, &right); 5876 answer = stub.GenerateCall(masm_, frame_, &left, &right);
5815 } 5877 }
5816 } 5878 }
5817 5879
5818 // Set TypeInfo of result according to the operation performed.
5819 // We rely on the fact that smis have a 32 bit payload on x64.
5820 ASSERT(kSmiValueSize == 32);
5821 TypeInfo result_type = TypeInfo::Unknown();
5822 switch (op) {
5823 case Token::COMMA:
5824 result_type = right.type_info();
5825 break;
5826 case Token::OR:
5827 case Token::AND:
5828 // Result type can be either of the two input types.
5829 result_type = operands_type;
5830 break;
5831 case Token::BIT_OR:
5832 case Token::BIT_XOR:
5833 case Token::BIT_AND:
5834 // Result is always a smi.
5835 result_type = TypeInfo::Smi();
5836 break;
5837 case Token::SAR:
5838 case Token::SHL:
5839 // Result is always a smi.
5840 result_type = TypeInfo::Smi();
5841 break;
5842 case Token::SHR:
5843 // Result of x >>> y is always a smi if masked y >= 1, otherwise a number.
5844 result_type = (right.is_constant() && right.handle()->IsSmi()
5845 && (Smi::cast(*right.handle())->value() & 0x1F) >= 1)
5846 ? TypeInfo::Smi()
5847 : TypeInfo::Number();
5848 break;
5849 case Token::ADD:
5850 if (operands_type.IsNumber()) {
5851 result_type = TypeInfo::Number();
5852 } else if (operands_type.IsString()) {
5853 result_type = TypeInfo::String();
5854 } else {
5855 result_type = TypeInfo::Unknown();
5856 }
5857 break;
5858 case Token::SUB:
5859 case Token::MUL:
5860 case Token::DIV:
5861 case Token::MOD:
5862 // Result is always a number.
5863 result_type = TypeInfo::Number();
5864 break;
5865 default:
5866 UNREACHABLE();
5867 }
5868 answer.set_type_info(result_type); 5880 answer.set_type_info(result_type);
5869 frame_->Push(&answer); 5881 frame_->Push(&answer);
5870 } 5882 }
5871 5883
5872 5884
5873 // Emit a LoadIC call to get the value from receiver and leave it in 5885 // Emit a LoadIC call to get the value from receiver and leave it in
5874 // dst. The receiver register is restored after the call. 5886 // dst. The receiver register is restored after the call.
5875 class DeferredReferenceGetNamedValue: public DeferredCode { 5887 class DeferredReferenceGetNamedValue: public DeferredCode {
5876 public: 5888 public:
5877 DeferredReferenceGetNamedValue(Register dst, 5889 DeferredReferenceGetNamedValue(Register dst,
(...skipping 4589 matching lines...) Expand 10 before | Expand all | Expand 10 after
10467 // Call the function from C++. 10479 // Call the function from C++.
10468 return FUNCTION_CAST<ModuloFunction>(buffer); 10480 return FUNCTION_CAST<ModuloFunction>(buffer);
10469 } 10481 }
10470 10482
10471 #endif 10483 #endif
10472 10484
10473 10485
10474 #undef __ 10486 #undef __
10475 10487
10476 } } // namespace v8::internal 10488 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698