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

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

Issue 16450: Use unspilled virtual frames when compiling compare operations.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 11 years, 12 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
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698