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

Unified Diff: src/codegen-ia32.cc

Issue 18144: Experimental: remove the cc_reg_ state from the code generator. There... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/codegen-ia32.h ('k') | src/jump-target-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/codegen-ia32.cc
===================================================================
--- src/codegen-ia32.cc (revision 1094)
+++ src/codegen-ia32.cc (working copy)
@@ -81,7 +81,6 @@
scope_(NULL),
frame_(NULL),
allocator_(NULL),
- cc_reg_(no_condition),
state_(NULL),
break_stack_height_(0),
loop_nesting_(0),
@@ -139,7 +138,6 @@
allocator_ = &register_allocator;
ASSERT(frame_ == NULL);
frame_ = new VirtualFrame(this);
- cc_reg_ = no_condition;
function_return_.set_code_generator(this);
function_return_is_shadowed_ = false;
set_in_spilled_code(false);
@@ -330,7 +328,6 @@
ASSERT(loop_nesting() == 0);
ASSERT(!function_return_is_shadowed_);
function_return_.Unuse();
- ASSERT(!has_cc());
DeleteFrame();
// Process any deferred code using the register allocator.
@@ -394,19 +391,16 @@
}
-// Loads a value on TOS. If it is a boolean value, the result may have been
-// (partially) translated into branches, or it may have set the condition
-// code register. If force_cc is set, the value is forced to set the
-// condition code register and no value is pushed. If the condition code
-// register was set, has_cc() is true and cc_reg_ contains the condition to
-// test for 'true'.
+// Loads a value on TOS. If the result is a boolean value it may have
+// been translated into control flow to the true and/or false targets.
+// If force_control is true, control flow is forced and the function
+// exits without a valid frame.
void CodeGenerator::LoadCondition(Expression* x,
TypeofState typeof_state,
JumpTarget* true_target,
JumpTarget* false_target,
- bool force_cc) {
+ bool force_control) {
ASSERT(!in_spilled_code());
- ASSERT(!has_cc());
#ifdef DEBUG
int original_height = frame_->height();
#endif
@@ -414,15 +408,13 @@
Visit(x);
}
- if (force_cc && has_valid_frame() && !has_cc()) {
+ if (force_control && has_valid_frame()) {
// Convert the TOS value to a boolean in the condition code register.
ToBoolean(true_target, false_target);
}
- ASSERT(!force_cc || frame_ == NULL || has_cc());
- ASSERT(!has_valid_frame() ||
- (has_cc() && frame_->height() == original_height) ||
- (!has_cc() && frame_->height() == original_height + 1));
+ ASSERT(!(force_control && has_valid_frame()));
+ ASSERT(!has_valid_frame() || frame_->height() == original_height + 1);
}
@@ -435,22 +427,6 @@
JumpTarget false_target(this);
LoadCondition(x, typeof_state, &true_target, &false_target, false);
- if (has_cc()) {
- ASSERT(has_valid_frame());
- VirtualFrame::SpilledScope spilled_scope(this);
- // Convert cc_reg_ into a boolean value.
- JumpTarget loaded(this);
- JumpTarget materialize_true(this);
- Condition cc = cc_reg_;
- cc_reg_ = no_condition;
- materialize_true.Branch(cc);
- frame_->EmitPush(Immediate(Factory::false_value()));
- loaded.Jump();
- materialize_true.Bind();
- frame_->EmitPush(Immediate(Factory::true_value()));
- loaded.Bind();
- }
-
if (true_target.is_linked() || false_target.is_linked()) {
// We have at least one condition value that has been "translated" into
// a branch, thus it needs to be loaded explicitly.
@@ -480,7 +456,6 @@
loaded.Bind();
}
ASSERT(has_valid_frame());
- ASSERT(!has_cc());
ASSERT(frame_->height() == original_height + 1);
}
@@ -644,9 +619,9 @@
Result temp = frame_->CallStub(&stub, 1);
// Convert the result to a condition code.
__ test(temp.reg(), Operand(temp.reg()));
-
- ASSERT(not_equal == not_zero);
- cc_reg_ = not_equal;
+ temp.Unuse();
+ true_target->Branch(not_equal);
+ false_target->Jump();
}
@@ -1205,7 +1180,10 @@
};
-void CodeGenerator::Comparison(Condition cc, bool strict) {
+void CodeGenerator::Comparison(Condition cc,
+ bool strict,
+ JumpTarget* true_target,
+ JumpTarget* false_target) {
// Strict only makes sense for equality comparisons.
ASSERT(!strict || cc == equal);
@@ -1291,7 +1269,9 @@
done.Bind(&answer);
answer.ToRegister();
__ test(answer.reg(), Operand(answer.reg()));
- cc_reg_ = not_zero;
+ answer.Unuse();
+ true_target->Branch(not_zero);
+ false_target->Jump();
}
@@ -1374,7 +1354,9 @@
deferred->exit()->Bind(&flag);
flag.ToRegister();
__ test(flag.reg(), Operand(flag.reg()));
- cc_reg_ = not_zero;
+ flag.Unuse();
+ true_target()->Branch(not_zero);
+ false_target()->Jump();
}
@@ -1419,14 +1401,6 @@
}
-void CodeGenerator::Branch(bool if_true, JumpTarget* target) {
- ASSERT(has_cc());
- Condition cc = if_true ? cc_reg_ : NegateCondition(cc_reg_);
- cc_reg_ = no_condition;
- target->Branch(cc);
-}
-
-
void CodeGenerator::CheckStack() {
if (FLAG_check_stack) {
JumpTarget stack_is_ok(this);
@@ -1573,25 +1547,15 @@
JumpTarget then(this);
JumpTarget else_(this);
LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true);
- if (has_valid_frame()) {
- // We have fallen through from the condition (with a value in cc_reg).
- // Emit a branch if false around the then block and compile both
- // blocks.
- Branch(false, &else_);
- }
if (then.is_linked()) {
then.Bind();
- }
- if (has_valid_frame()) {
- // We have fallen through from the condition or reached here by a
- // direct jump to the then target.
Visit(node->then_statement());
+ if (has_valid_frame() && else_.is_linked()) {
+ // We have fallen through from the then block and we need to compile
+ // the else block. Emit an unconditional jump around it.
+ exit.Jump();
+ }
}
- if (has_valid_frame() && else_.is_linked()) {
- // We have fallen through from the then block and we need to compile
- // the else block. Emit an unconditional jump around it.
- exit.Jump();
- }
if (else_.is_linked()) {
else_.Bind();
Visit(node->else_statement());
@@ -1601,17 +1565,8 @@
ASSERT(!has_else_stm);
JumpTarget then(this);
LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &exit, true);
- if (has_valid_frame()) {
- // We have fallen through from the condition (with a value in cc_reg).
- // Emit a branch if false around the then block.
- Branch(false, &exit);
- }
if (then.is_linked()) {
then.Bind();
- }
- if (has_valid_frame()) {
- // We have fallen through from the condition or reached here by a
- // direct jump to the then target.
Visit(node->then_statement());
}
@@ -1619,34 +1574,21 @@
ASSERT(!has_then_stm);
JumpTarget else_(this);
LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &exit, &else_, true);
- if (has_valid_frame()) {
- // We have fallen through from the condition (with a value in cc_reg).
- // Emit a branch if true around the else block.
- Branch(true, &exit);
- }
if (else_.is_linked()) {
else_.Bind();
- }
- if (has_valid_frame()) {
- // We have fallen through from the condition or reached here by a
- // direct jump to the else target.
Visit(node->else_statement());
}
} else {
ASSERT(!has_then_stm && !has_else_stm);
- // We only care about the condition's side effects (not its value or
- // control flow effect). LoadCondition is called without forcing a
- // value into cc_reg.
+ // We only care about the condition's side effects (not its value
+ // or control flow effect). LoadCondition is called without
+ // forcing control flow.
LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &exit, &exit, false);
if (has_valid_frame()) {
- // Control flow can fall off the end of the condition. We discard its
- // value, which may be in cc_reg or else on top of the virtual frame.
- if (has_cc()) {
- cc_reg_ = no_condition;
- } else {
- frame_->Drop();
- }
+ // Control flow can fall off the end of the condition with a
+ // value on the frame.
+ frame_->Drop();
}
}
@@ -1906,11 +1848,12 @@
// Duplicate the switch value.
frame_->Dup();
Load(clause->label());
- Comparison(equal, true);
- Branch(false, &next_test);
+ JumpTarget enter_body(this);
+ Comparison(equal, true, &enter_body, &next_test);
// Before entering the body from the test remove the switch value from
// the frame.
+ enter_body.Bind();
frame_->Drop();
// Label the body so that fall through is enabled.
@@ -2031,11 +1974,6 @@
if (has_valid_frame()) {
LoadCondition(node->cond(), NOT_INSIDE_TYPEOF,
&body, node->break_target(), true);
- // An invalid frame here indicates that control flow did not fall
- // out of the test expression.
- if (has_valid_frame()) {
- Branch(true, &body);
- }
}
}
break;
@@ -2059,11 +1997,6 @@
JumpTarget body(this);
LoadCondition(node->cond(), NOT_INSIDE_TYPEOF,
&body, node->break_target(), true);
- // An invalid frame indicates that control did not fall out of the
- // test expression.
- if (has_valid_frame()) {
- Branch(false, node->break_target());
- }
if (body.is_linked()) {
body.Bind();
}
@@ -2107,9 +2040,6 @@
JumpTarget body(this);
LoadCondition(node->cond(), NOT_INSIDE_TYPEOF,
&body, node->break_target(), true);
- if (has_valid_frame()) {
- Branch(false, node->break_target());
- }
if (body.is_linked()) {
body.Bind();
}
@@ -2692,21 +2622,22 @@
JumpTarget else_(this);
JumpTarget exit(this);
LoadCondition(node->condition(), NOT_INSIDE_TYPEOF, &then, &else_, true);
- if (has_valid_frame()) {
- Branch(false, &else_);
- }
if (then.is_linked()) {
then.Bind();
- }
- if (has_valid_frame()) {
Load(node->then_expression(), typeof_state());
- exit.Jump();
+ if (else_.is_linked()) {
+ exit.Jump();
+ }
}
+
if (else_.is_linked()) {
else_.Bind();
Load(node->else_expression(), typeof_state());
}
- exit.Bind();
+
+ if (exit.is_linked()) {
+ exit.Bind();
+ }
}
@@ -3458,7 +3389,8 @@
LoadAndSpill(args->at(0));
frame_->EmitPop(eax);
__ test(eax, Immediate(kSmiTagMask));
- cc_reg_ = zero;
+ true_target()->Branch(zero);
+ false_target()->Jump();
}
@@ -3488,7 +3420,8 @@
LoadAndSpill(args->at(0));
frame_->EmitPop(eax);
__ test(eax, Immediate(kSmiTagMask | 0x80000000));
- cc_reg_ = zero;
+ true_target()->Branch(zero);
+ false_target()->Jump();
}
@@ -3612,7 +3545,6 @@
void CodeGenerator::GenerateIsArray(ZoneList<Expression*>* args) {
ASSERT(args->length() == 1);
LoadAndSpill(args->at(0));
- Label answer;
// We need the CC bits to come out as not_equal in the case where the
// object is a smi. This can't be done with the usual test opcode so
// we copy the object to ecx and do some destructive ops on it that
@@ -3621,14 +3553,14 @@
__ mov(ecx, Operand(eax));
__ and_(ecx, kSmiTagMask);
__ xor_(ecx, kSmiTagMask);
- __ j(not_equal, &answer, not_taken);
+ false_target()->Branch(not_equal);
// It is a heap object - get map.
__ mov(eax, FieldOperand(eax, HeapObject::kMapOffset));
__ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset));
// Check if the object is a JS array or not.
__ cmp(eax, JS_ARRAY_TYPE);
- __ bind(&answer);
- cc_reg_ = equal;
+ true_target()->Branch(equal);
+ false_target()->Jump();
}
@@ -3719,7 +3651,8 @@
frame_->EmitPop(eax);
frame_->EmitPop(ecx);
__ cmp(eax, Operand(ecx));
- cc_reg_ = equal;
+ true_target()->Branch(equal);
+ false_target()->Jump();
}
@@ -3774,7 +3707,6 @@
VirtualFrame::SpilledScope spilled_scope(this);
LoadConditionAndSpill(node->expression(), NOT_INSIDE_TYPEOF,
false_target(), true_target(), true);
- cc_reg_ = NegateCondition(cc_reg_);
} else if (op == Token::DELETE) {
VirtualFrame::SpilledScope spilled_scope(this);
@@ -4109,17 +4041,10 @@
JumpTarget is_true(this);
LoadCondition(node->left(), NOT_INSIDE_TYPEOF,
&is_true, false_target(), false);
- if (has_cc() || frame_ == NULL) {
- if (has_cc()) {
- ASSERT(has_valid_frame());
- Branch(false, false_target());
- }
-
+ if (!has_valid_frame()) {
if (is_true.is_linked()) {
- is_true.Bind();
- }
- if (has_valid_frame()) {
// Evaluate right side expression.
+ is_true.Bind();
LoadCondition(node->right(), NOT_INSIDE_TYPEOF,
true_target(), false_target(), false);
}
@@ -4135,7 +4060,6 @@
// Duplicate the TOS value. The duplicate will be popped by ToBoolean.
frame_->Dup();
ToBoolean(&pop_and_continue, &exit);
- Branch(false, &exit);
// Pop the result of evaluating the first part.
pop_and_continue.Bind();
@@ -4153,17 +4077,10 @@
JumpTarget is_false(this);
LoadCondition(node->left(), NOT_INSIDE_TYPEOF,
true_target(), &is_false, false);
- if (has_cc() || frame_ == NULL) {
- if (has_cc()) {
- ASSERT(has_valid_frame());
- Branch(true, true_target());
- }
-
+ if (!has_valid_frame()) {
if (is_false.is_linked()) {
// Evaluate right side expression.
is_false.Bind();
- }
- if (has_valid_frame()) {
LoadCondition(node->right(), NOT_INSIDE_TYPEOF,
true_target(), false_target(), false);
}
@@ -4178,7 +4095,6 @@
// Duplicate the TOS value. The duplicate will be popped by ToBoolean.
frame_->Dup();
ToBoolean(&exit, &pop_and_continue);
- Branch(true, &exit);
// Pop the result of evaluating the first part.
pop_and_continue.Bind();
@@ -4286,7 +4202,8 @@
__ cmp(eax, 1 << Map::kIsUndetectable);
}
- cc_reg_ = equal;
+ true_target()->Branch(equal);
+ false_target()->Jump();
return;
}
}
@@ -4311,7 +4228,8 @@
true_target()->Branch(zero);
__ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
__ cmp(edx, Factory::heap_number_map());
- cc_reg_ = equal;
+ true_target()->Branch(equal);
+ false_target()->Jump();
} else if (check->Equals(Heap::string_symbol())) {
__ test(edx, Immediate(kSmiTagMask));
@@ -4327,13 +4245,15 @@
__ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset));
__ cmp(ecx, FIRST_NONSTRING_TYPE);
- cc_reg_ = less;
+ true_target()->Branch(less);
+ false_target()->Jump();
} else if (check->Equals(Heap::boolean_symbol())) {
__ cmp(edx, Factory::true_value());
true_target()->Branch(equal);
__ cmp(edx, Factory::false_value());
- cc_reg_ = equal;
+ true_target()->Branch(equal);
+ false_target()->Jump();
} else if (check->Equals(Heap::undefined_symbol())) {
__ cmp(edx, Factory::undefined_value());
@@ -4347,16 +4267,17 @@
__ movzx_b(ecx, FieldOperand(edx, Map::kBitFieldOffset));
__ and_(ecx, 1 << Map::kIsUndetectable);
__ cmp(ecx, 1 << Map::kIsUndetectable);
+ true_target()->Branch(equal);
+ false_target()->Jump();
- cc_reg_ = equal;
-
} else if (check->Equals(Heap::function_symbol())) {
__ test(edx, Immediate(kSmiTagMask));
false_target()->Branch(zero);
__ mov(edx, FieldOperand(edx, HeapObject::kMapOffset));
__ movzx_b(edx, FieldOperand(edx, Map::kInstanceTypeOffset));
__ cmp(edx, JS_FUNCTION_TYPE);
- cc_reg_ = equal;
+ true_target()->Branch(equal);
+ false_target()->Jump();
} else if (check->Equals(Heap::object_symbol())) {
__ test(edx, Immediate(kSmiTagMask));
@@ -4376,14 +4297,13 @@
__ cmp(ecx, FIRST_JS_OBJECT_TYPE);
false_target()->Branch(less);
__ cmp(ecx, LAST_JS_OBJECT_TYPE);
- cc_reg_ = less_equal;
+ true_target()->Branch(less_equal);
+ false_target()->Jump();
} else {
// Uncommon case: typeof testing against a string literal that is
// never returned from the typeof operator.
false_target()->Jump();
- // TODO(kmilliken) : Can this cause a problem because it is an expression
- // that exits without a virtual frame in place?
}
return;
}
@@ -4422,7 +4342,8 @@
InstanceofStub stub;
frame_->CallStub(&stub, 2);
__ test(eax, Operand(eax));
- cc_reg_ = zero;
+ true_target()->Branch(zero);
+ false_target()->Jump();
return;
}
default:
@@ -4434,17 +4355,14 @@
if (IsInlineSmi(left->AsLiteral())) {
Load(right);
SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(), strict);
- return;
- }
- if (IsInlineSmi(right->AsLiteral())) {
+ } else if (IsInlineSmi(right->AsLiteral())) {
Load(left);
SmiComparison(cc, right->AsLiteral()->handle(), strict);
- return;
+ } else {
+ Load(left);
+ Load(right);
+ Comparison(cc, strict, true_target(), false_target());
}
-
- Load(left);
- Load(right);
- Comparison(cc, strict);
}
@@ -4534,7 +4452,6 @@
void Reference::GetValue(TypeofState typeof_state) {
ASSERT(!cgen_->in_spilled_code());
ASSERT(!is_illegal());
- ASSERT(!cgen_->has_cc());
MacroAssembler* masm = cgen_->masm();
switch (type_) {
case SLOT: {
@@ -4687,7 +4604,6 @@
// slot. For all others, we fall back on GetValue.
ASSERT(!cgen_->in_spilled_code());
ASSERT(!is_illegal());
- ASSERT(!cgen_->has_cc());
if (type_ != SLOT) {
GetValue(typeof_state);
return;
@@ -4715,7 +4631,6 @@
void Reference::SetValue(InitState init_state) {
ASSERT(!is_illegal());
- ASSERT(!cgen_->has_cc());
MacroAssembler* masm = cgen_->masm();
VirtualFrame* frame = cgen_->frame();
switch (type_) {
« no previous file with comments | « src/codegen-ia32.h ('k') | src/jump-target-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698