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

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

Issue 509007: Optimize implementation of Math.floor a little by special casing... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years 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 | « no previous file | src/jump-target.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 5979 matching lines...) Expand 10 before | Expand all | Expand 10 after
5990 5990
5991 5991
5992 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 5992 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
5993 frame_->PushFunction(); 5993 frame_->PushFunction();
5994 } 5994 }
5995 5995
5996 5996
5997 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { 5997 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
5998 Comment cmnt(masm_, "[ CompareOperation"); 5998 Comment cmnt(masm_, "[ CompareOperation");
5999 5999
6000 bool left_already_loaded = false;
6001
6000 // Get the expressions from the node. 6002 // Get the expressions from the node.
6001 Expression* left = node->left(); 6003 Expression* left = node->left();
6002 Expression* right = node->right(); 6004 Expression* right = node->right();
6003 Token::Value op = node->op(); 6005 Token::Value op = node->op();
6004 // To make typeof testing for natives implemented in JavaScript really 6006 // To make typeof testing for natives implemented in JavaScript really
6005 // efficient, we generate special code for expressions of the form: 6007 // efficient, we generate special code for expressions of the form:
6006 // 'typeof <expression> == <string>'. 6008 // 'typeof <expression> == <string>'.
6007 UnaryOperation* operation = left->AsUnaryOperation(); 6009 UnaryOperation* operation = left->AsUnaryOperation();
6008 if ((op == Token::EQ || op == Token::EQ_STRICT) && 6010 if ((op == Token::EQ || op == Token::EQ_STRICT) &&
6009 (operation != NULL && operation->op() == Token::TYPEOF) && 6011 (operation != NULL && operation->op() == Token::TYPEOF) &&
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
6070 } else if (check->Equals(Heap::function_symbol())) { 6072 } else if (check->Equals(Heap::function_symbol())) {
6071 __ test(answer.reg(), Immediate(kSmiTagMask)); 6073 __ test(answer.reg(), Immediate(kSmiTagMask));
6072 destination()->false_target()->Branch(zero); 6074 destination()->false_target()->Branch(zero);
6073 frame_->Spill(answer.reg()); 6075 frame_->Spill(answer.reg());
6074 __ CmpObjectType(answer.reg(), JS_FUNCTION_TYPE, answer.reg()); 6076 __ CmpObjectType(answer.reg(), JS_FUNCTION_TYPE, answer.reg());
6075 destination()->true_target()->Branch(equal); 6077 destination()->true_target()->Branch(equal);
6076 // Regular expressions are callable so typeof == 'function'. 6078 // Regular expressions are callable so typeof == 'function'.
6077 __ CmpInstanceType(answer.reg(), JS_REGEXP_TYPE); 6079 __ CmpInstanceType(answer.reg(), JS_REGEXP_TYPE);
6078 answer.Unuse(); 6080 answer.Unuse();
6079 destination()->Split(equal); 6081 destination()->Split(equal);
6080
6081 } else if (check->Equals(Heap::object_symbol())) { 6082 } else if (check->Equals(Heap::object_symbol())) {
6082 __ test(answer.reg(), Immediate(kSmiTagMask)); 6083 __ test(answer.reg(), Immediate(kSmiTagMask));
6083 destination()->false_target()->Branch(zero); 6084 destination()->false_target()->Branch(zero);
6084 __ cmp(answer.reg(), Factory::null_value()); 6085 __ cmp(answer.reg(), Factory::null_value());
6085 destination()->true_target()->Branch(equal); 6086 destination()->true_target()->Branch(equal);
6086 6087
6087 Result map = allocator()->Allocate(); 6088 Result map = allocator()->Allocate();
6088 ASSERT(map.is_valid()); 6089 ASSERT(map.is_valid());
6089 // Regular expressions are typeof == 'function', not 'object'. 6090 // Regular expressions are typeof == 'function', not 'object'.
6090 __ CmpObjectType(answer.reg(), JS_REGEXP_TYPE, map.reg()); 6091 __ CmpObjectType(answer.reg(), JS_REGEXP_TYPE, map.reg());
(...skipping 11 matching lines...) Expand all
6102 answer.Unuse(); 6103 answer.Unuse();
6103 map.Unuse(); 6104 map.Unuse();
6104 destination()->Split(less_equal); 6105 destination()->Split(less_equal);
6105 } else { 6106 } else {
6106 // Uncommon case: typeof testing against a string literal that is 6107 // Uncommon case: typeof testing against a string literal that is
6107 // never returned from the typeof operator. 6108 // never returned from the typeof operator.
6108 answer.Unuse(); 6109 answer.Unuse();
6109 destination()->Goto(false); 6110 destination()->Goto(false);
6110 } 6111 }
6111 return; 6112 return;
6113 } else if (op == Token::LT &&
6114 right->AsLiteral() != NULL &&
6115 right->AsLiteral()->handle()->IsHeapNumber()) {
6116 Handle<HeapNumber> check(HeapNumber::cast(*right->AsLiteral()->handle()));
6117 if (check->value() == 2147483648.0) { // 0x80000000.
6118 Load(left);
6119 left_already_loaded = true;
6120 Result lhs = frame_->Pop();
6121 lhs.ToRegister();
6122 __ test(lhs.reg(), Immediate(kSmiTagMask));
6123 destination()->true_target()->Branch(zero); // All Smis are less.
6124 Result scratch = allocator()->Allocate();
6125 ASSERT(scratch.is_valid());
6126 __ mov(scratch.reg(), FieldOperand(lhs.reg(), HeapObject::kMapOffset));
6127 __ cmp(scratch.reg(), Factory::heap_number_map());
6128 JumpTarget not_a_number;
6129 not_a_number.Branch(not_equal, &lhs);
6130 __ mov(scratch.reg(), FieldOperand(lhs.reg(), HeapNumber::kExponentOffset) );
Søren Thygesen Gjesse 2009/12/21 14:59:39 Line longer than 80 chars.
6131 __ cmp(Operand(scratch.reg()), Immediate(0xfff00000));
6132 not_a_number.Branch(above_equal, &lhs); // It's a negative NaN or -Infini ty.
Søren Thygesen Gjesse 2009/12/21 14:59:39 Ditto.
6133 const uint32_t borderline_exponent =
6134 (HeapNumber::kExponentBias + 31) << HeapNumber::kExponentShift;
6135 __ cmp(Operand(scratch.reg()), Immediate(borderline_exponent));
6136 scratch.Unuse();
6137 lhs.Unuse();
6138 destination()->true_target()->Branch(less);
6139 destination()->false_target()->Jump();
6140
6141 not_a_number.Bind(&lhs);
6142 frame_->Push(&lhs);
6143 }
6112 } 6144 }
6113 6145
6114 Condition cc = no_condition; 6146 Condition cc = no_condition;
6115 bool strict = false; 6147 bool strict = false;
6116 switch (op) { 6148 switch (op) {
6117 case Token::EQ_STRICT: 6149 case Token::EQ_STRICT:
6118 strict = true; 6150 strict = true;
6119 // Fall through 6151 // Fall through
6120 case Token::EQ: 6152 case Token::EQ:
6121 cc = equal; 6153 cc = equal;
6122 break; 6154 break;
6123 case Token::LT: 6155 case Token::LT:
6124 cc = less; 6156 cc = less;
6125 break; 6157 break;
6126 case Token::GT: 6158 case Token::GT:
6127 cc = greater; 6159 cc = greater;
6128 break; 6160 break;
6129 case Token::LTE: 6161 case Token::LTE:
6130 cc = less_equal; 6162 cc = less_equal;
6131 break; 6163 break;
6132 case Token::GTE: 6164 case Token::GTE:
6133 cc = greater_equal; 6165 cc = greater_equal;
6134 break; 6166 break;
6135 case Token::IN: { 6167 case Token::IN: {
6136 Load(left); 6168 if (!left_already_loaded) Load(left);
6137 Load(right); 6169 Load(right);
6138 Result answer = frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2); 6170 Result answer = frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2);
6139 frame_->Push(&answer); // push the result 6171 frame_->Push(&answer); // push the result
6140 return; 6172 return;
6141 } 6173 }
6142 case Token::INSTANCEOF: { 6174 case Token::INSTANCEOF: {
6143 Load(left); 6175 if (!left_already_loaded) Load(left);
6144 Load(right); 6176 Load(right);
6145 InstanceofStub stub; 6177 InstanceofStub stub;
6146 Result answer = frame_->CallStub(&stub, 2); 6178 Result answer = frame_->CallStub(&stub, 2);
6147 answer.ToRegister(); 6179 answer.ToRegister();
6148 __ test(answer.reg(), Operand(answer.reg())); 6180 __ test(answer.reg(), Operand(answer.reg()));
6149 answer.Unuse(); 6181 answer.Unuse();
6150 destination()->Split(zero); 6182 destination()->Split(zero);
6151 return; 6183 return;
6152 } 6184 }
6153 default: 6185 default:
6154 UNREACHABLE(); 6186 UNREACHABLE();
6155 } 6187 }
6156 Load(left); 6188 if (!left_already_loaded) Load(left);
6157 Load(right); 6189 Load(right);
6158 Comparison(node, cc, strict, destination()); 6190 Comparison(node, cc, strict, destination());
6159 } 6191 }
6160 6192
6161 6193
6162 #ifdef DEBUG 6194 #ifdef DEBUG
6163 bool CodeGenerator::HasValidEntryRegisters() { 6195 bool CodeGenerator::HasValidEntryRegisters() {
6164 return (allocator()->count(eax) == (frame()->is_used(eax) ? 1 : 0)) 6196 return (allocator()->count(eax) == (frame()->is_used(eax) ? 1 : 0))
6165 && (allocator()->count(ebx) == (frame()->is_used(ebx) ? 1 : 0)) 6197 && (allocator()->count(ebx) == (frame()->is_used(ebx) ? 1 : 0))
6166 && (allocator()->count(ecx) == (frame()->is_used(ecx) ? 1 : 0)) 6198 && (allocator()->count(ecx) == (frame()->is_used(ecx) ? 1 : 0))
(...skipping 2792 matching lines...) Expand 10 before | Expand all | Expand 10 after
8959 __ add(Operand(dest), Immediate(2)); 8991 __ add(Operand(dest), Immediate(2));
8960 } 8992 }
8961 __ sub(Operand(count), Immediate(1)); 8993 __ sub(Operand(count), Immediate(1));
8962 __ j(not_zero, &loop); 8994 __ j(not_zero, &loop);
8963 } 8995 }
8964 8996
8965 8997
8966 #undef __ 8998 #undef __
8967 8999
8968 } } // namespace v8::internal 9000 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/jump-target.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698