Chromium Code Reviews| 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 right_side = frame_->Pop(); |
|
Kevin Millikin (Chromium)
2008/12/29 09:05:38
I'm confused by this: the rhs is normally on top o
William Hesse
2008/12/29 11:47:42
True. Left and right were consistently flipped th
| |
| 1192 frame_->EmitPop(eax); | 1194 left_side = frame_->Pop(); |
| 1193 } else { | 1195 } else { |
| 1194 frame_->EmitPop(eax); | 1196 left_side = frame_->Pop(); |
| 1195 frame_->EmitPop(edx); | 1197 right_side = frame_->Pop(); |
| 1196 } | 1198 } |
| 1199 right_side.ToRegister(); | |
| 1200 left_side.ToRegister(); | |
| 1201 ASSERT(right_side.is_valid()); | |
| 1202 ASSERT(left_side.is_valid()); | |
| 1203 // Check for the smi case. | |
| 1204 JumpTarget is_not_smi(this); | |
| 1205 JumpTarget done(this); | |
| 1206 Result temp = allocator_->Allocate(); | |
| 1207 ASSERT(temp.is_valid()); | |
| 1208 __ mov(temp.reg(), right_side.reg()); | |
| 1209 __ or_(temp.reg(), Operand(left_side.reg())); | |
| 1210 __ test(temp.reg(), Immediate(kSmiTagMask)); | |
| 1211 temp.Unuse(); | |
| 1212 is_not_smi.Branch(not_zero, &left_side, &right_side, not_taken); | |
| 1213 __ cmp(right_side.reg(), Operand(left_side.reg())); | |
|
Kevin Millikin (Chromium)
2008/12/29 09:05:38
Here is where the variable naming/popping order co
William Hesse
2008/12/29 11:47:42
Done.
| |
| 1214 // Fall through to |done|. | |
|
Kevin Millikin (Chromium)
2008/12/29 09:05:38
Did we need to change the order we emit the smi an
William Hesse
2008/12/29 11:47:42
Changed back, so there is not an unconditional jum
| |
| 1215 left_side.Unuse(); | |
| 1216 right_side.Unuse(); | |
| 1217 done.Jump(); | |
| 1197 | 1218 |
| 1198 // Check for the smi case. | 1219 is_not_smi.Bind(&left_side, &right_side); |
| 1199 JumpTarget is_smi(this); | |
| 1200 JumpTarget done(this); | |
| 1201 __ mov(ecx, Operand(eax)); | |
| 1202 __ or_(ecx, Operand(edx)); | |
| 1203 __ test(ecx, Immediate(kSmiTagMask)); | |
| 1204 is_smi.Branch(zero, taken); | |
| 1205 | |
| 1206 // When non-smi, call out to the compare stub. "parameters" setup by | 1220 // 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. | 1221 // calling code in edx and eax and "result" is returned in the flags. |
| 1222 | |
|
Kevin Millikin (Chromium)
2008/12/29 09:05:38
Remove the extra blank line.
William Hesse
2008/12/29 11:47:42
Done.
| |
| 1223 if (!right_side.reg().is(eax)) { | |
| 1224 left_side.ToRegister(eax); | |
| 1225 right_side.ToRegister(edx); | |
| 1226 } else if (!left_side.reg().is(edx)) { | |
| 1227 right_side.ToRegister(edx); | |
| 1228 left_side.ToRegister(eax); | |
| 1229 } else { | |
| 1230 frame_->Spill(eax); // Can be multiply referenced, even now. | |
| 1231 frame_->Spill(edx); | |
| 1232 __ xchg(eax, edx); | |
| 1233 // If right_side and left_side become real (non-dummy) arguments | |
| 1234 // to CallStub, they need to be swapped in this case. | |
| 1235 } | |
| 1208 CompareStub stub(cc, strict); | 1236 CompareStub stub(cc, strict); |
| 1209 frame_->CallStub(&stub, 0); | 1237 Result answer = frame_->CallStub(&stub, &left_side, &right_side, 0); |
| 1210 if (cc == equal) { | 1238 if (cc == equal) { |
| 1211 __ test(eax, Operand(eax)); | 1239 __ test(answer.reg(), Operand(answer.reg())); |
| 1212 } else { | 1240 } else { |
| 1213 __ cmp(eax, 0); | 1241 __ cmp(answer.reg(), 0); |
| 1214 } | 1242 } |
| 1215 done.Jump(); | 1243 answer.Unuse(); |
| 1216 | |
| 1217 // Test smi equality by pointer comparison. | |
| 1218 is_smi.Bind(); | |
| 1219 __ cmp(edx, Operand(eax)); | |
| 1220 // Fall through to |done|. | |
| 1221 | |
| 1222 done.Bind(); | 1244 done.Bind(); |
| 1223 cc_reg_ = cc; | 1245 cc_reg_ = cc; |
| 1224 } | 1246 } |
| 1225 | 1247 |
| 1226 | 1248 |
| 1227 class DeferredSmiComparison: public DeferredCode { | 1249 class DeferredSmiComparison: public DeferredCode { |
| 1228 public: | 1250 public: |
| 1229 DeferredSmiComparison(CodeGenerator* generator, | 1251 DeferredSmiComparison(CodeGenerator* generator, |
| 1230 Condition cc, | 1252 Condition cc, |
| 1231 bool strict, | 1253 bool strict, |
| (...skipping 2934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4166 case Token::GT: | 4188 case Token::GT: |
| 4167 cc = greater; | 4189 cc = greater; |
| 4168 break; | 4190 break; |
| 4169 case Token::LTE: | 4191 case Token::LTE: |
| 4170 cc = less_equal; | 4192 cc = less_equal; |
| 4171 break; | 4193 break; |
| 4172 case Token::GTE: | 4194 case Token::GTE: |
| 4173 cc = greater_equal; | 4195 cc = greater_equal; |
| 4174 break; | 4196 break; |
| 4175 case Token::IN: { | 4197 case Token::IN: { |
| 4176 VirtualFrame::SpilledScope spilled_scope(this); | 4198 Load(left); |
| 4177 LoadAndSpill(left); | 4199 Load(right); |
| 4178 LoadAndSpill(right); | |
| 4179 frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2); | 4200 frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2); |
| 4180 frame_->EmitPush(eax); // push the result | 4201 frame_->Push(eax); // push the result |
|
Kevin Millikin (Chromium)
2008/12/29 09:05:38
Get rid of this explicit (and non-counted) referen
William Hesse
2008/12/29 11:47:42
I would like to make this a separate change, to be
| |
| 4181 return; | 4202 return; |
| 4182 } | 4203 } |
| 4183 case Token::INSTANCEOF: { | 4204 case Token::INSTANCEOF: { |
| 4184 VirtualFrame::SpilledScope spilled_scope(this); | 4205 Load(left); |
| 4185 LoadAndSpill(left); | 4206 Load(right); |
| 4186 LoadAndSpill(right); | |
| 4187 InstanceofStub stub; | 4207 InstanceofStub stub; |
| 4188 frame_->CallStub(&stub, 2); | 4208 frame_->CallStub(&stub, 2); |
| 4189 __ test(eax, Operand(eax)); | 4209 __ test(eax, Operand(eax)); |
|
Kevin Millikin (Chromium)
2008/12/29 09:05:38
Ditto.
William Hesse
2008/12/29 11:47:42
To be done in separate change.
| |
| 4190 cc_reg_ = zero; | 4210 cc_reg_ = zero; |
| 4191 return; | 4211 return; |
| 4192 } | 4212 } |
| 4193 default: | 4213 default: |
| 4194 UNREACHABLE(); | 4214 UNREACHABLE(); |
| 4195 } | 4215 } |
| 4196 | 4216 |
| 4197 // Optimize for the case where (at least) one of the expressions | 4217 // Optimize for the case where (at least) one of the expressions |
| 4198 // is a literal small integer. | 4218 // is a literal small integer. |
| 4199 if (IsInlineSmi(left->AsLiteral())) { | 4219 if (IsInlineSmi(left->AsLiteral())) { |
| 4200 Load(right); | 4220 Load(right); |
| 4201 SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(), strict); | 4221 SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(), strict); |
| 4202 return; | 4222 return; |
| 4203 } | 4223 } |
| 4204 if (IsInlineSmi(right->AsLiteral())) { | 4224 if (IsInlineSmi(right->AsLiteral())) { |
| 4205 Load(left); | 4225 Load(left); |
| 4206 SmiComparison(cc, right->AsLiteral()->handle(), strict); | 4226 SmiComparison(cc, right->AsLiteral()->handle(), strict); |
| 4207 return; | 4227 return; |
| 4208 } | 4228 } |
| 4209 | 4229 |
| 4210 VirtualFrame::SpilledScope spilled_scope(this); | 4230 Load(left); |
| 4211 LoadAndSpill(left); | 4231 Load(right); |
| 4212 LoadAndSpill(right); | |
| 4213 Comparison(cc, strict); | 4232 Comparison(cc, strict); |
| 4214 } | 4233 } |
| 4215 | 4234 |
| 4216 | 4235 |
| 4217 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { | 4236 bool CodeGenerator::IsActualFunctionReturn(JumpTarget* target) { |
| 4218 return (target == &function_return_ && !function_return_is_shadowed_); | 4237 return (target == &function_return_ && !function_return_is_shadowed_); |
| 4219 } | 4238 } |
| 4220 | 4239 |
| 4221 | 4240 |
| 4222 #ifdef DEBUG | 4241 #ifdef DEBUG |
| (...skipping 1542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5765 | 5784 |
| 5766 // Slow-case: Go through the JavaScript implementation. | 5785 // Slow-case: Go through the JavaScript implementation. |
| 5767 __ bind(&slow); | 5786 __ bind(&slow); |
| 5768 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5787 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
| 5769 } | 5788 } |
| 5770 | 5789 |
| 5771 | 5790 |
| 5772 #undef __ | 5791 #undef __ |
| 5773 | 5792 |
| 5774 } } // namespace v8::internal | 5793 } } // namespace v8::internal |
| OLD | NEW |