| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1178 strict_ ? "true" : "false"); | 1178 strict_ ? "true" : "false"); |
| 1179 } | 1179 } |
| 1180 #endif | 1180 #endif |
| 1181 }; | 1181 }; |
| 1182 | 1182 |
| 1183 | 1183 |
| 1184 void CodeGenerator::Comparison(Condition cc, bool strict) { | 1184 void CodeGenerator::Comparison(Condition cc, bool strict) { |
| 1185 // Strict only makes sense for equality comparisons. | 1185 // Strict only makes sense for equality comparisons. |
| 1186 ASSERT(!strict || cc == equal); | 1186 ASSERT(!strict || cc == equal); |
| 1187 | 1187 |
| 1188 Result left_side(this); |
| 1189 Result right_side(this); |
| 1188 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. | 1190 // Implement '>' and '<=' by reversal to obtain ECMA-262 conversion order. |
| 1189 if (cc == greater || cc == less_equal) { | 1191 if (cc == greater || cc == less_equal) { |
| 1190 cc = ReverseCondition(cc); | 1192 cc = ReverseCondition(cc); |
| 1191 frame_->EmitPop(edx); | 1193 left_side = frame_->Pop(); |
| 1192 frame_->EmitPop(eax); | 1194 right_side = frame_->Pop(); |
| 1193 } else { | 1195 } else { |
| 1194 frame_->EmitPop(eax); | 1196 right_side = frame_->Pop(); |
| 1195 frame_->EmitPop(edx); | 1197 left_side = frame_->Pop(); |
| 1196 } | 1198 } |
| 1197 | 1199 left_side.ToRegister(); |
| 1200 right_side.ToRegister(); |
| 1201 ASSERT(left_side.is_valid()); |
| 1202 ASSERT(right_side.is_valid()); |
| 1198 // Check for the smi case. | 1203 // Check for the smi case. |
| 1199 JumpTarget is_smi(this); | 1204 JumpTarget is_smi(this); |
| 1200 JumpTarget done(this); | 1205 JumpTarget done(this); |
| 1201 __ mov(ecx, Operand(eax)); | 1206 Result temp = allocator_->Allocate(); |
| 1202 __ or_(ecx, Operand(edx)); | 1207 ASSERT(temp.is_valid()); |
| 1203 __ test(ecx, Immediate(kSmiTagMask)); | 1208 __ mov(temp.reg(), left_side.reg()); |
| 1204 is_smi.Branch(zero, taken); | 1209 __ or_(temp.reg(), Operand(right_side.reg())); |
| 1210 __ test(temp.reg(), Immediate(kSmiTagMask)); |
| 1211 temp.Unuse(); |
| 1212 is_smi.Branch(zero, &left_side, &right_side, taken); |
| 1205 | 1213 |
| 1206 // When non-smi, call out to the compare stub. "parameters" setup by | 1214 // When non-smi, call out to the compare stub. "parameters" setup by |
| 1207 // calling code in edx and eax and "result" is returned in the flags. | 1215 // calling code in edx and eax and "result" is returned in the flags. |
| 1216 if (!left_side.reg().is(eax)) { |
| 1217 right_side.ToRegister(eax); |
| 1218 left_side.ToRegister(edx); |
| 1219 } else if (!right_side.reg().is(edx)) { |
| 1220 left_side.ToRegister(edx); |
| 1221 right_side.ToRegister(eax); |
| 1222 } else { |
| 1223 frame_->Spill(eax); // Can be multiply referenced, even now. |
| 1224 frame_->Spill(edx); |
| 1225 __ xchg(eax, edx); |
| 1226 // If left_side and right_side become real (non-dummy) arguments |
| 1227 // to CallStub, they need to be swapped in this case. |
| 1228 } |
| 1208 CompareStub stub(cc, strict); | 1229 CompareStub stub(cc, strict); |
| 1209 frame_->CallStub(&stub, 0); | 1230 Result answer = frame_->CallStub(&stub, &right_side, &left_side, 0); |
| 1210 if (cc == equal) { | 1231 if (cc == equal) { |
| 1211 __ test(eax, Operand(eax)); | 1232 __ test(answer.reg(), Operand(answer.reg())); |
| 1212 } else { | 1233 } else { |
| 1213 __ cmp(eax, 0); | 1234 __ cmp(answer.reg(), 0); |
| 1214 } | 1235 } |
| 1236 answer.Unuse(); |
| 1237 // The expected frame at JumpTarget "done" is bound to the current frame. |
| 1238 // This current frame is spilled, due to the call to CallStub. |
| 1239 // It would be better if the fast SMI case controlled the expected frame. |
| 1215 done.Jump(); | 1240 done.Jump(); |
| 1216 | 1241 |
| 1217 // Test smi equality by pointer comparison. | 1242 is_smi.Bind(&left_side, &right_side); |
| 1218 is_smi.Bind(); | 1243 __ cmp(left_side.reg(), Operand(right_side.reg())); |
| 1219 __ cmp(edx, Operand(eax)); | 1244 right_side.Unuse(); |
| 1245 left_side.Unuse(); |
| 1220 // Fall through to |done|. | 1246 // Fall through to |done|. |
| 1221 | 1247 |
| 1222 done.Bind(); | 1248 done.Bind(); |
| 1223 cc_reg_ = cc; | 1249 cc_reg_ = cc; |
| 1224 } | 1250 } |
| 1225 | 1251 |
| 1226 | 1252 |
| 1227 class DeferredSmiComparison: public DeferredCode { | 1253 class DeferredSmiComparison: public DeferredCode { |
| 1228 public: | 1254 public: |
| 1229 DeferredSmiComparison(CodeGenerator* generator, | 1255 DeferredSmiComparison(CodeGenerator* generator, |
| (...skipping 2935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4165 case Token::GT: | 4191 case Token::GT: |
| 4166 cc = greater; | 4192 cc = greater; |
| 4167 break; | 4193 break; |
| 4168 case Token::LTE: | 4194 case Token::LTE: |
| 4169 cc = less_equal; | 4195 cc = less_equal; |
| 4170 break; | 4196 break; |
| 4171 case Token::GTE: | 4197 case Token::GTE: |
| 4172 cc = greater_equal; | 4198 cc = greater_equal; |
| 4173 break; | 4199 break; |
| 4174 case Token::IN: { | 4200 case Token::IN: { |
| 4175 VirtualFrame::SpilledScope spilled_scope(this); | 4201 Load(left); |
| 4176 LoadAndSpill(left); | 4202 Load(right); |
| 4177 LoadAndSpill(right); | |
| 4178 frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2); | 4203 frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2); |
| 4179 frame_->EmitPush(eax); // push the result | 4204 frame_->Push(eax); // push the result |
| 4180 return; | 4205 return; |
| 4181 } | 4206 } |
| 4182 case Token::INSTANCEOF: { | 4207 case Token::INSTANCEOF: { |
| 4183 VirtualFrame::SpilledScope spilled_scope(this); | 4208 Load(left); |
| 4184 LoadAndSpill(left); | 4209 Load(right); |
| 4185 LoadAndSpill(right); | |
| 4186 InstanceofStub stub; | 4210 InstanceofStub stub; |
| 4187 frame_->CallStub(&stub, 2); | 4211 frame_->CallStub(&stub, 2); |
| 4188 __ test(eax, Operand(eax)); | 4212 __ test(eax, Operand(eax)); |
| 4189 cc_reg_ = zero; | 4213 cc_reg_ = zero; |
| 4190 return; | 4214 return; |
| 4191 } | 4215 } |
| 4192 default: | 4216 default: |
| 4193 UNREACHABLE(); | 4217 UNREACHABLE(); |
| 4194 } | 4218 } |
| 4195 | 4219 |
| 4196 // Optimize for the case where (at least) one of the expressions | 4220 // Optimize for the case where (at least) one of the expressions |
| 4197 // is a literal small integer. | 4221 // is a literal small integer. |
| 4198 if (IsInlineSmi(left->AsLiteral())) { | 4222 if (IsInlineSmi(left->AsLiteral())) { |
| 4199 Load(right); | 4223 Load(right); |
| 4200 SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(), strict); | 4224 SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(), strict); |
| 4201 return; | 4225 return; |
| 4202 } | 4226 } |
| 4203 if (IsInlineSmi(right->AsLiteral())) { | 4227 if (IsInlineSmi(right->AsLiteral())) { |
| 4204 Load(left); | 4228 Load(left); |
| 4205 SmiComparison(cc, right->AsLiteral()->handle(), strict); | 4229 SmiComparison(cc, right->AsLiteral()->handle(), strict); |
| 4206 return; | 4230 return; |
| 4207 } | 4231 } |
| 4208 | 4232 |
| 4209 VirtualFrame::SpilledScope spilled_scope(this); | 4233 Load(left); |
| 4210 LoadAndSpill(left); | 4234 Load(right); |
| 4211 LoadAndSpill(right); | |
| 4212 Comparison(cc, strict); | 4235 Comparison(cc, strict); |
| 4213 } | 4236 } |
| 4214 | 4237 |
| 4215 | 4238 |
| 4216 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { | 4239 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { |
| 4217 return (target == &function_return_ && !function_return_is_shadowed_); | 4240 return (target == &function_return_ && !function_return_is_shadowed_); |
| 4218 } | 4241 } |
| 4219 | 4242 |
| 4220 | 4243 |
| 4221 #ifdef DEBUG | 4244 #ifdef DEBUG |
| (...skipping 1542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5764 | 5787 |
| 5765 // Slow-case: Go through the JavaScript implementation. | 5788 // Slow-case: Go through the JavaScript implementation. |
| 5766 __ bind(&slow); | 5789 __ bind(&slow); |
| 5767 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5790 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 5768 } | 5791 } |
| 5769 | 5792 |
| 5770 | 5793 |
| 5771 #undef __ | 5794 #undef __ |
| 5772 | 5795 |
| 5773 } } // namespace v8::internal | 5796 } } // namespace v8::internal |
| OLD | NEW |