Chromium Code Reviews| Index: src/x64/lithium-codegen-x64.cc |
| =================================================================== |
| --- src/x64/lithium-codegen-x64.cc (revision 6814) |
| +++ src/x64/lithium-codegen-x64.cc (working copy) |
| @@ -1599,7 +1599,18 @@ |
| 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); |
| + __ testq(rax, rax); |
| + NearLabel true_value, done; |
|
Rico
2011/02/16 14:43:25
Maybe put labels above the testq minimize diff to
William Hesse
2011/02/16 15:15:06
Done.
|
| + __ 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 @@ |
| 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,67 @@ |
| 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); |
| + |
| + // Here result has either true or false. Deferred code also produces true or |
|
Rico
2011/02/16 14:43:25
it never has true here does it?
William Hesse
2011/02/16 15:15:06
Comment deleted.
On 2011/02/16 14:43:25, Rico wro
|
| + // false object. |
| + __ 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); |
| } |