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
This commit is contained in:
fschneider@chromium.org 2011-06-28 14:21:55 +00:00
parent e859416b9f
commit 2760bd2927
8 changed files with 22 additions and 37 deletions

View File

@ -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()),

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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));
}

View File

@ -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")