From: ager@chromium.org Date: Mon, 24 Jan 2011 12:28:38 +0000 (+0000) Subject: ARM: Implement DoIsObject and DoIsObjectAndBranch in the lithium code generator. X-Git-Tag: upstream/4.7.83~20474 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=883a56717dc29f5fde0c82f2a09359fdbd8b0109;p=platform%2Fupstream%2Fv8.git ARM: Implement DoIsObject and DoIsObjectAndBranch in the lithium code generator. BUG=none TEST=none Review URL: http://codereview.chromium.org/6308012 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6438 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index c484e39..912072b 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -1018,11 +1018,8 @@ LInstruction* LChunkBuilder::DoTest(HTest* instr) { HIsObject* compare = HIsObject::cast(v); ASSERT(compare->value()->representation().IsTagged()); - LOperand* temp1 = TempRegister(); - LOperand* temp2 = TempRegister(); - return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), - temp1, - temp2); + LOperand* temp = TempRegister(); + return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp); } else if (v->IsCompareJSObjectEq()) { HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), @@ -1404,7 +1401,7 @@ LInstruction* LChunkBuilder::DoIsObject(HIsObject* instr) { ASSERT(instr->value()->representation().IsTagged()); LOperand* value = UseRegisterAtStart(instr->value()); - return DefineAsRegister(new LIsObject(value, TempRegister())); + return DefineAsRegister(new LIsObject(value)); } diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 81a0266..eb90b8c 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -734,9 +734,8 @@ class LIsNullAndBranch: public LControlInstruction<1, 0> { class LIsObject: public LTemplateInstruction<1, 1, 1> { public: - LIsObject(LOperand* value, LOperand* temp) { + explicit LIsObject(LOperand* value) { inputs_[0] = value; - temps_[0] = temp; } DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object") @@ -745,10 +744,9 @@ class LIsObject: public LTemplateInstruction<1, 1, 1> { class LIsObjectAndBranch: public LControlInstruction<1, 2> { 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") diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 6abb830..f34724c 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -1730,18 +1730,62 @@ Condition LCodeGen::EmitIsObject(Register input, Register temp2, Label* is_not_object, Label* is_object) { - Abort("EmitIsObject unimplemented."); - return ne; + __ BranchOnSmi(input, is_not_object); + + __ LoadRoot(temp1, Heap::kNullValueRootIndex); + __ cmp(input, temp1); + __ b(eq, is_object); + + // Load map. + __ ldr(temp1, FieldMemOperand(input, HeapObject::kMapOffset)); + // Undetectable objects behave like undefined. + __ ldrb(temp2, FieldMemOperand(temp1, Map::kBitFieldOffset)); + __ tst(temp2, Operand(1 << Map::kIsUndetectable)); + __ b(ne, is_not_object); + + // Load instance type and check that it is in object type range. + __ ldrb(temp2, FieldMemOperand(temp1, Map::kInstanceTypeOffset)); + __ cmp(temp2, Operand(FIRST_JS_OBJECT_TYPE)); + __ b(lt, is_not_object); + __ cmp(temp2, Operand(LAST_JS_OBJECT_TYPE)); + return le; } void LCodeGen::DoIsObject(LIsObject* instr) { - Abort("DoIsObject unimplemented."); + 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); + __ b(true_cond, &is_true); + + __ bind(&is_false); + __ LoadRoot(result, Heap::kFalseValueRootIndex); + __ b(&done); + + __ bind(&is_true); + __ LoadRoot(result, Heap::kTrueValueRootIndex); + + __ bind(&done); } void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { - Abort("DoIsObjectAndBranch unimplemented."); + Register reg = ToRegister(instr->InputAt(0)); + Register temp1 = ToRegister(instr->TempAt(0)); + Register temp2 = scratch0(); + + 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, temp1, temp2, false_label, true_label); + + EmitBranch(true_block, false_block, true_cond); }