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

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

Issue 593110: Pass the complete number type information into the GenericBinaryOpStub.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 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/x64/codegen-x64.h ('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 5169 matching lines...) Expand 10 before | Expand all | Expand 10 after
5180 right.is_constant() && !right.handle()->IsSmi(); 5180 right.is_constant() && !right.handle()->IsSmi();
5181 5181
5182 if (left_is_smi_constant && right_is_smi_constant) { 5182 if (left_is_smi_constant && right_is_smi_constant) {
5183 // Compute the constant result at compile time, and leave it on the frame. 5183 // Compute the constant result at compile time, and leave it on the frame.
5184 int left_int = Smi::cast(*left.handle())->value(); 5184 int left_int = Smi::cast(*left.handle())->value();
5185 int right_int = Smi::cast(*right.handle())->value(); 5185 int right_int = Smi::cast(*right.handle())->value();
5186 if (FoldConstantSmis(op, left_int, right_int)) return; 5186 if (FoldConstantSmis(op, left_int, right_int)) return;
5187 } 5187 }
5188 5188
5189 // Get number type of left and right sub-expressions. 5189 // Get number type of left and right sub-expressions.
5190 bool only_numbers = left.is_number() && right.is_number(); 5190 NumberInfo::Type operands_type =
5191 bool only_smis = left.is_smi() && right.is_smi(); 5191 NumberInfo::Combine(left.number_info(), right.number_info());
5192 5192
5193 Result answer; 5193 Result answer;
5194 if (left_is_non_smi_constant || right_is_non_smi_constant) { 5194 if (left_is_non_smi_constant || right_is_non_smi_constant) {
5195 GenericBinaryOpStub stub(op, 5195 GenericBinaryOpStub stub(op,
5196 overwrite_mode, 5196 overwrite_mode,
5197 NO_SMI_CODE_IN_STUB, 5197 NO_SMI_CODE_IN_STUB,
5198 only_numbers); 5198 operands_type);
5199 answer = stub.GenerateCall(masm_, frame_, &left, &right); 5199 answer = stub.GenerateCall(masm_, frame_, &left, &right);
5200 } else if (right_is_smi_constant) { 5200 } else if (right_is_smi_constant) {
5201 answer = ConstantSmiBinaryOperation(op, &left, right.handle(), 5201 answer = ConstantSmiBinaryOperation(op, &left, right.handle(),
5202 type, false, overwrite_mode); 5202 type, false, overwrite_mode);
5203 } else if (left_is_smi_constant) { 5203 } else if (left_is_smi_constant) {
5204 answer = ConstantSmiBinaryOperation(op, &right, left.handle(), 5204 answer = ConstantSmiBinaryOperation(op, &right, left.handle(),
5205 type, true, overwrite_mode); 5205 type, true, overwrite_mode);
5206 } else { 5206 } else {
5207 // Set the flags based on the operation, type and loop nesting level. 5207 // Set the flags based on the operation, type and loop nesting level.
5208 // Bit operations always assume they likely operate on Smis. Still only 5208 // Bit operations always assume they likely operate on Smis. Still only
5209 // generate the inline Smi check code if this operation is part of a loop. 5209 // generate the inline Smi check code if this operation is part of a loop.
5210 // For all other operations only inline the Smi check code for likely smis 5210 // For all other operations only inline the Smi check code for likely smis
5211 // if the operation is part of a loop. 5211 // if the operation is part of a loop.
5212 if (loop_nesting() > 0 && (Token::IsBitOp(op) || type->IsLikelySmi())) { 5212 if (loop_nesting() > 0 && (Token::IsBitOp(op) || type->IsLikelySmi())) {
5213 answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode); 5213 answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode);
5214 } else { 5214 } else {
5215 GenericBinaryOpStub stub(op, 5215 GenericBinaryOpStub stub(op,
5216 overwrite_mode, 5216 overwrite_mode,
5217 NO_GENERIC_BINARY_FLAGS, 5217 NO_GENERIC_BINARY_FLAGS,
5218 only_numbers); 5218 operands_type);
5219 answer = stub.GenerateCall(masm_, frame_, &left, &right); 5219 answer = stub.GenerateCall(masm_, frame_, &left, &right);
5220 } 5220 }
5221 } 5221 }
5222 5222
5223 // Set NumberInfo of result according to the operation performed. 5223 // Set NumberInfo of result according to the operation performed.
5224 NumberInfo::Type info = NumberInfo::kUnknown; 5224 // We rely on the fact that smis have a 32 bit payload on x64.
5225 ASSERT(kSmiValueSize == 32);
5226 NumberInfo::Type result_type = NumberInfo::kUnknown;
5225 switch (op) { 5227 switch (op) {
5226 case Token::COMMA: 5228 case Token::COMMA:
5227 info = right.number_info(); 5229 result_type = right.number_info();
5228 break; 5230 break;
5229 case Token::OR: 5231 case Token::OR:
5230 case Token::AND: 5232 case Token::AND:
5231 // Could be anything. Check inputs. 5233 // Result type can be either of the two input types.
5232 if (only_numbers) 5234 result_type = operands_type;
5233 info = NumberInfo::kNumber;
5234 break; 5235 break;
5235 case Token::BIT_OR: 5236 case Token::BIT_OR:
5236 case Token::BIT_XOR: 5237 case Token::BIT_XOR:
5237 case Token::BIT_AND: 5238 case Token::BIT_AND:
5239 // Result is always a smi.
5240 result_type = NumberInfo::kSmi;
5241 break;
5238 case Token::SAR: 5242 case Token::SAR:
5243 case Token::SHL:
5244 // Result is always a smi.
5245 result_type = NumberInfo::kSmi;
5246 break;
5239 case Token::SHR: 5247 case Token::SHR:
5240 // TODO(fsc): Make use of the fact that smis are 32 bits on x64. 5248 // Result of x >>> y is always a smi if y >= 1, otherwise a number.
5241 info = only_smis ? NumberInfo::kSmi : NumberInfo::kNumber; 5249 result_type = (right.is_constant() && right.handle()->IsSmi()
5242 break; 5250 && Smi::cast(*right.handle())->value() >= 1)
5243 case Token::SHL: 5251 ? NumberInfo::kSmi
5244 info = NumberInfo::kNumber; 5252 : NumberInfo::kNumber;
5245 break; 5253 break;
5246 case Token::ADD: 5254 case Token::ADD:
5247 // Could be strings or numbers. Check types of inputs. 5255 // Result could be a string or a number. Check types of inputs.
5248 if (only_numbers) { 5256 result_type = NumberInfo::IsNumber(operands_type)
5249 info = NumberInfo::kNumber; 5257 ? NumberInfo::kNumber
5250 } 5258 : NumberInfo::kUnknown;
5251 break; 5259 break;
5252 case Token::SUB: 5260 case Token::SUB:
5253 case Token::MUL: 5261 case Token::MUL:
5254 case Token::DIV: 5262 case Token::DIV:
5255 case Token::MOD: 5263 case Token::MOD:
5256 info = NumberInfo::kNumber; 5264 // Result is always a number.
5265 result_type = NumberInfo::kNumber;
5257 break; 5266 break;
5258 default: 5267 default:
5259 UNREACHABLE(); 5268 UNREACHABLE();
5260 } 5269 }
5261 answer.set_number_info(info); 5270 answer.set_number_info(result_type);
5262 frame_->Push(&answer); 5271 frame_->Push(&answer);
5263 } 5272 }
5264 5273
5265 5274
5266 // Emit a LoadIC call to get the value from receiver and leave it in 5275 // Emit a LoadIC call to get the value from receiver and leave it in
5267 // dst. The receiver register is restored after the call. 5276 // dst. The receiver register is restored after the call.
5268 class DeferredReferenceGetNamedValue: public DeferredCode { 5277 class DeferredReferenceGetNamedValue: public DeferredCode {
5269 public: 5278 public:
5270 DeferredReferenceGetNamedValue(Register dst, 5279 DeferredReferenceGetNamedValue(Register dst,
5271 Register receiver, 5280 Register receiver,
(...skipping 2875 matching lines...) Expand 10 before | Expand all | Expand 10 after
8147 } 8156 }
8148 8157
8149 OS::SNPrintF(Vector<char>(name_, len), 8158 OS::SNPrintF(Vector<char>(name_, len),
8150 "GenericBinaryOpStub_%s_%s%s_%s%s_%s%s", 8159 "GenericBinaryOpStub_%s_%s%s_%s%s_%s%s",
8151 op_name, 8160 op_name,
8152 overwrite_name, 8161 overwrite_name,
8153 (flags_ & NO_SMI_CODE_IN_STUB) ? "_NoSmiInStub" : "", 8162 (flags_ & NO_SMI_CODE_IN_STUB) ? "_NoSmiInStub" : "",
8154 args_in_registers_ ? "RegArgs" : "StackArgs", 8163 args_in_registers_ ? "RegArgs" : "StackArgs",
8155 args_reversed_ ? "_R" : "", 8164 args_reversed_ ? "_R" : "",
8156 use_sse3_ ? "SSE3" : "SSE2", 8165 use_sse3_ ? "SSE3" : "SSE2",
8157 only_numbers_in_stub_ ? "_OnlyNumbers" : ""); 8166 NumberInfo::ToString(operands_type_));
8158 return name_; 8167 return name_;
8159 } 8168 }
8160 8169
8161 8170
8162 void GenericBinaryOpStub::GenerateCall( 8171 void GenericBinaryOpStub::GenerateCall(
8163 MacroAssembler* masm, 8172 MacroAssembler* masm,
8164 Register left, 8173 Register left,
8165 Register right) { 8174 Register right) {
8166 if (!ArgsInRegistersSupported()) { 8175 if (!ArgsInRegistersSupported()) {
8167 // Pass arguments on the stack. 8176 // Pass arguments on the stack.
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
8471 GenerateLoadArguments(masm); 8480 GenerateLoadArguments(masm);
8472 } 8481 }
8473 // Floating point case. 8482 // Floating point case.
8474 switch (op_) { 8483 switch (op_) {
8475 case Token::ADD: 8484 case Token::ADD:
8476 case Token::SUB: 8485 case Token::SUB:
8477 case Token::MUL: 8486 case Token::MUL:
8478 case Token::DIV: { 8487 case Token::DIV: {
8479 // rax: y 8488 // rax: y
8480 // rdx: x 8489 // rdx: x
8481 if (only_numbers_in_stub_) { 8490 if (NumberInfo::IsNumber(operands_type_)) {
8482 if (FLAG_debug_code) { 8491 if (FLAG_debug_code) {
8483 // Assert at runtime that inputs are only numbers. 8492 // Assert at runtime that inputs are only numbers.
8484 __ AbortIfNotNumber(rdx, "GenericBinaryOpStub operand not a number."); 8493 __ AbortIfNotNumber(rdx, "GenericBinaryOpStub operand not a number.");
8485 __ AbortIfNotNumber(rax, "GenericBinaryOpStub operand not a number."); 8494 __ AbortIfNotNumber(rax, "GenericBinaryOpStub operand not a number.");
8486 } 8495 }
8487 } else { 8496 } else {
8488 FloatingPointHelper::CheckNumberOperands(masm, &call_runtime); 8497 FloatingPointHelper::CheckNumberOperands(masm, &call_runtime);
8489 } 8498 }
8490 // Fast-case: Both operands are numbers. 8499 // Fast-case: Both operands are numbers.
8491 // xmm4 and xmm5 are volatile XMM registers. 8500 // xmm4 and xmm5 are volatile XMM registers.
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after
9375 // Call the function from C++. 9384 // Call the function from C++.
9376 return FUNCTION_CAST<ModuloFunction>(buffer); 9385 return FUNCTION_CAST<ModuloFunction>(buffer);
9377 } 9386 }
9378 9387
9379 #endif 9388 #endif
9380 9389
9381 9390
9382 #undef __ 9391 #undef __
9383 9392
9384 } } // namespace v8::internal 9393 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698