Slightly improved register assignment for %_IsObject on IA32 and ARM.

The new approach uses one temp register instead of two on IA32. The ARM
instructions are modified so the input can be UseAtStart again.
Review URL: http://codereview.chromium.org/7274025

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8451 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e859416b
......@@ -1098,7 +1098,7 @@ LInstruction* LChunkBuilder::DoTest(HTest* instr) {
HIsObject* compare = HIsObject::cast(v);
ASSERT(compare->value()->representation().IsTagged());
LOperand* temp = TempRegister();
return new LIsObjectAndBranch(UseRegister(compare->value()), temp);
return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp);
} else if (v->IsCompareObjectEq()) {
HCompareObjectEq* compare = HCompareObjectEq::cast(v);
return new LCmpObjectEqAndBranch(UseRegisterAtStart(compare->left()),
......
......@@ -705,7 +705,7 @@ class LIsNullAndBranch: public LControlInstruction<1, 0> {
};
class LIsObject: public LTemplateInstruction<1, 1, 1> {
class LIsObject: public LTemplateInstruction<1, 1, 0> {
public:
explicit LIsObject(LOperand* value) {
inputs_[0] = value;
......@@ -715,7 +715,7 @@ class LIsObject: public LTemplateInstruction<1, 1, 1> {
};
class LIsObjectAndBranch: public LControlInstruction<1, 2> {
class LIsObjectAndBranch: public LControlInstruction<1, 1> {
public:
LIsObjectAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
......
......@@ -1796,13 +1796,13 @@ void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
Condition LCodeGen::EmitIsObject(Register input,
Register temp1,
Register temp2,
Label* is_not_object,
Label* is_object) {
Register temp2 = scratch0();
__ JumpIfSmi(input, is_not_object);
__ LoadRoot(temp1, Heap::kNullValueRootIndex);
__ cmp(input, temp1);
__ LoadRoot(temp2, Heap::kNullValueRootIndex);
__ cmp(input, temp2);
__ b(eq, is_object);
// Load map.
......@@ -1824,10 +1824,9 @@ Condition LCodeGen::EmitIsObject(Register input,
void LCodeGen::DoIsObject(LIsObject* instr) {
Register reg = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
Register temp = scratch0();
Label is_false, is_true, done;
Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true);
Condition true_cond = EmitIsObject(reg, result, &is_false, &is_true);
__ b(true_cond, &is_true);
__ bind(&is_false);
......@@ -1852,7 +1851,7 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
Label* false_label = chunk_->GetAssemblyLabel(false_block);
Condition true_cond =
EmitIsObject(reg, temp1, temp2, false_label, true_label);
EmitIsObject(reg, temp1, false_label, true_label);
EmitBranch(true_block, false_block, true_cond);
}
......
......@@ -280,7 +280,6 @@ class LCodeGen BASE_EMBEDDED {
// true and false label should be made, to optimize fallthrough.
Condition EmitIsObject(Register input,
Register temp1,
Register temp2,
Label* is_not_object,
Label* is_object);
......
......@@ -1637,13 +1637,8 @@ void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
Condition LCodeGen::EmitIsObject(Register input,
Register temp1,
Register temp2,
Label* is_not_object,
Label* is_object) {
ASSERT(!input.is(temp1));
ASSERT(!input.is(temp2));
ASSERT(!temp1.is(temp2));
__ JumpIfSmi(input, is_not_object);
__ cmp(input, isolate()->factory()->null_value());
......@@ -1651,14 +1646,14 @@ Condition LCodeGen::EmitIsObject(Register input,
__ mov(temp1, FieldOperand(input, HeapObject::kMapOffset));
// Undetectable objects behave like undefined.
__ movzx_b(temp2, FieldOperand(temp1, Map::kBitFieldOffset));
__ test(temp2, Immediate(1 << Map::kIsUndetectable));
__ test_b(FieldOperand(temp1, Map::kBitFieldOffset),
1 << Map::kIsUndetectable);
__ j(not_zero, is_not_object);
__ movzx_b(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset));
__ cmp(temp2, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
__ movzx_b(temp1, FieldOperand(temp1, Map::kInstanceTypeOffset));
__ cmp(temp1, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE);
__ j(below, is_not_object);
__ cmp(temp2, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
__ cmp(temp1, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
return below_equal;
}
......@@ -1666,10 +1661,9 @@ Condition LCodeGen::EmitIsObject(Register input,
void LCodeGen::DoIsObject(LIsObject* instr) {
Register reg = ToRegister(instr->InputAt(0));
Register result = ToRegister(instr->result());
Register temp = ToRegister(instr->TempAt(0));
Label is_false, is_true, done;
Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true);
Condition true_cond = EmitIsObject(reg, result, &is_false, &is_true);
__ j(true_cond, &is_true);
__ bind(&is_false);
......@@ -1686,14 +1680,13 @@ void LCodeGen::DoIsObject(LIsObject* instr) {
void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
Register reg = ToRegister(instr->InputAt(0));
Register temp = ToRegister(instr->TempAt(0));
Register temp2 = ToRegister(instr->TempAt(1));
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 = EmitIsObject(reg, temp, temp2, false_label, true_label);
Condition true_cond = EmitIsObject(reg, temp, false_label, true_label);
EmitBranch(true_block, false_block, true_cond);
}
......
......@@ -277,7 +277,6 @@ class LCodeGen BASE_EMBEDDED {
// true and false label should be made, to optimize fallthrough.
Condition EmitIsObject(Register input,
Register temp1,
Register temp2,
Label* is_not_object,
Label* is_object);
......
......@@ -1096,11 +1096,8 @@ LInstruction* LChunkBuilder::DoTest(HTest* instr) {
} else if (v->IsIsObject()) {
HIsObject* compare = HIsObject::cast(v);
ASSERT(compare->value()->representation().IsTagged());
LOperand* temp1 = TempRegister();
LOperand* temp2 = TempRegister();
return new LIsObjectAndBranch(UseRegister(compare->value()),
temp1,
temp2);
LOperand* temp = TempRegister();
return new LIsObjectAndBranch(UseRegister(compare->value()), temp);
} else if (v->IsCompareObjectEq()) {
HCompareObjectEq* compare = HCompareObjectEq::cast(v);
return new LCmpObjectEqAndBranch(UseRegisterAtStart(compare->left()),
......@@ -1546,7 +1543,7 @@ LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) {
ASSERT(instr->value()->representation().IsTagged());
LOperand* value = UseRegister(instr->value());
return DefineAsRegister(new LIsObject(value, TempRegister()));
return DefineAsRegister(new LIsObject(value));
}
......
......@@ -692,23 +692,21 @@ class LIsNullAndBranch: public LControlInstruction<1, 1> {
};
class LIsObject: public LTemplateInstruction<1, 1, 1> {
class LIsObject: public LTemplateInstruction<1, 1, 0> {
public:
LIsObject(LOperand* value, LOperand* temp) {
explicit LIsObject(LOperand* value) {
inputs_[0] = value;
temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object")
};
class LIsObjectAndBranch: public LControlInstruction<1, 2> {
class LIsObjectAndBranch: public LControlInstruction<1, 1> {
public:
LIsObjectAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
LIsObjectAndBranch(LOperand* value, LOperand* temp) {
inputs_[0] = value;
temps_[0] = temp;
temps_[1] = temp2;
}
DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch")
......
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