Commit 4ee7a92d authored by olivf@chromium.org's avatar olivf@chromium.org

Lithium codegen should not pass around block_ids. Rather encapsulate the basic...

Lithium codegen should not pass around block_ids. Rather encapsulate the basic block to assembly label mapping in the LInstruction.

BUG=
R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/17276002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15235 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6ed90f08
...@@ -490,17 +490,44 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> { ...@@ -490,17 +490,44 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
template<int I, int T> template<int I, int T>
class LControlInstruction: public LTemplateInstruction<0, I, T> { class LControlInstruction: public LTemplateInstruction<0, I, T> {
public: public:
LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
virtual bool IsControl() const { return true; } virtual bool IsControl() const { return true; }
int SuccessorCount() { return hydrogen()->SuccessorCount(); } int SuccessorCount() { return hydrogen()->SuccessorCount(); }
HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); }
int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); } int TrueDestination(LChunk* chunk) {
return chunk->LookupDestination(true_block_id());
}
int FalseDestination(LChunk* chunk) {
return chunk->LookupDestination(false_block_id());
}
Label* TrueLabel(LChunk* chunk) {
if (true_label_ == NULL) {
true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
}
return true_label_;
}
Label* FalseLabel(LChunk* chunk) {
if (false_label_ == NULL) {
false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
}
return false_label_;
}
protected:
int true_block_id() { return SuccessorAt(0)->block_id(); }
int false_block_id() { return SuccessorAt(1)->block_id(); }
private: private:
HControlInstruction* hydrogen() { HControlInstruction* hydrogen() {
return HControlInstruction::cast(this->hydrogen_value()); return HControlInstruction::cast(this->hydrogen_value());
} }
Label* false_label_;
Label* true_label_;
}; };
...@@ -1237,7 +1264,7 @@ class LBranch: public LControlInstruction<1, 0> { ...@@ -1237,7 +1264,7 @@ class LBranch: public LControlInstruction<1, 0> {
}; };
class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> { class LCmpMapAndBranch: public LControlInstruction<1, 1> {
public: public:
LCmpMapAndBranch(LOperand* value, LOperand* temp) { LCmpMapAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value; inputs_[0] = value;
...@@ -1250,15 +1277,7 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> { ...@@ -1250,15 +1277,7 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> {
DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMap) DECLARE_HYDROGEN_ACCESSOR(CompareMap)
virtual bool IsControl() const { return true; }
Handle<Map> map() const { return hydrogen()->map(); } Handle<Map> map() const { return hydrogen()->map(); }
int true_block_id() const {
return hydrogen()->FirstSuccessor()->block_id();
}
int false_block_id() const {
return hydrogen()->SecondSuccessor()->block_id();
}
}; };
......
...@@ -2159,11 +2159,12 @@ int LCodeGen::GetNextEmittedBlock() const { ...@@ -2159,11 +2159,12 @@ int LCodeGen::GetNextEmittedBlock() const {
return -1; return -1;
} }
template<class InstrType>
void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
int right_block = instr->FalseDestination(chunk_);
int left_block = instr->TrueDestination(chunk_);
void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) {
int next_block = GetNextEmittedBlock(); int next_block = GetNextEmittedBlock();
right_block = chunk_->LookupDestination(right_block);
left_block = chunk_->LookupDestination(left_block);
if (right_block == left_block) { if (right_block == left_block) {
EmitGoto(left_block); EmitGoto(left_block);
...@@ -2184,22 +2185,19 @@ void LCodeGen::DoDebugBreak(LDebugBreak* instr) { ...@@ -2184,22 +2185,19 @@ void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
void LCodeGen::DoBranch(LBranch* instr) { void LCodeGen::DoBranch(LBranch* instr) {
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Representation r = instr->hydrogen()->value()->representation(); Representation r = instr->hydrogen()->value()->representation();
if (r.IsInteger32() || r.IsSmi()) { if (r.IsInteger32() || r.IsSmi()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
__ cmp(reg, Operand::Zero()); __ cmp(reg, Operand::Zero());
EmitBranch(true_block, false_block, ne); EmitBranch(instr, ne);
} else if (r.IsDouble()) { } else if (r.IsDouble()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
DwVfpRegister reg = ToDoubleRegister(instr->value()); DwVfpRegister reg = ToDoubleRegister(instr->value());
// Test the double value. Zero and NaN are false. // Test the double value. Zero and NaN are false.
__ VFPCompareAndSetFlags(reg, 0.0); __ VFPCompareAndSetFlags(reg, 0.0);
__ cmp(r0, r0, vs); // If NaN, set the Z flag. __ cmp(r0, r0, vs); // If NaN, set the Z flag.
EmitBranch(true_block, false_block, ne); EmitBranch(instr, ne);
} else { } else {
ASSERT(r.IsTagged()); ASSERT(r.IsTagged());
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
...@@ -2207,15 +2205,12 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2207,15 +2205,12 @@ void LCodeGen::DoBranch(LBranch* instr) {
if (type.IsBoolean()) { if (type.IsBoolean()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
__ CompareRoot(reg, Heap::kTrueValueRootIndex); __ CompareRoot(reg, Heap::kTrueValueRootIndex);
EmitBranch(true_block, false_block, eq); EmitBranch(instr, eq);
} else if (type.IsSmi()) { } else if (type.IsSmi()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
__ cmp(reg, Operand::Zero()); __ cmp(reg, Operand::Zero());
EmitBranch(true_block, false_block, ne); EmitBranch(instr, ne);
} else { } else {
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
// Avoid deopts in the case where we've never executed this path before. // Avoid deopts in the case where we've never executed this path before.
if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
...@@ -2223,26 +2218,26 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2223,26 +2218,26 @@ void LCodeGen::DoBranch(LBranch* instr) {
if (expected.Contains(ToBooleanStub::UNDEFINED)) { if (expected.Contains(ToBooleanStub::UNDEFINED)) {
// undefined -> false. // undefined -> false.
__ CompareRoot(reg, Heap::kUndefinedValueRootIndex); __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
__ b(eq, false_label); __ b(eq, instr->FalseLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::BOOLEAN)) { if (expected.Contains(ToBooleanStub::BOOLEAN)) {
// Boolean -> its value. // Boolean -> its value.
__ CompareRoot(reg, Heap::kTrueValueRootIndex); __ CompareRoot(reg, Heap::kTrueValueRootIndex);
__ b(eq, true_label); __ b(eq, instr->TrueLabel(chunk_));
__ CompareRoot(reg, Heap::kFalseValueRootIndex); __ CompareRoot(reg, Heap::kFalseValueRootIndex);
__ b(eq, false_label); __ b(eq, instr->FalseLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::NULL_TYPE)) { if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
// 'null' -> false. // 'null' -> false.
__ CompareRoot(reg, Heap::kNullValueRootIndex); __ CompareRoot(reg, Heap::kNullValueRootIndex);
__ b(eq, false_label); __ b(eq, instr->FalseLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::SMI)) { if (expected.Contains(ToBooleanStub::SMI)) {
// Smis: 0 -> false, all other -> true. // Smis: 0 -> false, all other -> true.
__ cmp(reg, Operand::Zero()); __ cmp(reg, Operand::Zero());
__ b(eq, false_label); __ b(eq, instr->FalseLabel(chunk_));
__ JumpIfSmi(reg, true_label); __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
} else if (expected.NeedsMap()) { } else if (expected.NeedsMap()) {
// If we need a map later and have a Smi -> deopt. // If we need a map later and have a Smi -> deopt.
__ SmiTst(reg); __ SmiTst(reg);
...@@ -2257,14 +2252,14 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2257,14 +2252,14 @@ void LCodeGen::DoBranch(LBranch* instr) {
// Undetectable -> false. // Undetectable -> false.
__ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset));
__ tst(ip, Operand(1 << Map::kIsUndetectable)); __ tst(ip, Operand(1 << Map::kIsUndetectable));
__ b(ne, false_label); __ b(ne, instr->FalseLabel(chunk_));
} }
} }
if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
// spec object -> true. // spec object -> true.
__ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE); __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE);
__ b(ge, true_label); __ b(ge, instr->TrueLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::STRING)) { if (expected.Contains(ToBooleanStub::STRING)) {
...@@ -2274,15 +2269,15 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2274,15 +2269,15 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ b(ge, &not_string); __ b(ge, &not_string);
__ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset));
__ cmp(ip, Operand::Zero()); __ cmp(ip, Operand::Zero());
__ b(ne, true_label); __ b(ne, instr->TrueLabel(chunk_));
__ b(false_label); __ b(instr->FalseLabel(chunk_));
__ bind(&not_string); __ bind(&not_string);
} }
if (expected.Contains(ToBooleanStub::SYMBOL)) { if (expected.Contains(ToBooleanStub::SYMBOL)) {
// Symbol value -> true. // Symbol value -> true.
__ CompareInstanceType(map, ip, SYMBOL_TYPE); __ CompareInstanceType(map, ip, SYMBOL_TYPE);
__ b(eq, true_label); __ b(eq, instr->TrueLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
...@@ -2294,8 +2289,8 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2294,8 +2289,8 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
__ VFPCompareAndSetFlags(dbl_scratch, 0.0); __ VFPCompareAndSetFlags(dbl_scratch, 0.0);
__ cmp(r0, r0, vs); // NaN -> false. __ cmp(r0, r0, vs); // NaN -> false.
__ b(eq, false_label); // +0, -0 -> false. __ b(eq, instr->FalseLabel(chunk_)); // +0, -0 -> false.
__ b(true_label); __ b(instr->TrueLabel(chunk_));
__ bind(&not_heap_number); __ bind(&not_heap_number);
} }
...@@ -2308,7 +2303,7 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2308,7 +2303,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
void LCodeGen::EmitGoto(int block) { void LCodeGen::EmitGoto(int block) {
if (!IsNextEmittedBlock(block)) { if (!IsNextEmittedBlock(block)) {
__ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block))); __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
} }
} }
...@@ -2349,17 +2344,14 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { ...@@ -2349,17 +2344,14 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
LOperand* left = instr->left(); LOperand* left = instr->left();
LOperand* right = instr->right(); LOperand* right = instr->right();
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
Condition cond = TokenToCondition(instr->op(), false); Condition cond = TokenToCondition(instr->op(), false);
if (left->IsConstantOperand() && right->IsConstantOperand()) { if (left->IsConstantOperand() && right->IsConstantOperand()) {
// We can statically evaluate the comparison. // We can statically evaluate the comparison.
double left_val = ToDouble(LConstantOperand::cast(left)); double left_val = ToDouble(LConstantOperand::cast(left));
double right_val = ToDouble(LConstantOperand::cast(right)); double right_val = ToDouble(LConstantOperand::cast(right));
int next_block = int next_block = EvalComparison(instr->op(), left_val, right_val) ?
EvalComparison(instr->op(), left_val, right_val) ? true_block instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
: false_block;
EmitGoto(next_block); EmitGoto(next_block);
} else { } else {
if (instr->is_double()) { if (instr->is_double()) {
...@@ -2368,7 +2360,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { ...@@ -2368,7 +2360,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
__ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right));
// If a NaN is involved, i.e. the result is unordered (V set), // If a NaN is involved, i.e. the result is unordered (V set),
// jump to false block label. // jump to false block label.
__ b(vs, chunk_->GetAssemblyLabel(false_block)); __ b(vs, instr->FalseLabel(chunk_));
} else { } else {
if (right->IsConstantOperand()) { if (right->IsConstantOperand()) {
int32_t value = ToInteger32(LConstantOperand::cast(right)); int32_t value = ToInteger32(LConstantOperand::cast(right));
...@@ -2390,7 +2382,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { ...@@ -2390,7 +2382,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
__ cmp(ToRegister(left), ToRegister(right)); __ cmp(ToRegister(left), ToRegister(right));
} }
} }
EmitBranch(true_block, false_block, cond); EmitBranch(instr, cond);
} }
} }
...@@ -2398,21 +2390,17 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { ...@@ -2398,21 +2390,17 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
Register left = ToRegister(instr->left()); Register left = ToRegister(instr->left());
Register right = ToRegister(instr->right()); Register right = ToRegister(instr->right());
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
__ cmp(left, Operand(right)); __ cmp(left, Operand(right));
EmitBranch(true_block, false_block, eq); EmitBranch(instr, eq);
} }
void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
Register left = ToRegister(instr->left()); Register left = ToRegister(instr->left());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
__ cmp(left, Operand(instr->hydrogen()->right())); __ cmp(left, Operand(instr->hydrogen()->right()));
EmitBranch(true_block, false_block, eq); EmitBranch(instr, eq);
} }
...@@ -2447,15 +2435,11 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { ...@@ -2447,15 +2435,11 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
Register temp1 = ToRegister(instr->temp()); Register temp1 = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
Condition true_cond = Condition true_cond =
EmitIsObject(reg, temp1, false_label, true_label); EmitIsObject(reg, temp1,
instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
EmitBranch(true_block, false_block, true_cond); EmitBranch(instr, true_cond);
} }
...@@ -2473,24 +2457,17 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { ...@@ -2473,24 +2457,17 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
Register temp1 = ToRegister(instr->temp()); Register temp1 = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* false_label = chunk_->GetAssemblyLabel(false_block);
Condition true_cond = Condition true_cond =
EmitIsString(reg, temp1, false_label); EmitIsString(reg, temp1, instr->FalseLabel(chunk_));
EmitBranch(true_block, false_block, true_cond); EmitBranch(instr, true_cond);
} }
void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Register input_reg = EmitLoadRegister(instr->value(), ip); Register input_reg = EmitLoadRegister(instr->value(), ip);
__ SmiTst(input_reg); __ SmiTst(input_reg);
EmitBranch(true_block, false_block, eq); EmitBranch(instr, eq);
} }
...@@ -2498,14 +2475,11 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { ...@@ -2498,14 +2475,11 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id()); __ JumpIfSmi(input, instr->FalseLabel(chunk_));
int false_block = chunk_->LookupDestination(instr->false_block_id());
__ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
__ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset));
__ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset));
__ tst(temp, Operand(1 << Map::kIsUndetectable)); __ tst(temp, Operand(1 << Map::kIsUndetectable));
EmitBranch(true_block, false_block, ne); EmitBranch(instr, ne);
} }
...@@ -2531,8 +2505,6 @@ static Condition ComputeCompareCondition(Token::Value op) { ...@@ -2531,8 +2505,6 @@ static Condition ComputeCompareCondition(Token::Value op) {
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
Token::Value op = instr->op(); Token::Value op = instr->op();
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
...@@ -2541,7 +2513,7 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { ...@@ -2541,7 +2513,7 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
Condition condition = ComputeCompareCondition(op); Condition condition = ComputeCompareCondition(op);
EmitBranch(true_block, false_block, condition); EmitBranch(instr, condition);
} }
...@@ -2569,15 +2541,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { ...@@ -2569,15 +2541,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
Register scratch = scratch0(); Register scratch = scratch0();
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id()); __ JumpIfSmi(input, instr->FalseLabel(chunk_));
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* false_label = chunk_->GetAssemblyLabel(false_block);
__ JumpIfSmi(input, false_label);
__ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen()));
EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); EmitBranch(instr, BranchCondition(instr->hydrogen()));
} }
...@@ -2597,13 +2564,10 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch( ...@@ -2597,13 +2564,10 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
Register scratch = scratch0(); Register scratch = scratch0();
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
__ ldr(scratch, __ ldr(scratch,
FieldMemOperand(input, String::kHashFieldOffset)); FieldMemOperand(input, String::kHashFieldOffset));
__ tst(scratch, Operand(String::kContainsCachedArrayIndexMask)); __ tst(scratch, Operand(String::kContainsCachedArrayIndexMask));
EmitBranch(true_block, false_block, eq); EmitBranch(instr, eq);
} }
...@@ -2680,27 +2644,20 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { ...@@ -2680,27 +2644,20 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
Register temp2 = ToRegister(instr->temp()); Register temp2 = ToRegister(instr->temp());
Handle<String> class_name = instr->hydrogen()->class_name(); Handle<String> class_name = instr->hydrogen()->class_name();
int true_block = chunk_->LookupDestination(instr->true_block_id()); EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
int false_block = chunk_->LookupDestination(instr->false_block_id()); class_name, input, temp, temp2);
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
EmitBranch(true_block, false_block, eq); EmitBranch(instr, eq);
} }
void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
int true_block = instr->true_block_id();
int false_block = instr->false_block_id();
__ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset));
__ cmp(temp, Operand(instr->map())); __ cmp(temp, Operand(instr->map()));
EmitBranch(true_block, false_block, eq); EmitBranch(instr, eq);
} }
...@@ -5597,17 +5554,13 @@ void LCodeGen::DoTypeof(LTypeof* instr) { ...@@ -5597,17 +5554,13 @@ void LCodeGen::DoTypeof(LTypeof* instr) {
void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
Condition final_branch_condition = EmitTypeofIs(true_label, Condition final_branch_condition = EmitTypeofIs(instr->TrueLabel(chunk_),
false_label, instr->FalseLabel(chunk_),
input, input,
instr->type_literal()); instr->type_literal());
if (final_branch_condition != kNoCondition) { if (final_branch_condition != kNoCondition) {
EmitBranch(true_block, false_block, final_branch_condition); EmitBranch(instr, final_branch_condition);
} }
} }
...@@ -5692,11 +5645,9 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, ...@@ -5692,11 +5645,9 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
Register temp1 = ToRegister(instr->temp()); Register temp1 = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
EmitIsConstructCall(temp1, scratch0()); EmitIsConstructCall(temp1, scratch0());
EmitBranch(true_block, false_block, eq); EmitBranch(instr, eq);
} }
......
...@@ -79,7 +79,6 @@ class LCodeGen BASE_EMBEDDED { ...@@ -79,7 +79,6 @@ class LCodeGen BASE_EMBEDDED {
Heap* heap() const { return isolate()->heap(); } Heap* heap() const { return isolate()->heap(); }
Zone* zone() const { return zone_; } Zone* zone() const { return zone_; }
// TODO(svenpanne) Use this consistently.
int LookupDestination(int block_id) const { int LookupDestination(int block_id) const {
return chunk()->LookupDestination(block_id); return chunk()->LookupDestination(block_id);
} }
...@@ -320,7 +319,8 @@ class LCodeGen BASE_EMBEDDED { ...@@ -320,7 +319,8 @@ class LCodeGen BASE_EMBEDDED {
static Condition TokenToCondition(Token::Value op, bool is_unsigned); static Condition TokenToCondition(Token::Value op, bool is_unsigned);
void EmitGoto(int block); void EmitGoto(int block);
void EmitBranch(int left_block, int right_block, Condition cc); template<class InstrType>
void EmitBranch(InstrType instr, Condition cc);
void EmitNumberUntagD(Register input, void EmitNumberUntagD(Register input,
DwVfpRegister result, DwVfpRegister result,
bool allow_undefined_as_nan, bool allow_undefined_as_nan,
......
...@@ -2087,10 +2087,12 @@ int LCodeGen::GetNextEmittedBlock() const { ...@@ -2087,10 +2087,12 @@ int LCodeGen::GetNextEmittedBlock() const {
} }
void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) { template<class InstrType>
void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
int right_block = instr->FalseDestination(chunk_);
int left_block = instr->TrueDestination(chunk_);
int next_block = GetNextEmittedBlock(); int next_block = GetNextEmittedBlock();
right_block = chunk_->LookupDestination(right_block);
left_block = chunk_->LookupDestination(left_block);
if (right_block == left_block) { if (right_block == left_block) {
EmitGoto(left_block); EmitGoto(left_block);
...@@ -2106,22 +2108,19 @@ void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) { ...@@ -2106,22 +2108,19 @@ void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) {
void LCodeGen::DoBranch(LBranch* instr) { void LCodeGen::DoBranch(LBranch* instr) {
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Representation r = instr->hydrogen()->value()->representation(); Representation r = instr->hydrogen()->value()->representation();
if (r.IsSmiOrInteger32()) { if (r.IsSmiOrInteger32()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
__ test(reg, Operand(reg)); __ test(reg, Operand(reg));
EmitBranch(true_block, false_block, not_zero); EmitBranch(instr, not_zero);
} else if (r.IsDouble()) { } else if (r.IsDouble()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
CpuFeatureScope scope(masm(), SSE2); CpuFeatureScope scope(masm(), SSE2);
XMMRegister reg = ToDoubleRegister(instr->value()); XMMRegister reg = ToDoubleRegister(instr->value());
__ xorps(xmm0, xmm0); __ xorps(xmm0, xmm0);
__ ucomisd(reg, xmm0); __ ucomisd(reg, xmm0);
EmitBranch(true_block, false_block, not_equal); EmitBranch(instr, not_equal);
} else { } else {
ASSERT(r.IsTagged()); ASSERT(r.IsTagged());
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
...@@ -2129,15 +2128,12 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2129,15 +2128,12 @@ void LCodeGen::DoBranch(LBranch* instr) {
if (type.IsBoolean()) { if (type.IsBoolean()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
__ cmp(reg, factory()->true_value()); __ cmp(reg, factory()->true_value());
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} else if (type.IsSmi()) { } else if (type.IsSmi()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
__ test(reg, Operand(reg)); __ test(reg, Operand(reg));
EmitBranch(true_block, false_block, not_equal); EmitBranch(instr, not_equal);
} else { } else {
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
// Avoid deopts in the case where we've never executed this path before. // Avoid deopts in the case where we've never executed this path before.
if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
...@@ -2145,27 +2141,27 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2145,27 +2141,27 @@ void LCodeGen::DoBranch(LBranch* instr) {
if (expected.Contains(ToBooleanStub::UNDEFINED)) { if (expected.Contains(ToBooleanStub::UNDEFINED)) {
// undefined -> false. // undefined -> false.
__ cmp(reg, factory()->undefined_value()); __ cmp(reg, factory()->undefined_value());
__ j(equal, false_label); __ j(equal, instr->FalseLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::BOOLEAN)) { if (expected.Contains(ToBooleanStub::BOOLEAN)) {
// true -> true. // true -> true.
__ cmp(reg, factory()->true_value()); __ cmp(reg, factory()->true_value());
__ j(equal, true_label); __ j(equal, instr->TrueLabel(chunk_));
// false -> false. // false -> false.
__ cmp(reg, factory()->false_value()); __ cmp(reg, factory()->false_value());
__ j(equal, false_label); __ j(equal, instr->FalseLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::NULL_TYPE)) { if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
// 'null' -> false. // 'null' -> false.
__ cmp(reg, factory()->null_value()); __ cmp(reg, factory()->null_value());
__ j(equal, false_label); __ j(equal, instr->FalseLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::SMI)) { if (expected.Contains(ToBooleanStub::SMI)) {
// Smis: 0 -> false, all other -> true. // Smis: 0 -> false, all other -> true.
__ test(reg, Operand(reg)); __ test(reg, Operand(reg));
__ j(equal, false_label); __ j(equal, instr->FalseLabel(chunk_));
__ JumpIfSmi(reg, true_label); __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
} else if (expected.NeedsMap()) { } else if (expected.NeedsMap()) {
// If we need a map later and have a Smi -> deopt. // If we need a map later and have a Smi -> deopt.
__ test(reg, Immediate(kSmiTagMask)); __ test(reg, Immediate(kSmiTagMask));
...@@ -2182,14 +2178,14 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2182,14 +2178,14 @@ void LCodeGen::DoBranch(LBranch* instr) {
// Undetectable -> false. // Undetectable -> false.
__ test_b(FieldOperand(map, Map::kBitFieldOffset), __ test_b(FieldOperand(map, Map::kBitFieldOffset),
1 << Map::kIsUndetectable); 1 << Map::kIsUndetectable);
__ j(not_zero, false_label); __ j(not_zero, instr->FalseLabel(chunk_));
} }
} }
if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
// spec object -> true. // spec object -> true.
__ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
__ j(above_equal, true_label); __ j(above_equal, instr->TrueLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::STRING)) { if (expected.Contains(ToBooleanStub::STRING)) {
...@@ -2198,15 +2194,15 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2198,15 +2194,15 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ CmpInstanceType(map, FIRST_NONSTRING_TYPE); __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
__ j(above_equal, &not_string, Label::kNear); __ j(above_equal, &not_string, Label::kNear);
__ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0));
__ j(not_zero, true_label); __ j(not_zero, instr->TrueLabel(chunk_));
__ jmp(false_label); __ jmp(instr->FalseLabel(chunk_));
__ bind(&not_string); __ bind(&not_string);
} }
if (expected.Contains(ToBooleanStub::SYMBOL)) { if (expected.Contains(ToBooleanStub::SYMBOL)) {
// Symbol value -> true. // Symbol value -> true.
__ CmpInstanceType(map, SYMBOL_TYPE); __ CmpInstanceType(map, SYMBOL_TYPE);
__ j(equal, true_label); __ j(equal, instr->TrueLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
...@@ -2224,8 +2220,8 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2224,8 +2220,8 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
__ FCmp(); __ FCmp();
} }
__ j(zero, false_label); __ j(zero, instr->FalseLabel(chunk_));
__ jmp(true_label); __ jmp(instr->TrueLabel(chunk_));
__ bind(&not_heap_number); __ bind(&not_heap_number);
} }
...@@ -2238,7 +2234,7 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -2238,7 +2234,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
void LCodeGen::EmitGoto(int block) { void LCodeGen::EmitGoto(int block) {
if (!IsNextEmittedBlock(block)) { if (!IsNextEmittedBlock(block)) {
__ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block))); __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block)));
} }
} }
...@@ -2279,17 +2275,14 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { ...@@ -2279,17 +2275,14 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
LOperand* left = instr->left(); LOperand* left = instr->left();
LOperand* right = instr->right(); LOperand* right = instr->right();
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
Condition cc = TokenToCondition(instr->op(), instr->is_double()); Condition cc = TokenToCondition(instr->op(), instr->is_double());
if (left->IsConstantOperand() && right->IsConstantOperand()) { if (left->IsConstantOperand() && right->IsConstantOperand()) {
// We can statically evaluate the comparison. // We can statically evaluate the comparison.
double left_val = ToDouble(LConstantOperand::cast(left)); double left_val = ToDouble(LConstantOperand::cast(left));
double right_val = ToDouble(LConstantOperand::cast(right)); double right_val = ToDouble(LConstantOperand::cast(right));
int next_block = int next_block = EvalComparison(instr->op(), left_val, right_val) ?
EvalComparison(instr->op(), left_val, right_val) ? true_block instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
: false_block;
EmitGoto(next_block); EmitGoto(next_block);
} else { } else {
if (instr->is_double()) { if (instr->is_double()) {
...@@ -2297,7 +2290,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { ...@@ -2297,7 +2290,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
// Don't base result on EFLAGS when a NaN is involved. Instead // Don't base result on EFLAGS when a NaN is involved. Instead
// jump to the false block. // jump to the false block.
__ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
__ j(parity_even, chunk_->GetAssemblyLabel(false_block)); __ j(parity_even, instr->FalseLabel(chunk_));
} else { } else {
if (right->IsConstantOperand()) { if (right->IsConstantOperand()) {
int32_t const_value = ToInteger32(LConstantOperand::cast(right)); int32_t const_value = ToInteger32(LConstantOperand::cast(right));
...@@ -2319,15 +2312,13 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { ...@@ -2319,15 +2312,13 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
__ cmp(ToRegister(left), ToOperand(right)); __ cmp(ToRegister(left), ToOperand(right));
} }
} }
EmitBranch(true_block, false_block, cc); EmitBranch(instr, cc);
} }
} }
void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
Register left = ToRegister(instr->left()); Register left = ToRegister(instr->left());
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
if (instr->right()->IsConstantOperand()) { if (instr->right()->IsConstantOperand()) {
Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
...@@ -2336,17 +2327,15 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { ...@@ -2336,17 +2327,15 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
Operand right = ToOperand(instr->right()); Operand right = ToOperand(instr->right());
__ cmp(left, right); __ cmp(left, right);
} }
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
Register left = ToRegister(instr->left()); Register left = ToRegister(instr->left());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
__ cmp(left, instr->hydrogen()->right()); __ cmp(left, instr->hydrogen()->right());
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
...@@ -2377,14 +2366,10 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { ...@@ -2377,14 +2366,10 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id()); Condition true_cond = EmitIsObject(
int false_block = chunk_->LookupDestination(instr->false_block_id()); reg, temp, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
Condition true_cond = EmitIsObject(reg, temp, false_label, true_label);
EmitBranch(true_block, false_block, true_cond); EmitBranch(instr, true_cond);
} }
...@@ -2403,24 +2388,17 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { ...@@ -2403,24 +2388,17 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id()); Condition true_cond = EmitIsString(reg, temp, instr->FalseLabel(chunk_));
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* false_label = chunk_->GetAssemblyLabel(false_block);
Condition true_cond = EmitIsString(reg, temp, false_label); EmitBranch(instr, true_cond);
EmitBranch(true_block, false_block, true_cond);
} }
void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
Operand input = ToOperand(instr->value()); Operand input = ToOperand(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
__ test(input, Immediate(kSmiTagMask)); __ test(input, Immediate(kSmiTagMask));
EmitBranch(true_block, false_block, zero); EmitBranch(instr, zero);
} }
...@@ -2428,15 +2406,12 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { ...@@ -2428,15 +2406,12 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTag == 0);
__ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); __ JumpIfSmi(input, instr->FalseLabel(chunk_));
__ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); __ mov(temp, FieldOperand(input, HeapObject::kMapOffset));
__ test_b(FieldOperand(temp, Map::kBitFieldOffset), __ test_b(FieldOperand(temp, Map::kBitFieldOffset),
1 << Map::kIsUndetectable); 1 << Map::kIsUndetectable);
EmitBranch(true_block, false_block, not_zero); EmitBranch(instr, not_zero);
} }
...@@ -2462,8 +2437,6 @@ static Condition ComputeCompareCondition(Token::Value op) { ...@@ -2462,8 +2437,6 @@ static Condition ComputeCompareCondition(Token::Value op) {
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
Token::Value op = instr->op(); Token::Value op = instr->op();
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
...@@ -2471,7 +2444,7 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { ...@@ -2471,7 +2444,7 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
Condition condition = ComputeCompareCondition(op); Condition condition = ComputeCompareCondition(op);
__ test(eax, Operand(eax)); __ test(eax, Operand(eax));
EmitBranch(true_block, false_block, condition); EmitBranch(instr, condition);
} }
...@@ -2499,15 +2472,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { ...@@ -2499,15 +2472,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id()); __ JumpIfSmi(input, instr->FalseLabel(chunk_));
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* false_label = chunk_->GetAssemblyLabel(false_block);
__ JumpIfSmi(input, false_label);
__ CmpObjectType(input, TestType(instr->hydrogen()), temp); __ CmpObjectType(input, TestType(instr->hydrogen()), temp);
EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); EmitBranch(instr, BranchCondition(instr->hydrogen()));
} }
...@@ -2526,12 +2494,9 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch( ...@@ -2526,12 +2494,9 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
LHasCachedArrayIndexAndBranch* instr) { LHasCachedArrayIndexAndBranch* instr) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
__ test(FieldOperand(input, String::kHashFieldOffset), __ test(FieldOperand(input, String::kHashFieldOffset),
Immediate(String::kContainsCachedArrayIndexMask)); Immediate(String::kContainsCachedArrayIndexMask));
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
...@@ -2607,25 +2572,17 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { ...@@ -2607,25 +2572,17 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
Handle<String> class_name = instr->hydrogen()->class_name(); Handle<String> class_name = instr->hydrogen()->class_name();
int true_block = chunk_->LookupDestination(instr->true_block_id()); EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
int false_block = chunk_->LookupDestination(instr->false_block_id()); class_name, input, temp, temp2);
Label* true_label = chunk_->GetAssemblyLabel(true_block); EmitBranch(instr, equal);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
EmitBranch(true_block, false_block, equal);
} }
void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
int true_block = instr->true_block_id();
int false_block = instr->false_block_id();
__ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
...@@ -6243,15 +6200,12 @@ void LCodeGen::DoTypeof(LTypeof* instr) { ...@@ -6243,15 +6200,12 @@ void LCodeGen::DoTypeof(LTypeof* instr) {
void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
Condition final_branch_condition = Condition final_branch_condition =
EmitTypeofIs(true_label, false_label, input, instr->type_literal()); EmitTypeofIs(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
input, instr->type_literal());
if (final_branch_condition != no_condition) { if (final_branch_condition != no_condition) {
EmitBranch(true_block, false_block, final_branch_condition); EmitBranch(instr, final_branch_condition);
} }
} }
...@@ -6332,11 +6286,9 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, ...@@ -6332,11 +6286,9 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
EmitIsConstructCall(temp); EmitIsConstructCall(temp);
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
......
...@@ -83,7 +83,6 @@ class LCodeGen BASE_EMBEDDED { ...@@ -83,7 +83,6 @@ class LCodeGen BASE_EMBEDDED {
Heap* heap() const { return isolate()->heap(); } Heap* heap() const { return isolate()->heap(); }
Zone* zone() const { return zone_; } Zone* zone() const { return zone_; }
// TODO(svenpanne) Use this consistently.
int LookupDestination(int block_id) const { int LookupDestination(int block_id) const {
return chunk()->LookupDestination(block_id); return chunk()->LookupDestination(block_id);
} }
...@@ -318,7 +317,8 @@ class LCodeGen BASE_EMBEDDED { ...@@ -318,7 +317,8 @@ class LCodeGen BASE_EMBEDDED {
static Condition TokenToCondition(Token::Value op, bool is_unsigned); static Condition TokenToCondition(Token::Value op, bool is_unsigned);
void EmitGoto(int block); void EmitGoto(int block);
void EmitBranch(int left_block, int right_block, Condition cc); template<class InstrType>
void EmitBranch(InstrType instr, Condition cc);
void EmitNumberUntagD( void EmitNumberUntagD(
Register input, Register input,
Register temp, Register temp,
......
...@@ -483,17 +483,44 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> { ...@@ -483,17 +483,44 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
template<int I, int T> template<int I, int T>
class LControlInstruction: public LTemplateInstruction<0, I, T> { class LControlInstruction: public LTemplateInstruction<0, I, T> {
public: public:
LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
virtual bool IsControl() const { return true; } virtual bool IsControl() const { return true; }
int SuccessorCount() { return hydrogen()->SuccessorCount(); } int SuccessorCount() { return hydrogen()->SuccessorCount(); }
HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); }
int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); } int TrueDestination(LChunk* chunk) {
return chunk->LookupDestination(true_block_id());
}
int FalseDestination(LChunk* chunk) {
return chunk->LookupDestination(false_block_id());
}
Label* TrueLabel(LChunk* chunk) {
if (true_label_ == NULL) {
true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
}
return true_label_;
}
Label* FalseLabel(LChunk* chunk) {
if (false_label_ == NULL) {
false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
}
return false_label_;
}
protected:
int true_block_id() { return SuccessorAt(0)->block_id(); }
int false_block_id() { return SuccessorAt(1)->block_id(); }
private: private:
HControlInstruction* hydrogen() { HControlInstruction* hydrogen() {
return HControlInstruction::cast(this->hydrogen_value()); return HControlInstruction::cast(this->hydrogen_value());
} }
Label* false_label_;
Label* true_label_;
}; };
...@@ -1207,7 +1234,7 @@ class LBranch: public LControlInstruction<1, 1> { ...@@ -1207,7 +1234,7 @@ class LBranch: public LControlInstruction<1, 1> {
}; };
class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> { class LCmpMapAndBranch: public LControlInstruction<1, 0> {
public: public:
explicit LCmpMapAndBranch(LOperand* value) { explicit LCmpMapAndBranch(LOperand* value) {
inputs_[0] = value; inputs_[0] = value;
...@@ -1218,15 +1245,7 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> { ...@@ -1218,15 +1245,7 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> {
DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMap) DECLARE_HYDROGEN_ACCESSOR(CompareMap)
virtual bool IsControl() const { return true; }
Handle<Map> map() const { return hydrogen()->map(); } Handle<Map> map() const { return hydrogen()->map(); }
int true_block_id() const {
return hydrogen()->FirstSuccessor()->block_id();
}
int false_block_id() const {
return hydrogen()->SecondSuccessor()->block_id();
}
}; };
......
...@@ -1862,10 +1862,12 @@ int LCodeGen::GetNextEmittedBlock() const { ...@@ -1862,10 +1862,12 @@ int LCodeGen::GetNextEmittedBlock() const {
} }
void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) { template<class InstrType>
void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
int right_block = instr->FalseDestination(chunk_);
int left_block = instr->TrueDestination(chunk_);
int next_block = GetNextEmittedBlock(); int next_block = GetNextEmittedBlock();
right_block = chunk_->LookupDestination(right_block);
left_block = chunk_->LookupDestination(left_block);
if (right_block == left_block) { if (right_block == left_block) {
EmitGoto(left_block); EmitGoto(left_block);
...@@ -1888,26 +1890,23 @@ void LCodeGen::DoDebugBreak(LDebugBreak* instr) { ...@@ -1888,26 +1890,23 @@ void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
void LCodeGen::DoBranch(LBranch* instr) { void LCodeGen::DoBranch(LBranch* instr) {
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Representation r = instr->hydrogen()->value()->representation(); Representation r = instr->hydrogen()->value()->representation();
if (r.IsInteger32()) { if (r.IsInteger32()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
__ testl(reg, reg); __ testl(reg, reg);
EmitBranch(true_block, false_block, not_zero); EmitBranch(instr, not_zero);
} else if (r.IsSmi()) { } else if (r.IsSmi()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
__ testq(reg, reg); __ testq(reg, reg);
EmitBranch(true_block, false_block, not_zero); EmitBranch(instr, not_zero);
} else if (r.IsDouble()) { } else if (r.IsDouble()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
XMMRegister reg = ToDoubleRegister(instr->value()); XMMRegister reg = ToDoubleRegister(instr->value());
__ xorps(xmm0, xmm0); __ xorps(xmm0, xmm0);
__ ucomisd(reg, xmm0); __ ucomisd(reg, xmm0);
EmitBranch(true_block, false_block, not_equal); EmitBranch(instr, not_equal);
} else { } else {
ASSERT(r.IsTagged()); ASSERT(r.IsTagged());
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
...@@ -1915,15 +1914,12 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -1915,15 +1914,12 @@ void LCodeGen::DoBranch(LBranch* instr) {
if (type.IsBoolean()) { if (type.IsBoolean()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
__ CompareRoot(reg, Heap::kTrueValueRootIndex); __ CompareRoot(reg, Heap::kTrueValueRootIndex);
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} else if (type.IsSmi()) { } else if (type.IsSmi()) {
ASSERT(!info()->IsStub()); ASSERT(!info()->IsStub());
__ SmiCompare(reg, Smi::FromInt(0)); __ SmiCompare(reg, Smi::FromInt(0));
EmitBranch(true_block, false_block, not_equal); EmitBranch(instr, not_equal);
} else { } else {
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
// Avoid deopts in the case where we've never executed this path before. // Avoid deopts in the case where we've never executed this path before.
if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
...@@ -1931,27 +1927,27 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -1931,27 +1927,27 @@ void LCodeGen::DoBranch(LBranch* instr) {
if (expected.Contains(ToBooleanStub::UNDEFINED)) { if (expected.Contains(ToBooleanStub::UNDEFINED)) {
// undefined -> false. // undefined -> false.
__ CompareRoot(reg, Heap::kUndefinedValueRootIndex); __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
__ j(equal, false_label); __ j(equal, instr->FalseLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::BOOLEAN)) { if (expected.Contains(ToBooleanStub::BOOLEAN)) {
// true -> true. // true -> true.
__ CompareRoot(reg, Heap::kTrueValueRootIndex); __ CompareRoot(reg, Heap::kTrueValueRootIndex);
__ j(equal, true_label); __ j(equal, instr->TrueLabel(chunk_));
// false -> false. // false -> false.
__ CompareRoot(reg, Heap::kFalseValueRootIndex); __ CompareRoot(reg, Heap::kFalseValueRootIndex);
__ j(equal, false_label); __ j(equal, instr->FalseLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::NULL_TYPE)) { if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
// 'null' -> false. // 'null' -> false.
__ CompareRoot(reg, Heap::kNullValueRootIndex); __ CompareRoot(reg, Heap::kNullValueRootIndex);
__ j(equal, false_label); __ j(equal, instr->FalseLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::SMI)) { if (expected.Contains(ToBooleanStub::SMI)) {
// Smis: 0 -> false, all other -> true. // Smis: 0 -> false, all other -> true.
__ Cmp(reg, Smi::FromInt(0)); __ Cmp(reg, Smi::FromInt(0));
__ j(equal, false_label); __ j(equal, instr->FalseLabel(chunk_));
__ JumpIfSmi(reg, true_label); __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
} else if (expected.NeedsMap()) { } else if (expected.NeedsMap()) {
// If we need a map later and have a Smi -> deopt. // If we need a map later and have a Smi -> deopt.
__ testb(reg, Immediate(kSmiTagMask)); __ testb(reg, Immediate(kSmiTagMask));
...@@ -1966,14 +1962,14 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -1966,14 +1962,14 @@ void LCodeGen::DoBranch(LBranch* instr) {
// Undetectable -> false. // Undetectable -> false.
__ testb(FieldOperand(map, Map::kBitFieldOffset), __ testb(FieldOperand(map, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable)); Immediate(1 << Map::kIsUndetectable));
__ j(not_zero, false_label); __ j(not_zero, instr->FalseLabel(chunk_));
} }
} }
if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
// spec object -> true. // spec object -> true.
__ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
__ j(above_equal, true_label); __ j(above_equal, instr->TrueLabel(chunk_));
} }
if (expected.Contains(ToBooleanStub::STRING)) { if (expected.Contains(ToBooleanStub::STRING)) {
...@@ -1982,8 +1978,8 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -1982,8 +1978,8 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ CmpInstanceType(map, FIRST_NONSTRING_TYPE); __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
__ j(above_equal, &not_string, Label::kNear); __ j(above_equal, &not_string, Label::kNear);
__ cmpq(FieldOperand(reg, String::kLengthOffset), Immediate(0)); __ cmpq(FieldOperand(reg, String::kLengthOffset), Immediate(0));
__ j(not_zero, true_label); __ j(not_zero, instr->TrueLabel(chunk_));
__ jmp(false_label); __ jmp(instr->FalseLabel(chunk_));
__ bind(&not_string); __ bind(&not_string);
} }
...@@ -1994,8 +1990,8 @@ void LCodeGen::DoBranch(LBranch* instr) { ...@@ -1994,8 +1990,8 @@ void LCodeGen::DoBranch(LBranch* instr) {
__ j(not_equal, &not_heap_number, Label::kNear); __ j(not_equal, &not_heap_number, Label::kNear);
__ xorps(xmm0, xmm0); __ xorps(xmm0, xmm0);
__ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset));
__ j(zero, false_label); __ j(zero, instr->FalseLabel(chunk_));
__ jmp(true_label); __ jmp(instr->TrueLabel(chunk_));
__ bind(&not_heap_number); __ bind(&not_heap_number);
} }
...@@ -2049,24 +2045,21 @@ inline Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { ...@@ -2049,24 +2045,21 @@ inline Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
LOperand* left = instr->left(); LOperand* left = instr->left();
LOperand* right = instr->right(); LOperand* right = instr->right();
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
Condition cc = TokenToCondition(instr->op(), instr->is_double()); Condition cc = TokenToCondition(instr->op(), instr->is_double());
if (left->IsConstantOperand() && right->IsConstantOperand()) { if (left->IsConstantOperand() && right->IsConstantOperand()) {
// We can statically evaluate the comparison. // We can statically evaluate the comparison.
double left_val = ToDouble(LConstantOperand::cast(left)); double left_val = ToDouble(LConstantOperand::cast(left));
double right_val = ToDouble(LConstantOperand::cast(right)); double right_val = ToDouble(LConstantOperand::cast(right));
int next_block = int next_block = EvalComparison(instr->op(), left_val, right_val) ?
EvalComparison(instr->op(), left_val, right_val) ? true_block instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_);
: false_block;
EmitGoto(next_block); EmitGoto(next_block);
} else { } else {
if (instr->is_double()) { if (instr->is_double()) {
// Don't base result on EFLAGS when a NaN is involved. Instead // Don't base result on EFLAGS when a NaN is involved. Instead
// jump to the false block. // jump to the false block.
__ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right));
__ j(parity_even, chunk_->GetAssemblyLabel(false_block)); __ j(parity_even, instr->FalseLabel(chunk_));
} else { } else {
int32_t value; int32_t value;
if (right->IsConstantOperand()) { if (right->IsConstantOperand()) {
...@@ -2105,15 +2098,13 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { ...@@ -2105,15 +2098,13 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
} }
} }
} }
EmitBranch(true_block, false_block, cc); EmitBranch(instr, cc);
} }
} }
void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
Register left = ToRegister(instr->left()); Register left = ToRegister(instr->left());
int false_block = chunk_->LookupDestination(instr->false_block_id());
int true_block = chunk_->LookupDestination(instr->true_block_id());
if (instr->right()->IsConstantOperand()) { if (instr->right()->IsConstantOperand()) {
Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right())); Handle<Object> right = ToHandle(LConstantOperand::cast(instr->right()));
...@@ -2122,17 +2113,15 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { ...@@ -2122,17 +2113,15 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
Register right = ToRegister(instr->right()); Register right = ToRegister(instr->right());
__ cmpq(left, right); __ cmpq(left, right);
} }
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) {
Register left = ToRegister(instr->left()); Register left = ToRegister(instr->left());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
__ cmpq(left, Immediate(instr->hydrogen()->right())); __ cmpq(left, Immediate(instr->hydrogen()->right()));
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
...@@ -2164,14 +2153,10 @@ Condition LCodeGen::EmitIsObject(Register input, ...@@ -2164,14 +2153,10 @@ Condition LCodeGen::EmitIsObject(Register input,
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id()); Condition true_cond = EmitIsObject(
int false_block = chunk_->LookupDestination(instr->false_block_id()); reg, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_));
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
Condition true_cond = EmitIsObject(reg, false_label, true_label); EmitBranch(instr, true_cond);
EmitBranch(true_block, false_block, true_cond);
} }
...@@ -2189,20 +2174,13 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { ...@@ -2189,20 +2174,13 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) {
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id()); Condition true_cond = EmitIsString(reg, temp, instr->FalseLabel(chunk_));
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* false_label = chunk_->GetAssemblyLabel(false_block);
Condition true_cond = EmitIsString(reg, temp, false_label);
EmitBranch(true_block, false_block, true_cond); EmitBranch(instr, true_cond);
} }
void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Condition is_smi; Condition is_smi;
if (instr->value()->IsRegister()) { if (instr->value()->IsRegister()) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
...@@ -2211,7 +2189,7 @@ void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { ...@@ -2211,7 +2189,7 @@ void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
Operand input = ToOperand(instr->value()); Operand input = ToOperand(instr->value());
is_smi = masm()->CheckSmi(input); is_smi = masm()->CheckSmi(input);
} }
EmitBranch(true_block, false_block, is_smi); EmitBranch(instr, is_smi);
} }
...@@ -2219,21 +2197,16 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { ...@@ -2219,21 +2197,16 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id()); __ JumpIfSmi(input, instr->FalseLabel(chunk_));
int false_block = chunk_->LookupDestination(instr->false_block_id());
__ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block));
__ movq(temp, FieldOperand(input, HeapObject::kMapOffset)); __ movq(temp, FieldOperand(input, HeapObject::kMapOffset));
__ testb(FieldOperand(temp, Map::kBitFieldOffset), __ testb(FieldOperand(temp, Map::kBitFieldOffset),
Immediate(1 << Map::kIsUndetectable)); Immediate(1 << Map::kIsUndetectable));
EmitBranch(true_block, false_block, not_zero); EmitBranch(instr, not_zero);
} }
void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
Token::Value op = instr->op(); Token::Value op = instr->op();
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op); Handle<Code> ic = CompareIC::GetUninitialized(isolate(), op);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
...@@ -2241,7 +2214,7 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { ...@@ -2241,7 +2214,7 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) {
Condition condition = TokenToCondition(op, false); Condition condition = TokenToCondition(op, false);
__ testq(rax, rax); __ testq(rax, rax);
EmitBranch(true_block, false_block, condition); EmitBranch(instr, condition);
} }
...@@ -2268,15 +2241,10 @@ static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { ...@@ -2268,15 +2241,10 @@ static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) {
void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id()); __ JumpIfSmi(input, instr->FalseLabel(chunk_));
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* false_label = chunk_->GetAssemblyLabel(false_block);
__ JumpIfSmi(input, false_label);
__ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister); __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister);
EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); EmitBranch(instr, BranchCondition(instr->hydrogen()));
} }
...@@ -2296,12 +2264,9 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch( ...@@ -2296,12 +2264,9 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch(
LHasCachedArrayIndexAndBranch* instr) { LHasCachedArrayIndexAndBranch* instr) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
__ testl(FieldOperand(input, String::kHashFieldOffset), __ testl(FieldOperand(input, String::kHashFieldOffset),
Immediate(String::kContainsCachedArrayIndexMask)); Immediate(String::kContainsCachedArrayIndexMask));
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
...@@ -2379,25 +2344,18 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { ...@@ -2379,25 +2344,18 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
Register temp2 = ToRegister(instr->temp2()); Register temp2 = ToRegister(instr->temp2());
Handle<String> class_name = instr->hydrogen()->class_name(); Handle<String> class_name = instr->hydrogen()->class_name();
int true_block = chunk_->LookupDestination(instr->true_block_id()); EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_),
int false_block = chunk_->LookupDestination(instr->false_block_id()); class_name, input, temp, temp2);
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2);
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
Register reg = ToRegister(instr->value()); Register reg = ToRegister(instr->value());
int true_block = instr->true_block_id();
int false_block = instr->false_block_id();
__ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
...@@ -5347,15 +5305,12 @@ void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { ...@@ -5347,15 +5305,12 @@ void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) {
Register input = ToRegister(instr->value()); Register input = ToRegister(instr->value());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
Label* true_label = chunk_->GetAssemblyLabel(true_block);
Label* false_label = chunk_->GetAssemblyLabel(false_block);
Condition final_branch_condition = Condition final_branch_condition =
EmitTypeofIs(true_label, false_label, input, instr->type_literal()); EmitTypeofIs(instr->TrueLabel(chunk_),
instr->FalseLabel(chunk_), input, instr->type_literal());
if (final_branch_condition != no_condition) { if (final_branch_condition != no_condition) {
EmitBranch(true_block, false_block, final_branch_condition); EmitBranch(instr, final_branch_condition);
} }
} }
...@@ -5438,11 +5393,9 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, ...@@ -5438,11 +5393,9 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
Register temp = ToRegister(instr->temp()); Register temp = ToRegister(instr->temp());
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
EmitIsConstructCall(temp); EmitIsConstructCall(temp);
EmitBranch(true_block, false_block, equal); EmitBranch(instr, equal);
} }
......
...@@ -79,7 +79,6 @@ class LCodeGen BASE_EMBEDDED { ...@@ -79,7 +79,6 @@ class LCodeGen BASE_EMBEDDED {
Heap* heap() const { return isolate()->heap(); } Heap* heap() const { return isolate()->heap(); }
Zone* zone() const { return zone_; } Zone* zone() const { return zone_; }
// TODO(svenpanne) Use this consistently.
int LookupDestination(int block_id) const { int LookupDestination(int block_id) const {
return chunk()->LookupDestination(block_id); return chunk()->LookupDestination(block_id);
} }
...@@ -283,7 +282,8 @@ class LCodeGen BASE_EMBEDDED { ...@@ -283,7 +282,8 @@ class LCodeGen BASE_EMBEDDED {
static Condition TokenToCondition(Token::Value op, bool is_unsigned); static Condition TokenToCondition(Token::Value op, bool is_unsigned);
void EmitGoto(int block); void EmitGoto(int block);
void EmitBranch(int left_block, int right_block, Condition cc); template<class InstrType>
void EmitBranch(InstrType instr, Condition cc);
void EmitNumberUntagD( void EmitNumberUntagD(
Register input, Register input,
XMMRegister result, XMMRegister result,
......
...@@ -490,17 +490,44 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> { ...@@ -490,17 +490,44 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> {
template<int I, int T> template<int I, int T>
class LControlInstruction: public LTemplateInstruction<0, I, T> { class LControlInstruction: public LTemplateInstruction<0, I, T> {
public: public:
LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
virtual bool IsControl() const { return true; } virtual bool IsControl() const { return true; }
int SuccessorCount() { return hydrogen()->SuccessorCount(); } int SuccessorCount() { return hydrogen()->SuccessorCount(); }
HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); }
int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); } int TrueDestination(LChunk* chunk) {
return chunk->LookupDestination(true_block_id());
}
int FalseDestination(LChunk* chunk) {
return chunk->LookupDestination(false_block_id());
}
Label* TrueLabel(LChunk* chunk) {
if (true_label_ == NULL) {
true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
}
return true_label_;
}
Label* FalseLabel(LChunk* chunk) {
if (false_label_ == NULL) {
false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
}
return false_label_;
}
protected:
int true_block_id() { return SuccessorAt(0)->block_id(); }
int false_block_id() { return SuccessorAt(1)->block_id(); }
private: private:
HControlInstruction* hydrogen() { HControlInstruction* hydrogen() {
return HControlInstruction::cast(this->hydrogen_value()); return HControlInstruction::cast(this->hydrogen_value());
} }
Label* false_label_;
Label* true_label_;
}; };
...@@ -1191,7 +1218,7 @@ class LDebugBreak: public LTemplateInstruction<0, 0, 0> { ...@@ -1191,7 +1218,7 @@ class LDebugBreak: public LTemplateInstruction<0, 0, 0> {
}; };
class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> { class LCmpMapAndBranch: public LControlInstruction<1, 0> {
public: public:
explicit LCmpMapAndBranch(LOperand* value) { explicit LCmpMapAndBranch(LOperand* value) {
inputs_[0] = value; inputs_[0] = value;
...@@ -1202,15 +1229,7 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> { ...@@ -1202,15 +1229,7 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> {
DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareMap) DECLARE_HYDROGEN_ACCESSOR(CompareMap)
virtual bool IsControl() const { return true; }
Handle<Map> map() const { return hydrogen()->map(); } Handle<Map> map() const { return hydrogen()->map(); }
int true_block_id() const {
return hydrogen()->FirstSuccessor()->block_id();
}
int false_block_id() const {
return hydrogen()->SecondSuccessor()->block_id();
}
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment