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

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

Issue 13665: Allow non-spilled frames into VisitCompareOperation, and allow them... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 12 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/virtual-frame-ia32.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-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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 } 396 }
397 397
398 398
399 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) { 399 void CodeGenerator::Load(Expression* x, TypeofState typeof_state) {
400 JumpTarget true_target(this); 400 JumpTarget true_target(this);
401 JumpTarget false_target(this); 401 JumpTarget false_target(this);
402 LoadCondition(x, typeof_state, &true_target, &false_target, false); 402 LoadCondition(x, typeof_state, &true_target, &false_target, false);
403 403
404 if (has_cc()) { 404 if (has_cc()) {
405 ASSERT(frame_ != NULL); 405 ASSERT(frame_ != NULL);
406 frame_->SpillAll();
406 // Convert cc_reg_ into a boolean value. 407 // Convert cc_reg_ into a boolean value.
407 JumpTarget loaded(this); 408 JumpTarget loaded(this);
408 JumpTarget materialize_true(this); 409 JumpTarget materialize_true(this);
409 materialize_true.Branch(cc_reg_); 410 materialize_true.Branch(cc_reg_);
410 frame_->EmitPush(Immediate(Factory::false_value())); 411 frame_->EmitPush(Immediate(Factory::false_value()));
411 loaded.Jump(); 412 loaded.Jump();
412 materialize_true.Bind(); 413 materialize_true.Bind();
413 frame_->EmitPush(Immediate(Factory::true_value())); 414 frame_->EmitPush(Immediate(Factory::true_value()));
414 loaded.Bind(); 415 loaded.Bind();
415 cc_reg_ = no_condition; 416 cc_reg_ = no_condition;
416 } 417 }
417 418
418 if (true_target.is_linked() || false_target.is_linked()) { 419 if (true_target.is_linked() || false_target.is_linked()) {
419 // We have at least one condition value that has been "translated" into 420 // We have at least one condition value that has been "translated" into
420 // a branch, thus it needs to be loaded explicitly. 421 // a branch, thus it needs to be loaded explicitly.
421 JumpTarget loaded(this); 422 JumpTarget loaded(this);
422 if (frame_ != NULL) { 423 if (frame_ != NULL) {
423 loaded.Jump(); // Don't lose the current TOS. 424 loaded.Jump(); // Don't lose the current TOS.
424 } 425 }
425 bool both = true_target.is_linked() && false_target.is_linked(); 426 bool both = true_target.is_linked() && false_target.is_linked();
426 // Load "true" if necessary. 427 // Load "true" if necessary.
427 if (true_target.is_linked()) { 428 if (true_target.is_linked()) {
428 true_target.Bind(); 429 true_target.Bind();
430 frame_->SpillAll();
429 frame_->EmitPush(Immediate(Factory::true_value())); 431 frame_->EmitPush(Immediate(Factory::true_value()));
430 } 432 }
431 // If both "true" and "false" need to be reincarnated jump across the 433 // If both "true" and "false" need to be reincarnated jump across the
432 // code for "false". 434 // code for "false".
433 if (both) { 435 if (both) {
434 loaded.Jump(); 436 loaded.Jump();
435 } 437 }
436 // Load "false" if necessary. 438 // Load "false" if necessary.
437 if (false_target.is_linked()) { 439 if (false_target.is_linked()) {
438 false_target.Bind(); 440 false_target.Bind();
441 frame_->SpillAll();
439 frame_->EmitPush(Immediate(Factory::false_value())); 442 frame_->EmitPush(Immediate(Factory::false_value()));
440 } 443 }
441 // A value is loaded on all paths reaching this point. 444 // A value is loaded on all paths reaching this point.
442 loaded.Bind(); 445 loaded.Bind();
443 } 446 }
444 ASSERT(frame_ != NULL); 447 ASSERT(frame_ != NULL);
445 ASSERT(!has_cc()); 448 ASSERT(!has_cc());
446 } 449 }
447 450
448 451
(...skipping 729 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 done.Bind(); 1181 done.Bind();
1179 cc_reg_ = cc; 1182 cc_reg_ = cc;
1180 } 1183 }
1181 1184
1182 1185
1183 class SmiComparisonDeferred: public DeferredCode { 1186 class SmiComparisonDeferred: public DeferredCode {
1184 public: 1187 public:
1185 SmiComparisonDeferred(CodeGenerator* generator, 1188 SmiComparisonDeferred(CodeGenerator* generator,
1186 Condition cc, 1189 Condition cc,
1187 bool strict, 1190 bool strict,
1188 int value) 1191 Register left_side,
1189 : DeferredCode(generator), cc_(cc), strict_(strict), value_(value) { 1192 int right_side) :
1193 DeferredCode(generator),
1194 cc_(cc),
1195 strict_(strict),
1196 left_side_(left_side),
1197 right_side_(right_side) {
1190 set_comment("[ ComparisonDeferred"); 1198 set_comment("[ ComparisonDeferred");
1191 } 1199 }
1192 virtual void Generate(); 1200 virtual void Generate();
1193 1201
1194 private: 1202 private:
1195 Condition cc_; 1203 Condition cc_;
1196 bool strict_; 1204 bool strict_;
1197 int value_; 1205 Register left_side_;
1206 int right_side_;
1198 }; 1207 };
1199 1208
1200 1209
1201 void SmiComparisonDeferred::Generate() { 1210 void SmiComparisonDeferred::Generate() {
1202 CompareStub stub(cc_, strict_); 1211 CompareStub stub(cc_, strict_);
1203 // Setup parameters and call stub. 1212 // Setup parameters and call stub.
1204 __ mov(edx, Operand(eax)); 1213 if (!left_side_.is(edx)) {
1205 __ Set(eax, Immediate(Smi::FromInt(value_))); 1214 __ mov(edx, Operand(left_side_));
1215 }
1216 __ Set(eax, Immediate(Smi::FromInt(right_side_)));
1206 __ CallStub(&stub); 1217 __ CallStub(&stub);
1207 __ cmp(eax, 0); 1218 __ cmp(eax, 0);
1208 // "result" is returned in the flags 1219 // "result" is returned in the flags.
1209 } 1220 }
1210 1221
1211 1222
1212 void CodeGenerator::SmiComparison(Condition cc, 1223 void CodeGenerator::SmiComparison(Condition cc,
1213 Handle<Object> value, 1224 Handle<Object> value,
1214 bool strict) { 1225 bool strict) {
1215 // Strict only makes sense for equality comparisons. 1226 // Strict only makes sense for equality comparisons.
1216 ASSERT(!strict || cc == equal); 1227 ASSERT(!strict || cc == equal);
1217 1228
1218 int int_value = Smi::cast(*value)->value(); 1229 int int_value = Smi::cast(*value)->value();
1219 ASSERT(is_intn(int_value, kMaxSmiInlinedBits)); 1230 ASSERT(is_intn(int_value, kMaxSmiInlinedBits));
1220 1231
1232 Result comparee = frame_->Pop();
1233 comparee.ToRegister();
1234 Register reg = comparee.reg();
1235 __ test(reg, Immediate(kSmiTagMask));
1221 SmiComparisonDeferred* deferred = 1236 SmiComparisonDeferred* deferred =
1222 new SmiComparisonDeferred(this, cc, strict, int_value); 1237 new SmiComparisonDeferred(this, cc, strict, reg, int_value);
1223 frame_->EmitPop(eax);
1224 __ test(eax, Immediate(kSmiTagMask));
1225 deferred->enter()->Branch(not_zero, not_taken); 1238 deferred->enter()->Branch(not_zero, not_taken);
1226 // Test smi equality by pointer comparison. 1239 // Test smi equality and comparison by signed int comparison.
1227 __ cmp(Operand(eax), Immediate(value)); 1240 __ cmp(Operand(reg), Immediate(value));
1241 comparee.Unuse();
1228 deferred->exit()->Bind(); 1242 deferred->exit()->Bind();
1229 cc_reg_ = cc; 1243 cc_reg_ = cc;
1230 } 1244 }
1231 1245
1232 1246
1233 class CallFunctionStub: public CodeStub { 1247 class CallFunctionStub: public CodeStub {
1234 public: 1248 public:
1235 explicit CallFunctionStub(int argc) : argc_(argc) { } 1249 explicit CallFunctionStub(int argc) : argc_(argc) { }
1236 1250
1237 void Generate(MacroAssembler* masm); 1251 void Generate(MacroAssembler* masm);
(...skipping 2741 matching lines...) Expand 10 before | Expand all | Expand 10 after
3979 // literal 'null'. If so, we optimize the code by inlining a null check 3993 // literal 'null'. If so, we optimize the code by inlining a null check
3980 // instead of calling the (very) general runtime routine for checking 3994 // instead of calling the (very) general runtime routine for checking
3981 // equality. 3995 // equality.
3982 if (op == Token::EQ || op == Token::EQ_STRICT) { 3996 if (op == Token::EQ || op == Token::EQ_STRICT) {
3983 bool left_is_null = 3997 bool left_is_null =
3984 left->AsLiteral() != NULL && left->AsLiteral()->IsNull(); 3998 left->AsLiteral() != NULL && left->AsLiteral()->IsNull();
3985 bool right_is_null = 3999 bool right_is_null =
3986 right->AsLiteral() != NULL && right->AsLiteral()->IsNull(); 4000 right->AsLiteral() != NULL && right->AsLiteral()->IsNull();
3987 // The 'null' value can only be equal to 'null' or 'undefined'. 4001 // The 'null' value can only be equal to 'null' or 'undefined'.
3988 if (left_is_null || right_is_null) { 4002 if (left_is_null || right_is_null) {
4003 frame_->SpillAll();
3989 Load(left_is_null ? right : left); 4004 Load(left_is_null ? right : left);
3990 frame_->SpillAll(); 4005 frame_->SpillAll();
3991 frame_->EmitPop(eax); 4006 frame_->EmitPop(eax);
3992 __ cmp(eax, Factory::null_value()); 4007 __ cmp(eax, Factory::null_value());
3993 4008
3994 // The 'null' value is only equal to 'undefined' if using non-strict 4009 // The 'null' value is only equal to 'undefined' if using non-strict
3995 // comparisons. 4010 // comparisons.
3996 if (op != Token::EQ_STRICT) { 4011 if (op != Token::EQ_STRICT) {
3997 true_target()->Branch(equal); 4012 true_target()->Branch(equal);
3998 4013
(...skipping 18 matching lines...) Expand all
4017 // To make typeof testing for natives implemented in JavaScript really 4032 // To make typeof testing for natives implemented in JavaScript really
4018 // efficient, we generate special code for expressions of the form: 4033 // efficient, we generate special code for expressions of the form:
4019 // 'typeof <expression> == <string>'. 4034 // 'typeof <expression> == <string>'.
4020 UnaryOperation* operation = left->AsUnaryOperation(); 4035 UnaryOperation* operation = left->AsUnaryOperation();
4021 if ((op == Token::EQ || op == Token::EQ_STRICT) && 4036 if ((op == Token::EQ || op == Token::EQ_STRICT) &&
4022 (operation != NULL && operation->op() == Token::TYPEOF) && 4037 (operation != NULL && operation->op() == Token::TYPEOF) &&
4023 (right->AsLiteral() != NULL && 4038 (right->AsLiteral() != NULL &&
4024 right->AsLiteral()->handle()->IsString())) { 4039 right->AsLiteral()->handle()->IsString())) {
4025 Handle<String> check(String::cast(*right->AsLiteral()->handle())); 4040 Handle<String> check(String::cast(*right->AsLiteral()->handle()));
4026 4041
4042 frame_->SpillAll();
4027 // Load the operand and move it to register edx. 4043 // Load the operand and move it to register edx.
4028 LoadTypeofExpression(operation->expression()); 4044 LoadTypeofExpression(operation->expression());
4029 frame_->SpillAll(); 4045 frame_->SpillAll();
4030 frame_->EmitPop(edx); 4046 frame_->EmitPop(edx);
4031 4047
4032 if (check->Equals(Heap::number_symbol())) { 4048 if (check->Equals(Heap::number_symbol())) {
4033 __ test(edx, Immediate(kSmiTagMask)); 4049 __ test(edx, Immediate(kSmiTagMask));
4034 true_target()->Branch(zero); 4050 true_target()->Branch(zero);
4035 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset)); 4051 __ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
4036 __ cmp(edx, Factory::heap_number_map()); 4052 __ cmp(edx, Factory::heap_number_map());
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
4126 case Token::GT: 4142 case Token::GT:
4127 cc = greater; 4143 cc = greater;
4128 break; 4144 break;
4129 case Token::LTE: 4145 case Token::LTE:
4130 cc = less_equal; 4146 cc = less_equal;
4131 break; 4147 break;
4132 case Token::GTE: 4148 case Token::GTE:
4133 cc = greater_equal; 4149 cc = greater_equal;
4134 break; 4150 break;
4135 case Token::IN: { 4151 case Token::IN: {
4152 frame_->SpillAll();
4136 Load(left); 4153 Load(left);
4137 frame_->SpillAll(); 4154 frame_->SpillAll();
4138 Load(right); 4155 Load(right);
4139 frame_->SpillAll(); 4156 frame_->SpillAll();
4140 frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2); 4157 frame_->InvokeBuiltin(Builtins::IN, CALL_FUNCTION, 2);
4141 frame_->EmitPush(eax); // push the result 4158 frame_->EmitPush(eax); // push the result
4142 return; 4159 return;
4143 } 4160 }
4144 case Token::INSTANCEOF: { 4161 case Token::INSTANCEOF: {
4162 frame_->SpillAll();
4145 Load(left); 4163 Load(left);
4146 frame_->SpillAll(); 4164 frame_->SpillAll();
4147 Load(right); 4165 Load(right);
4148 frame_->SpillAll(); 4166 frame_->SpillAll();
4149 InstanceofStub stub; 4167 InstanceofStub stub;
4150 frame_->CallStub(&stub, 2); 4168 frame_->CallStub(&stub, 2);
4151 __ test(eax, Operand(eax)); 4169 __ test(eax, Operand(eax));
4152 cc_reg_ = zero; 4170 cc_reg_ = zero;
4153 return; 4171 return;
4154 } 4172 }
4155 default: 4173 default:
4156 UNREACHABLE(); 4174 UNREACHABLE();
4157 } 4175 }
4158 4176
4159 // Optimize for the case where (at least) one of the expressions 4177 // Optimize for the case where (at least) one of the expressions
4160 // is a literal small integer. 4178 // is a literal small integer.
4161 if (IsInlineSmi(left->AsLiteral())) { 4179 if (IsInlineSmi(left->AsLiteral())) {
4180 frame_->SpillAll();
4162 Load(right); 4181 Load(right);
4163 frame_->SpillAll(); 4182 frame_->SpillAll();
4164 SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(), strict); 4183 SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(), strict);
4165 return; 4184 return;
4166 } 4185 }
4167 if (IsInlineSmi(right->AsLiteral())) { 4186 if (IsInlineSmi(right->AsLiteral())) {
4168 Load(left); 4187 Load(left);
4169 frame_->SpillAll();
4170 SmiComparison(cc, right->AsLiteral()->handle(), strict); 4188 SmiComparison(cc, right->AsLiteral()->handle(), strict);
4171 return; 4189 return;
4172 } 4190 }
4173 4191
4192 frame_->SpillAll();
4174 Load(left); 4193 Load(left);
4175 frame_->SpillAll(); 4194 frame_->SpillAll();
4176 Load(right); 4195 Load(right);
4177 frame_->SpillAll(); 4196 frame_->SpillAll();
4178 Comparison(cc, strict); 4197 Comparison(cc, strict);
4179 } 4198 }
4180 4199
4181 4200
4182 void CodeGenerator::RecordStatementPosition(Node* node) { 4201 void CodeGenerator::RecordStatementPosition(Node* node) {
4183 if (FLAG_debug_info) { 4202 if (FLAG_debug_info) {
(...skipping 1521 matching lines...) Expand 10 before | Expand all | Expand 10 after
5705 5724
5706 // Slow-case: Go through the JavaScript implementation. 5725 // Slow-case: Go through the JavaScript implementation.
5707 __ bind(&slow); 5726 __ bind(&slow);
5708 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 5727 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
5709 } 5728 }
5710 5729
5711 5730
5712 #undef __ 5731 #undef __
5713 5732
5714 } } // namespace v8::internal 5733 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/virtual-frame-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698