OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3763 // rsp[2] : value | 3763 // rsp[2] : value |
3764 // Expected input state with an inline one-element cache: | 3764 // Expected input state with an inline one-element cache: |
3765 // rsp[0] : return address | 3765 // rsp[0] : return address |
3766 // rsp[1] : offset from return address to location of inline cache | 3766 // rsp[1] : offset from return address to location of inline cache |
3767 // rsp[2] : function pointer | 3767 // rsp[2] : function pointer |
3768 // rsp[3] : value | 3768 // rsp[3] : value |
3769 // Returns a bitwise zero to indicate that the value | 3769 // Returns a bitwise zero to indicate that the value |
3770 // is and instance of the function and anything else to | 3770 // is and instance of the function and anything else to |
3771 // indicate that the value is not an instance. | 3771 // indicate that the value is not an instance. |
3772 | 3772 |
3773 static const int kOffsetToMapCheckValue = 5; | 3773 static const int kOffsetToMapCheckValue = 2; |
3774 static const int kOffsetToResultValue = 21; | 3774 static const int kOffsetToResultValue = 18; |
3775 // The last 4 bytes of the instruction sequence | 3775 // The last 4 bytes of the instruction sequence |
3776 // movq(rax, FieldOperand(rdi, HeapObject::kMapOffset) | 3776 // movq(rdi, FieldOperand(rax, HeapObject::kMapOffset)) |
3777 // Move(kScratchRegister, FACTORY->the_hole_value()) | 3777 // Move(kScratchRegister, FACTORY->the_hole_value()) |
3778 // in front of the hole value address. | 3778 // in front of the hole value address. |
3779 static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78; | 3779 static const unsigned int kWordBeforeMapCheckValue = 0xBA49FF78; |
3780 // The last 4 bytes of the instruction sequence | 3780 // The last 4 bytes of the instruction sequence |
3781 // __ j(not_equal, &cache_miss); | 3781 // __ j(not_equal, &cache_miss); |
3782 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); | 3782 // __ LoadRoot(ToRegister(instr->result()), Heap::kTheHoleValueRootIndex); |
3783 // before the offset of the hole value in the root array. | 3783 // before the offset of the hole value in the root array. |
3784 static const unsigned int kWordBeforeResultValue = 0x458B4909; | 3784 static const unsigned int kWordBeforeResultValue = 0x458B4909; |
3785 // Only the inline check flag is supported on X64. | 3785 // Only the inline check flag is supported on X64. |
3786 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck()); | 3786 ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck()); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3832 if (!HasCallSiteInlineCheck()) { | 3832 if (!HasCallSiteInlineCheck()) { |
3833 __ StoreRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); | 3833 __ StoreRoot(rdx, Heap::kInstanceofCacheFunctionRootIndex); |
3834 __ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex); | 3834 __ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex); |
3835 } else { | 3835 } else { |
3836 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize)); | 3836 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize)); |
3837 __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); | 3837 __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); |
3838 __ movq(Operand(kScratchRegister, kOffsetToMapCheckValue), rax); | 3838 __ movq(Operand(kScratchRegister, kOffsetToMapCheckValue), rax); |
3839 if (FLAG_debug_code) { | 3839 if (FLAG_debug_code) { |
3840 __ movl(rdi, Immediate(kWordBeforeMapCheckValue)); | 3840 __ movl(rdi, Immediate(kWordBeforeMapCheckValue)); |
3841 __ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), rdi); | 3841 __ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), rdi); |
3842 __ Assert(equal, "InstanceofStub unexpected call site cache."); | 3842 __ Assert(equal, "InstanceofStub unexpected call site cache (check)."); |
3843 } | 3843 } |
3844 } | 3844 } |
3845 | 3845 |
3846 __ movq(rcx, FieldOperand(rax, Map::kPrototypeOffset)); | 3846 __ movq(rcx, FieldOperand(rax, Map::kPrototypeOffset)); |
3847 | 3847 |
3848 // Loop through the prototype chain looking for the function prototype. | 3848 // Loop through the prototype chain looking for the function prototype. |
3849 NearLabel loop, is_instance, is_not_instance; | 3849 NearLabel loop, is_instance, is_not_instance; |
3850 __ LoadRoot(kScratchRegister, Heap::kNullValueRootIndex); | 3850 __ LoadRoot(kScratchRegister, Heap::kNullValueRootIndex); |
3851 __ bind(&loop); | 3851 __ bind(&loop); |
3852 __ cmpq(rcx, rbx); | 3852 __ cmpq(rcx, rbx); |
(...skipping 16 matching lines...) Expand all Loading... |
3869 // Store offset of true in the root array at the inline check site. | 3869 // Store offset of true in the root array at the inline check site. |
3870 ASSERT((Heap::kTrueValueRootIndex << kPointerSizeLog2) - kRootRegisterBias | 3870 ASSERT((Heap::kTrueValueRootIndex << kPointerSizeLog2) - kRootRegisterBias |
3871 == 0xB0 - 0x100); | 3871 == 0xB0 - 0x100); |
3872 __ movl(rax, Immediate(0xB0)); // TrueValue is at -10 * kPointerSize. | 3872 __ movl(rax, Immediate(0xB0)); // TrueValue is at -10 * kPointerSize. |
3873 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize)); | 3873 __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize)); |
3874 __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); | 3874 __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize)); |
3875 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax); | 3875 __ movb(Operand(kScratchRegister, kOffsetToResultValue), rax); |
3876 if (FLAG_debug_code) { | 3876 if (FLAG_debug_code) { |
3877 __ movl(rax, Immediate(kWordBeforeResultValue)); | 3877 __ movl(rax, Immediate(kWordBeforeResultValue)); |
3878 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax); | 3878 __ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax); |
3879 __ Assert(equal, "InstanceofStub unexpected call site cache."); | 3879 __ Assert(equal, "InstanceofStub unexpected call site cache (mov)."); |
3880 } | 3880 } |
3881 __ xorl(rax, rax); | 3881 __ xorl(rax, rax); |
3882 } | 3882 } |
3883 __ ret(2 * kPointerSize + extra_stack_space); | 3883 __ ret(2 * kPointerSize + extra_stack_space); |
3884 | 3884 |
3885 __ bind(&is_not_instance); | 3885 __ bind(&is_not_instance); |
3886 if (!HasCallSiteInlineCheck()) { | 3886 if (!HasCallSiteInlineCheck()) { |
3887 // We have to store a non-zero value in the cache. | 3887 // We have to store a non-zero value in the cache. |
3888 __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex); | 3888 __ StoreRoot(kScratchRegister, Heap::kInstanceofCacheAnswerRootIndex); |
3889 } else { | 3889 } else { |
(...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5134 // Do a tail call to the rewritten stub. | 5134 // Do a tail call to the rewritten stub. |
5135 __ jmp(rdi); | 5135 __ jmp(rdi); |
5136 } | 5136 } |
5137 | 5137 |
5138 | 5138 |
5139 #undef __ | 5139 #undef __ |
5140 | 5140 |
5141 } } // namespace v8::internal | 5141 } } // namespace v8::internal |
5142 | 5142 |
5143 #endif // V8_TARGET_ARCH_X64 | 5143 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |