Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(383)

Unified Diff: src/arm64/lithium-codegen-arm64.cc

Issue 1304633002: Correctify instanceof and make it optimizable. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Add MIPS/MIPS64 ports. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm64/lithium-codegen-arm64.h ('k') | src/arm64/macro-assembler-arm64.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm64/lithium-codegen-arm64.cc
diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc
index 3dff64cbe84ce91571d901dbdfcab2f4cc1c81a7..728f074a8a0b0dcb5a80c392c538ed37e60f0c0f 100644
--- a/src/arm64/lithium-codegen-arm64.cc
+++ b/src/arm64/lithium-codegen-arm64.cc
@@ -3007,135 +3007,39 @@ void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
DCHECK(ToRegister(instr->context()).is(cp));
- // Assert that the arguments are in the registers expected by InstanceofStub.
- DCHECK(ToRegister(instr->left()).Is(InstanceofStub::left()));
- DCHECK(ToRegister(instr->right()).Is(InstanceofStub::right()));
-
- InstanceofStub stub(isolate(), InstanceofStub::kArgsInRegisters);
+ DCHECK(ToRegister(instr->left()).is(InstanceOfDescriptor::LeftRegister()));
+ DCHECK(ToRegister(instr->right()).is(InstanceOfDescriptor::RightRegister()));
+ DCHECK(ToRegister(instr->result()).is(x0));
+ InstanceOfStub stub(isolate());
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
-
- // InstanceofStub returns a result in x0:
- // 0 => not an instance
- // smi 1 => instance.
- __ Cmp(x0, 0);
- __ LoadTrueFalseRoots(x0, x1);
- __ Csel(x0, x0, x1, eq);
}
-void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
- class DeferredInstanceOfKnownGlobal: public LDeferredCode {
- public:
- DeferredInstanceOfKnownGlobal(LCodeGen* codegen,
- LInstanceOfKnownGlobal* instr)
- : LDeferredCode(codegen), instr_(instr) { }
- virtual void Generate() {
- codegen()->DoDeferredInstanceOfKnownGlobal(instr_);
- }
- virtual LInstruction* instr() { return instr_; }
- private:
- LInstanceOfKnownGlobal* instr_;
- };
-
- DeferredInstanceOfKnownGlobal* deferred =
- new(zone()) DeferredInstanceOfKnownGlobal(this, instr);
-
- Label map_check, return_false, cache_miss, done;
- Register object = ToRegister(instr->value());
- Register result = ToRegister(instr->result());
- // x4 is expected in the associated deferred code and stub.
- Register map_check_site = x4;
- Register map = x5;
-
- // This instruction is marked as call. We can clobber any register.
- DCHECK(instr->IsMarkedAsCall());
-
- // We must take into account that object is in x11.
- DCHECK(object.Is(x11));
- Register scratch = x10;
-
- // A Smi is not instance of anything.
- __ JumpIfSmi(object, &return_false);
+void LCodeGen::DoHasInPrototypeChainAndBranch(
+ LHasInPrototypeChainAndBranch* instr) {
+ Register const object = ToRegister(instr->object());
+ Register const object_map = ToRegister(instr->scratch());
+ Register const object_prototype = object_map;
+ Register const prototype = ToRegister(instr->prototype());
- // This is the inlined call site instanceof cache. The two occurences of the
- // hole value will be patched to the last map/result pair generated by the
- // instanceof stub.
- __ Ldr(map, FieldMemOperand(object, HeapObject::kMapOffset));
- {
- // Below we use Factory::the_hole_value() on purpose instead of loading from
- // the root array to force relocation and later be able to patch with a
- // custom value.
- InstructionAccurateScope scope(masm(), 5);
- __ bind(&map_check);
- // Will be patched with the cached map.
- Handle<Cell> cell = factory()->NewCell(factory()->the_hole_value());
- __ ldr(scratch, Immediate(cell));
- __ ldr(scratch, FieldMemOperand(scratch, Cell::kValueOffset));
- __ cmp(map, scratch);
- __ b(&cache_miss, ne);
- // The address of this instruction is computed relative to the map check
- // above, so check the size of the code generated.
- DCHECK(masm()->InstructionsGeneratedSince(&map_check) == 4);
- // Will be patched with the cached result.
- __ ldr(result, Immediate(factory()->the_hole_value()));
+ // The {object} must be a spec object. It's sufficient to know that {object}
+ // is not a smi, since all other non-spec objects have {null} prototypes and
+ // will be ruled out below.
+ if (instr->hydrogen()->ObjectNeedsSmiCheck()) {
+ __ JumpIfSmi(object, instr->FalseLabel(chunk_));
}
- __ B(&done);
-
- // The inlined call site cache did not match.
- // Check null and string before calling the deferred code.
- __ Bind(&cache_miss);
- // Compute the address of the map check. It must not be clobbered until the
- // InstanceOfStub has used it.
- __ Adr(map_check_site, &map_check);
- // Null is not instance of anything.
- __ JumpIfRoot(object, Heap::kNullValueRootIndex, &return_false);
-
- // String values are not instances of anything.
- // Return false if the object is a string. Otherwise, jump to the deferred
- // code.
- // Note that we can't jump directly to deferred code from
- // IsObjectJSStringType, because it uses tbz for the jump and the deferred
- // code can be out of range.
- __ IsObjectJSStringType(object, scratch, NULL, &return_false);
- __ B(deferred->entry());
-
- __ Bind(&return_false);
- __ LoadRoot(result, Heap::kFalseValueRootIndex);
-
- // Here result is either true or false.
- __ Bind(deferred->exit());
- __ Bind(&done);
-}
-
-void LCodeGen::DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) {
- Register result = ToRegister(instr->result());
- DCHECK(result.Is(x0)); // InstanceofStub returns its result in x0.
- InstanceofStub::Flags flags = InstanceofStub::kNoFlags;
- flags = static_cast<InstanceofStub::Flags>(
- flags | InstanceofStub::kArgsInRegisters);
- flags = static_cast<InstanceofStub::Flags>(
- flags | InstanceofStub::kReturnTrueFalseObject);
- flags = static_cast<InstanceofStub::Flags>(
- flags | InstanceofStub::kCallSiteInlineCheck);
-
- PushSafepointRegistersScope scope(this);
- LoadContextFromDeferred(instr->context());
-
- // Prepare InstanceofStub arguments.
- DCHECK(ToRegister(instr->value()).Is(InstanceofStub::left()));
- __ LoadObject(InstanceofStub::right(), instr->function());
-
- InstanceofStub stub(isolate(), flags);
- CallCodeGeneric(stub.GetCode(),
- RelocInfo::CODE_TARGET,
- instr,
- RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
- LEnvironment* env = instr->GetDeferredLazyDeoptimizationEnvironment();
- safepoints_.RecordLazyDeoptimizationIndex(env->deoptimization_index());
-
- // Put the result value into the result register slot.
- __ StoreToSafepointRegisterSlot(result, result);
+ // Loop through the {object}s prototype chain looking for the {prototype}.
+ __ Ldr(object_map, FieldMemOperand(object, HeapObject::kMapOffset));
+ Label loop;
+ __ Bind(&loop);
+ __ Ldr(object_prototype, FieldMemOperand(object_map, Map::kPrototypeOffset));
+ __ Cmp(object_prototype, prototype);
+ __ B(eq, instr->TrueLabel(chunk_));
+ __ CompareRoot(object_prototype, Heap::kNullValueRootIndex);
+ __ B(eq, instr->FalseLabel(chunk_));
+ __ Ldr(object_map, FieldMemOperand(object_prototype, HeapObject::kMapOffset));
+ __ B(&loop);
}
« no previous file with comments | « src/arm64/lithium-codegen-arm64.h ('k') | src/arm64/macro-assembler-arm64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698