From 8986022133432369438e4d9ab7a19790114996ec Mon Sep 17 00:00:00 2001 From: "whesse@chromium.org" Date: Wed, 16 Feb 2011 15:15:20 +0000 Subject: [PATCH] X64 Crankshaft: Implement InstanceOf and InstanceOfKnownGlobal Review URL: http://codereview.chromium.org/6529024 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6824 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/x64/code-stubs-x64.cc | 8 +++-- src/x64/lithium-codegen-x64.cc | 77 ++++++++++++++++++++++++++++++++++++++---- src/x64/lithium-codegen-x64.h | 3 +- src/x64/lithium-x64.cc | 17 ++++++---- src/x64/lithium-x64.h | 5 ++- 5 files changed, 90 insertions(+), 20 deletions(-) diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 0cfe665..d160aaf 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -3461,6 +3461,9 @@ void InstanceofStub::Generate(MacroAssembler* masm) { // is and instance of the function and anything else to // indicate that the value is not an instance. + // None of the flags are supported on X64. + ASSERT(flags_ == kNoFlags); + // Get the object - go slow case if it's a smi. Label slow; __ movq(rax, Operand(rsp, 2 * kPointerSize)); @@ -3536,10 +3539,11 @@ void InstanceofStub::Generate(MacroAssembler* masm) { } -Register InstanceofStub::left() { return rax; } +// Passing arguments in registers is not supported. +Register InstanceofStub::left() { return no_reg; } -Register InstanceofStub::right() { return rdx; } +Register InstanceofStub::right() { return no_reg; } int CompareStub::MinorKey() { diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 48d149e..cca52f4 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -1599,7 +1599,18 @@ void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { void LCodeGen::DoInstanceOf(LInstanceOf* instr) { - Abort("Unimplemented: %s", "DoInstanceOf"); + InstanceofStub stub(InstanceofStub::kNoFlags); + __ push(ToRegister(instr->InputAt(0))); + __ push(ToRegister(instr->InputAt(1))); + CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); + NearLabel true_value, done; + __ testq(rax, rax); + __ j(zero, &true_value); + __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); + __ jmp(&done); + __ bind(&true_value); + __ LoadRoot(ToRegister(instr->result()), Heap::kTrueValueRootIndex); + __ bind(&done); } @@ -1607,7 +1618,9 @@ void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { int true_block = chunk_->LookupDestination(instr->true_block_id()); int false_block = chunk_->LookupDestination(instr->false_block_id()); - InstanceofStub stub(InstanceofStub::kArgsInRegisters); + InstanceofStub stub(InstanceofStub::kNoFlags); + __ push(ToRegister(instr->InputAt(0))); + __ push(ToRegister(instr->InputAt(1))); CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); __ testq(rax, rax); EmitBranch(true_block, false_block, zero); @@ -1615,13 +1628,65 @@ void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { - Abort("Unimplemented: %s", "DoInstanceOfKnowGLobal"); + class DeferredInstanceOfKnownGlobal: public LDeferredCode { + public: + DeferredInstanceOfKnownGlobal(LCodeGen* codegen, + LInstanceOfKnownGlobal* instr) + : LDeferredCode(codegen), instr_(instr) { } + virtual void Generate() { + codegen()->DoDeferredLInstanceOfKnownGlobal(instr_); + } + + private: + LInstanceOfKnownGlobal* instr_; + }; + + + DeferredInstanceOfKnownGlobal* deferred; + deferred = new DeferredInstanceOfKnownGlobal(this, instr); + + Label false_result; + Register object = ToRegister(instr->InputAt(0)); + + // A Smi is not an instance of anything. + __ JumpIfSmi(object, &false_result); + + // Null is not an instance of anything. + __ CompareRoot(object, Heap::kNullValueRootIndex); + __ j(equal, &false_result); + + // String values are not instances of anything. + __ JumpIfNotString(object, kScratchRegister, deferred->entry()); + + __ bind(&false_result); + __ LoadRoot(ToRegister(instr->result()), Heap::kFalseValueRootIndex); + + __ bind(deferred->exit()); } -void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, - Label* map_check) { - Abort("Unimplemented: %s", "DoDeferredLInstanceOfKnownGlobakl"); +void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { + __ PushSafepointRegisters(); + + InstanceofStub stub(InstanceofStub::kNoFlags); + + __ push(ToRegister(instr->InputAt(0))); + __ Push(instr->function()); + __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); + __ Call(stub.GetCode(), RelocInfo::CODE_TARGET); + RecordSafepointWithRegisters( + instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); + __ movq(kScratchRegister, rax); + __ PopSafepointRegisters(); + __ testq(kScratchRegister, kScratchRegister); + Label load_false; + Label done; + __ j(not_zero, &load_false); + __ LoadRoot(rax, Heap::kTrueValueRootIndex); + __ jmp(&done); + __ bind(&load_false); + __ LoadRoot(rax, Heap::kFalseValueRootIndex); + __ bind(&done); } diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h index 6f8f06e..57db0ed 100644 --- a/src/x64/lithium-codegen-x64.h +++ b/src/x64/lithium-codegen-x64.h @@ -90,8 +90,7 @@ class LCodeGen BASE_EMBEDDED { void DoDeferredTaggedToI(LTaggedToI* instr); void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr); void DoDeferredStackCheck(LGoto* instr); - void DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, - Label* map_check); + void DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr); // Parallel move support. void DoParallelMove(LParallelMove* move); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 5b14639..2b950d4 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1081,9 +1081,8 @@ LInstruction* LChunkBuilder::DoTest(HTest* instr) { } else if (v->IsInstanceOf()) { HInstanceOf* instance_of = HInstanceOf::cast(v); LInstanceOfAndBranch* result = - new LInstanceOfAndBranch( - UseFixed(instance_of->left(), InstanceofStub::left()), - UseFixed(instance_of->right(), InstanceofStub::right())); + new LInstanceOfAndBranch(UseFixed(instance_of->left(), rax), + UseFixed(instance_of->right(), rdx)); return MarkAsCall(result, instr); } else if (v->IsTypeofIs()) { HTypeofIs* typeof_is = HTypeofIs::cast(v); @@ -1124,15 +1123,19 @@ LInstruction* LChunkBuilder::DoArgumentsElements(HArgumentsElements* elems) { LInstruction* LChunkBuilder::DoInstanceOf(HInstanceOf* instr) { - Abort("Unimplemented: %s", "DoInstanceOf"); - return NULL; + LOperand* left = UseFixed(instr->left(), rax); + LOperand* right = UseFixed(instr->right(), rdx); + LInstanceOf* result = new LInstanceOf(left, right); + return MarkAsCall(DefineFixed(result, rax), instr); } LInstruction* LChunkBuilder::DoInstanceOfKnownGlobal( HInstanceOfKnownGlobal* instr) { - Abort("Unimplemented: %s", "DoInstanceOfKnownGlobal"); - return NULL; + LInstanceOfKnownGlobal* result = + new LInstanceOfKnownGlobal(UseRegisterAtStart(instr->value())); + MarkAsSaveDoubles(result); + return AssignEnvironment(AssignPointerMap(DefineFixed(result, rax))); } diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index 80963d0..237a61a 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -831,11 +831,10 @@ class LInstanceOfAndBranch: public LControlInstruction<2, 0> { }; -class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> { +class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 0> { public: - LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) { + explicit LInstanceOfKnownGlobal(LOperand* value) { inputs_[0] = value; - temps_[0] = temp; } DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal, -- 2.7.4