| Index: src/x64/codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/codegen-x64.cc (revision 2320)
|
| +++ src/x64/codegen-x64.cc (working copy)
|
| @@ -5771,6 +5771,62 @@
|
|
|
|
|
| void InstanceofStub::Generate(MacroAssembler* masm) {
|
| + // Implements "value instanceof function" operator.
|
| + // Expected input state:
|
| + // rsp[0] : return address
|
| + // rsp[1] : function pointer
|
| + // rsp[2] : value
|
| +
|
| + // Get the object - go slow case if it's a smi.
|
| + Label slow;
|
| + __ movq(rax, Operand(rsp, 2 * kPointerSize));
|
| + __ testl(rax, Immediate(kSmiTagMask));
|
| + __ j(zero, &slow);
|
| +
|
| + // Check that the left hand is a JS object. Leave its map in rax.
|
| + __ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rax);
|
| + __ j(below, &slow);
|
| + __ CmpInstanceType(rax, LAST_JS_OBJECT_TYPE);
|
| + __ j(above, &slow);
|
| +
|
| + // Get the prototype of the function.
|
| + __ movq(rdx, Operand(rsp, 1 * kPointerSize));
|
| + __ TryGetFunctionPrototype(rdx, rbx, &slow);
|
| +
|
| + // Check that the function prototype is a JS object.
|
| + __ testl(rbx, Immediate(kSmiTagMask));
|
| + __ j(zero, &slow);
|
| + __ CmpObjectType(rbx, FIRST_JS_OBJECT_TYPE, kScratchRegister);
|
| + __ j(below, &slow);
|
| + __ CmpInstanceType(kScratchRegister, LAST_JS_OBJECT_TYPE);
|
| + __ j(above, &slow);
|
| +
|
| + // Register mapping: rax is object map and rbx is function prototype.
|
| + __ movq(rcx, FieldOperand(rax, Map::kPrototypeOffset));
|
| +
|
| + // Loop through the prototype chain looking for the function prototype.
|
| + Label loop, is_instance, is_not_instance;
|
| + __ Move(kScratchRegister, Factory::null_value());
|
| + __ bind(&loop);
|
| + __ cmpq(rcx, rbx);
|
| + __ j(equal, &is_instance);
|
| + __ cmpq(rcx, kScratchRegister);
|
| + __ j(equal, &is_not_instance);
|
| + __ movq(rcx, FieldOperand(rcx, HeapObject::kMapOffset));
|
| + __ movq(rcx, FieldOperand(rcx, Map::kPrototypeOffset));
|
| + __ jmp(&loop);
|
| +
|
| + __ bind(&is_instance);
|
| + __ xor_(rax, rax);
|
| + __ ret(2 * kPointerSize);
|
| +
|
| + __ bind(&is_not_instance);
|
| + __ movq(rax, Immediate(Smi::FromInt(1)));
|
| + __ ret(2 * kPointerSize);
|
| +
|
| + // Slow-case: Go through the JavaScript implementation.
|
| + __ bind(&slow);
|
| + __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
|
| }
|
|
|
|
|
|
|