2 * Copyright (c) 1999-2007 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <TargetConditionals.h>
25 #if __x86_64__ && !(TARGET_OS_SIMULATOR && !TARGET_OS_IOSMAC)
29 /********************************************************************
30 ********************************************************************
32 ** objc-msg-x86_64.s - x86-64 code to support objc messaging.
34 ********************************************************************
35 ********************************************************************/
39 // _objc_restartableRanges is used by method dispatch
40 // to get the critical regions for which method caches
41 // cannot be garbage collected.
43 .macro RestartableEntry
45 .short LLookupEnd$0 - LLookupStart$0
46 .short LCacheMiss$0 - LLookupStart$0
51 .private_extern _objc_restartableRanges
52 _objc_restartableRanges:
53 RestartableEntry _cache_getImp
54 RestartableEntry _objc_msgSend
55 RestartableEntry _objc_msgSend_fpret
56 RestartableEntry _objc_msgSend_fp2ret
57 RestartableEntry _objc_msgSend_stret
58 RestartableEntry _objc_msgSendSuper
59 RestartableEntry _objc_msgSendSuper_stret
60 RestartableEntry _objc_msgSendSuper2
61 RestartableEntry _objc_msgSendSuper2_stret
62 RestartableEntry _objc_msgLookup
63 RestartableEntry _objc_msgLookup_fpret
64 RestartableEntry _objc_msgLookup_fp2ret
65 RestartableEntry _objc_msgLookup_stret
66 RestartableEntry _objc_msgLookupSuper2
67 RestartableEntry _objc_msgLookupSuper2_stret
71 /********************************************************************
72 * Recommended multi-byte NOP instructions
73 * (Intel 64 and IA-32 Architectures Software Developer's Manual Volume 2B)
74 ********************************************************************/
75 #define nop1 .byte 0x90
76 #define nop2 .byte 0x66,0x90
77 #define nop3 .byte 0x0F,0x1F,0x00
78 #define nop4 .byte 0x0F,0x1F,0x40,0x00
79 #define nop5 .byte 0x0F,0x1F,0x44,0x00,0x00
80 #define nop6 .byte 0x66,0x0F,0x1F,0x44,0x00,0x00
81 #define nop7 .byte 0x0F,0x1F,0x80,0x00,0x00,0x00,0x00
82 #define nop8 .byte 0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
83 #define nop9 .byte 0x66,0x0F,0x1F,0x84,0x00,0x00,0x00,0x00,0x00
86 /********************************************************************
87 * Harmless branch prefix hint for instruction alignment
88 ********************************************************************/
93 /********************************************************************
94 * Names for parameter registers.
95 ********************************************************************/
114 /********************************************************************
115 * Names for relative labels
116 * DO NOT USE THESE LABELS ELSEWHERE
117 * Reserved labels: 6: 7: 8: 9:
118 ********************************************************************/
119 #define LNilTestSlow 7
120 #define LNilTestSlow_f 7f
121 #define LNilTestSlow_b 7b
122 #define LGetIsaDone 8
123 #define LGetIsaDone_f 8f
124 #define LGetIsaDone_b 8b
125 #define LGetIsaSlow 9
126 #define LGetIsaSlow_f 9f
127 #define LGetIsaSlow_b 9b
129 /********************************************************************
131 ********************************************************************/
143 /********************************************************************
145 * Structure definitions.
147 ********************************************************************/
149 // objc_super parameter to sendSuper
153 // Selected field offsets in class structure
154 // #define isa 0 USE GetIsa INSTEAD
157 #define method_name 0
158 #define method_imp 16
165 //////////////////////////////////////////////////////////////////////
167 // ENTRY functionName
169 // Assembly directives to begin an exported function.
171 // Takes: functionName - name of the exported function
172 //////////////////////////////////////////////////////////////////////
188 //////////////////////////////////////////////////////////////////////
190 // END_ENTRY functionName
192 // Assembly directives to end an exported function. Just a placeholder,
193 // a close-parenthesis for ENTRY, until it is needed for something.
195 // Takes: functionName - name of the exported function
196 //////////////////////////////////////////////////////////////////////
203 /********************************************************************
205 * Unwind info generation
206 ********************************************************************/
208 .section __LD,__compact_unwind,regular,debug
210 .set LUnwind$0, LExit$0 - $0
213 .quad 0 /* no personality */
214 .quad 0 /* no LSDA */
218 #define NoFrame 0x02010000 // no frame, no SP adjustment except return address
219 #define FrameWithNoSaves 0x01000000 // frame, no non-volatile saves
222 //////////////////////////////////////////////////////////////////////
226 // Create a stack frame and save all argument registers in preparation
227 // for a function call.
228 //////////////////////////////////////////////////////////////////////
235 sub $$0x80+8, %rsp // +8 for alignment
237 movdqa %xmm0, -0x80(%rbp)
238 push %rax // might be xmm parameter count
239 movdqa %xmm1, -0x70(%rbp)
241 movdqa %xmm2, -0x60(%rbp)
243 movdqa %xmm3, -0x50(%rbp)
245 movdqa %xmm4, -0x40(%rbp)
247 movdqa %xmm5, -0x30(%rbp)
249 movdqa %xmm6, -0x20(%rbp)
251 movdqa %xmm7, -0x10(%rbp)
256 //////////////////////////////////////////////////////////////////////
260 // Restore all argument registers and pop the stack frame created by
262 //////////////////////////////////////////////////////////////////////
266 movdqa -0x80(%rbp), %xmm0
268 movdqa -0x70(%rbp), %xmm1
270 movdqa -0x60(%rbp), %xmm2
272 movdqa -0x50(%rbp), %xmm3
274 movdqa -0x40(%rbp), %xmm4
276 movdqa -0x30(%rbp), %xmm5
278 movdqa -0x20(%rbp), %xmm6
280 movdqa -0x10(%rbp), %xmm7
286 /////////////////////////////////////////////////////////////////////
288 // CacheLookup return-type, caller, function
290 // Locate the implementation for a class in a selector's method cache.
292 // When this is used in a function that doesn't hold the runtime lock,
293 // this represents the critical section that may access dead memory.
294 // If the kernel causes one of these functions to go down the recovery
295 // path, we pretend the lookup failed by jumping the JumpMiss branch.
298 // $0 = NORMAL, FPRET, FP2RET, STRET
299 // $1 = CALL, LOOKUP, GETIMP
300 // a1 or a2 (STRET) = receiver
301 // a2 or a3 (STRET) = selector
302 // r10 = class to search
304 // On exit: r10 clobbered
305 // (found) calls or returns IMP in r11, eq/ne set for forwarding
306 // (not found) jumps to LCacheMiss, class still in r10
308 /////////////////////////////////////////////////////////////////////
312 // r11 = found bucket
315 movq cached_imp(%r11), %rax // return imp
317 jz 9f // don't xor a nil imp
318 xorq %r10, %rax // xor the isa with the imp
324 movq cached_imp(%r11), %r11 // load imp
325 xorq %r10, %r11 // xor imp and isa
327 // ne already set for forwarding by `xor`
329 cmp %r11, %r11 // set eq for stret forwarding
331 jmp *%r11 // call imp
334 movq cached_imp(%r11), %r11
335 xorq %r10, %r11 // return imp ^ isa
351 // As soon as we're past the LLookupStart$1 label we may have loaded
352 // an invalid cache pointer or mask.
354 // When task_restartable_ranges_synchronize() is called,
355 // (or when a signal hits us) before we're past LLookupEnd$1,
356 // then our PC will be reset to LCacheMiss$1 which forcefully
357 // jumps to the cache-miss codepath which have the following
361 // The cache-miss is just returning NULL (setting %rax to 0)
364 // - a1 or a2 (STRET) contains the receiver
365 // - a2 or a3 (STRET) contains the selector
366 // - r10 contains the isa
367 // - other registers are set as per calling conventions
372 movq %a2, %r11 // r11 = _cmd
374 movq %a3, %r11 // r11 = _cmd
376 andl 24(%r10), %r11d // r11 = _cmd & class->cache.mask
377 shlq $$4, %r11 // r11 = offset = (_cmd & mask)<<4
378 addq 16(%r10), %r11 // r11 = class->cache.buckets + offset
381 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
383 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
386 CacheHit $0, $1 // call or return imp
390 cmpq $$1, cached_sel(%r11)
391 jbe 3f // if (bucket->sel <= 1) wrap or miss
393 addq $$16, %r11 // bucket++
396 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
398 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
401 CacheHit $0, $1 // call or return imp
405 jb LCacheMiss$2 // if (bucket->sel < 1) cache miss
407 movq cached_imp(%r11), %r11 // bucket->imp is really first bucket
410 // Clone scanning loop to miss instead of hang when cache is corrupt.
411 // The slow path may detect any corruption and halt later.
415 cmpq $$1, cached_sel(%r11)
416 jbe 3f // if (bucket->sel <= 1) wrap or miss
418 addq $$16, %r11 // bucket++
421 cmpq cached_sel(%r11), %a2 // if (bucket->sel != _cmd)
423 cmpq cached_sel(%r11), %a3 // if (bucket->sel != _cmd)
426 CacheHit $0, $1 // call or return imp
429 // double wrap or miss
436 /////////////////////////////////////////////////////////////////////
438 // MethodTableLookup NORMAL|STRET
440 // Takes: a1 or a2 (STRET) = receiver
441 // a2 or a3 (STRET) = selector to search for
442 // r10 = class to search
444 // On exit: imp in %r11, eq/ne set for forwarding
446 /////////////////////////////////////////////////////////////////////
448 .macro MethodTableLookup
452 // lookUpImpOrForward(obj, sel, cls, LOOKUP_INITIALIZE | LOOKUP_RESOLVER)
454 // receiver already in a1
455 // selector already in a2
462 call _lookUpImpOrForward
464 // IMP is now in %rax
470 test %r11, %r11 // set ne for nonstret forwarding
472 cmp %r11, %r11 // set eq for stret forwarding
478 /////////////////////////////////////////////////////////////////////
480 // GetIsaFast return-type
481 // GetIsaSupport return-type
483 // Sets r10 = obj->isa. Consults the tagged isa table if necessary.
485 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
486 // a1 or a2 (STRET) = receiver
488 // On exit: r10 = receiver->isa
491 /////////////////////////////////////////////////////////////////////
498 movq $$ ISA_MASK, %r10
504 movq $$ ISA_MASK, %r10
519 leaq _objc_debug_taggedpointer_classes(%rip), %r10
520 movq (%r10, %r11, 8), %r10 // read isa from table
521 leaq _OBJC_CLASS_$___NSUnrecognizedTaggedPointer(%rip), %r11
532 leaq _objc_debug_taggedpointer_ext_classes(%rip), %r10
533 movq (%r10, %r11, 8), %r10 // read isa from table
538 /////////////////////////////////////////////////////////////////////
540 // NilTest return-type
542 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
543 // %a1 or %a2 (STRET) = receiver
545 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
548 // NilTestReturnZero return-type
550 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
551 // %a1 or %a2 (STRET) = receiver
553 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
556 // NilTestReturnIMP return-type
558 // Takes: $0 = NORMAL or FPRET or FP2RET or STRET
559 // %a1 or %a2 (STRET) = receiver
561 // On exit: Loads non-nil receiver in %a1 or %a2 (STRET)
562 // or returns an IMP in r11 that returns zero.
564 /////////////////////////////////////////////////////////////////////
573 .macro ZeroReturnFPRET
578 .macro ZeroReturnFP2RET
584 .macro ZeroReturnSTRET
585 // rax gets the struct-return address as passed in rdi
589 STATIC_ENTRY __objc_msgNil
592 END_ENTRY __objc_msgNil
594 STATIC_ENTRY __objc_msgNil_fpret
597 END_ENTRY __objc_msgNil_fpret
599 STATIC_ENTRY __objc_msgNil_fp2ret
602 END_ENTRY __objc_msgNil_fp2ret
604 STATIC_ENTRY __objc_msgNil_stret
607 END_ENTRY __objc_msgNil_stret
621 .macro NilTestReturnZero
640 .macro NilTestReturnIMP
645 leaq __objc_msgNil(%rip), %r11
647 leaq __objc_msgNil_fpret(%rip), %r11
649 leaq __objc_msgNil_fp2ret(%rip), %r11
651 leaq __objc_msgNil_stret(%rip), %r11
659 /********************************************************************
660 * IMP cache_getImp(Class cls, SEL sel)
662 * On entry: a1 = class whose cache is to be searched
663 * a2 = selector to search for
665 * If found, returns method implementation.
666 * If not found, returns NULL.
667 ********************************************************************/
669 STATIC_ENTRY _cache_getImp
672 movq %a1, %r10 // move class to r10 for CacheLookup
673 // returns IMP on success
674 CacheLookup NORMAL, GETIMP, _cache_getImp
676 LCacheMiss_cache_getImp:
677 // cache miss, return nil
681 END_ENTRY _cache_getImp
684 /********************************************************************
686 * id objc_msgSend(id self, SEL _cmd,...);
687 * IMP objc_msgLookup(id self, SEL _cmd, ...);
689 * objc_msgLookup ABI:
690 * IMP returned in r11
691 * Forwarding returned in Z flag
692 * r10 reserved for our use but not used
694 ********************************************************************/
698 .globl _objc_debug_taggedpointer_classes
699 _objc_debug_taggedpointer_classes:
701 .globl _objc_debug_taggedpointer_ext_classes
702 _objc_debug_taggedpointer_ext_classes:
706 UNWIND _objc_msgSend, NoFrame
710 GetIsaFast NORMAL // r10 = self->isa
711 // calls IMP on success
712 CacheLookup NORMAL, CALL, _objc_msgSend
714 NilTestReturnZero NORMAL
718 // cache miss: go search the method lists
719 LCacheMiss_objc_msgSend:
721 jmp __objc_msgSend_uncached
723 END_ENTRY _objc_msgSend
726 ENTRY _objc_msgLookup
730 GetIsaFast NORMAL // r10 = self->isa
731 // returns IMP on success
732 CacheLookup NORMAL, LOOKUP, _objc_msgLookup
734 NilTestReturnIMP NORMAL
738 // cache miss: go search the method lists
739 LCacheMiss_objc_msgLookup:
741 jmp __objc_msgLookup_uncached
743 END_ENTRY _objc_msgLookup
746 ENTRY _objc_msgSend_fixup
748 END_ENTRY _objc_msgSend_fixup
751 STATIC_ENTRY _objc_msgSend_fixedup
752 // Load _cmd from the message_ref
755 END_ENTRY _objc_msgSend_fixedup
758 /********************************************************************
760 * id objc_msgSendSuper(struct objc_super *super, SEL _cmd,...);
762 * struct objc_super {
766 ********************************************************************/
768 ENTRY _objc_msgSendSuper
769 UNWIND _objc_msgSendSuper, NoFrame
771 // search the cache (objc_super in %a1)
772 movq class(%a1), %r10 // class = objc_super->class
773 movq receiver(%a1), %a1 // load real receiver
774 // calls IMP on success
775 CacheLookup NORMAL, CALL, _objc_msgSendSuper
777 // cache miss: go search the method lists
778 LCacheMiss_objc_msgSendSuper:
779 // class still in r10
780 jmp __objc_msgSend_uncached
782 END_ENTRY _objc_msgSendSuper
785 /********************************************************************
786 * id objc_msgSendSuper2
787 ********************************************************************/
789 ENTRY _objc_msgSendSuper2
790 UNWIND _objc_msgSendSuper2, NoFrame
792 // objc_super->class is superclass of class to search
794 // search the cache (objc_super in %a1)
795 movq class(%a1), %r10 // cls = objc_super->class
796 movq receiver(%a1), %a1 // load real receiver
797 movq 8(%r10), %r10 // cls = class->superclass
798 // calls IMP on success
799 CacheLookup NORMAL, CALL, _objc_msgSendSuper2
801 // cache miss: go search the method lists
802 LCacheMiss_objc_msgSendSuper2:
803 // superclass still in r10
804 jmp __objc_msgSend_uncached
806 END_ENTRY _objc_msgSendSuper2
809 ENTRY _objc_msgLookupSuper2
811 // objc_super->class is superclass of class to search
813 // search the cache (objc_super in %a1)
814 movq class(%a1), %r10 // cls = objc_super->class
815 movq receiver(%a1), %a1 // load real receiver
816 movq 8(%r10), %r10 // cls = class->superclass
817 // returns IMP on success
818 CacheLookup NORMAL, LOOKUP, _objc_msgLookupSuper2
820 // cache miss: go search the method lists
821 LCacheMiss_objc_msgLookupSuper2:
822 // superclass still in r10
823 jmp __objc_msgLookup_uncached
825 END_ENTRY _objc_msgLookupSuper2
828 ENTRY _objc_msgSendSuper2_fixup
830 END_ENTRY _objc_msgSendSuper2_fixup
833 STATIC_ENTRY _objc_msgSendSuper2_fixedup
834 // Load _cmd from the message_ref
836 jmp _objc_msgSendSuper2
837 END_ENTRY _objc_msgSendSuper2_fixedup
840 /********************************************************************
842 * double objc_msgSend_fpret(id self, SEL _cmd,...);
843 * Used for `long double` return only. `float` and `double` use objc_msgSend.
845 ********************************************************************/
847 ENTRY _objc_msgSend_fpret
848 UNWIND _objc_msgSend_fpret, NoFrame
852 GetIsaFast FPRET // r10 = self->isa
853 // calls IMP on success
854 CacheLookup FPRET, CALL, _objc_msgSend_fpret
856 NilTestReturnZero FPRET
860 // cache miss: go search the method lists
861 LCacheMiss_objc_msgSend_fpret:
863 jmp __objc_msgSend_uncached
865 END_ENTRY _objc_msgSend_fpret
868 ENTRY _objc_msgLookup_fpret
872 GetIsaFast FPRET // r10 = self->isa
873 // returns IMP on success
874 CacheLookup FPRET, LOOKUP, _objc_msgLookup_fpret
876 NilTestReturnIMP FPRET
880 // cache miss: go search the method lists
881 LCacheMiss_objc_msgLookup_fpret:
883 jmp __objc_msgLookup_uncached
885 END_ENTRY _objc_msgLookup_fpret
888 ENTRY _objc_msgSend_fpret_fixup
890 END_ENTRY _objc_msgSend_fpret_fixup
893 STATIC_ENTRY _objc_msgSend_fpret_fixedup
894 // Load _cmd from the message_ref
896 jmp _objc_msgSend_fpret
897 END_ENTRY _objc_msgSend_fpret_fixedup
900 /********************************************************************
902 * double objc_msgSend_fp2ret(id self, SEL _cmd,...);
903 * Used for `complex long double` return only.
905 ********************************************************************/
907 ENTRY _objc_msgSend_fp2ret
908 UNWIND _objc_msgSend_fp2ret, NoFrame
912 GetIsaFast FP2RET // r10 = self->isa
913 // calls IMP on success
914 CacheLookup FP2RET, CALL, _objc_msgSend_fp2ret
916 NilTestReturnZero FP2RET
920 // cache miss: go search the method lists
921 LCacheMiss_objc_msgSend_fp2ret:
923 jmp __objc_msgSend_uncached
925 END_ENTRY _objc_msgSend_fp2ret
928 ENTRY _objc_msgLookup_fp2ret
932 GetIsaFast FP2RET // r10 = self->isa
933 // returns IMP on success
934 CacheLookup FP2RET, LOOKUP, _objc_msgLookup_fp2ret
936 NilTestReturnIMP FP2RET
940 // cache miss: go search the method lists
941 LCacheMiss_objc_msgLookup_fp2ret:
943 jmp __objc_msgLookup_uncached
945 END_ENTRY _objc_msgLookup_fp2ret
948 ENTRY _objc_msgSend_fp2ret_fixup
950 END_ENTRY _objc_msgSend_fp2ret_fixup
953 STATIC_ENTRY _objc_msgSend_fp2ret_fixedup
954 // Load _cmd from the message_ref
956 jmp _objc_msgSend_fp2ret
957 END_ENTRY _objc_msgSend_fp2ret_fixedup
960 /********************************************************************
962 * void objc_msgSend_stret(void *st_addr, id self, SEL _cmd, ...);
964 * objc_msgSend_stret is the struct-return form of msgSend.
965 * The ABI calls for %a1 to be used as the address of the structure
966 * being returned, with the parameters in the succeeding locations.
968 * On entry: %a1 is the address where the structure is returned,
969 * %a2 is the message receiver,
970 * %a3 is the selector
971 ********************************************************************/
973 ENTRY _objc_msgSend_stret
974 UNWIND _objc_msgSend_stret, NoFrame
978 GetIsaFast STRET // r10 = self->isa
979 // calls IMP on success
980 CacheLookup STRET, CALL, _objc_msgSend_stret
982 NilTestReturnZero STRET
986 // cache miss: go search the method lists
987 LCacheMiss_objc_msgSend_stret:
989 jmp __objc_msgSend_stret_uncached
991 END_ENTRY _objc_msgSend_stret
994 ENTRY _objc_msgLookup_stret
998 GetIsaFast STRET // r10 = self->isa
999 // returns IMP on success
1000 CacheLookup STRET, LOOKUP, _objc_msgLookup_stret
1002 NilTestReturnIMP STRET
1006 // cache miss: go search the method lists
1007 LCacheMiss_objc_msgLookup_stret:
1009 jmp __objc_msgLookup_stret_uncached
1011 END_ENTRY _objc_msgLookup_stret
1014 ENTRY _objc_msgSend_stret_fixup
1016 END_ENTRY _objc_msgSend_stret_fixup
1019 STATIC_ENTRY _objc_msgSend_stret_fixedup
1020 // Load _cmd from the message_ref
1022 jmp _objc_msgSend_stret
1023 END_ENTRY _objc_msgSend_stret_fixedup
1026 /********************************************************************
1028 * void objc_msgSendSuper_stret(void *st_addr, struct objc_super *super, SEL _cmd, ...);
1030 * struct objc_super {
1035 * objc_msgSendSuper_stret is the struct-return form of msgSendSuper.
1036 * The ABI calls for (sp+4) to be used as the address of the structure
1037 * being returned, with the parameters in the succeeding registers.
1039 * On entry: %a1 is the address where the structure is returned,
1040 * %a2 is the address of the objc_super structure,
1041 * %a3 is the selector
1043 ********************************************************************/
1045 ENTRY _objc_msgSendSuper_stret
1046 UNWIND _objc_msgSendSuper_stret, NoFrame
1048 // search the cache (objc_super in %a2)
1049 movq class(%a2), %r10 // class = objc_super->class
1050 movq receiver(%a2), %a2 // load real receiver
1051 // calls IMP on success
1052 CacheLookup STRET, CALL, _objc_msgSendSuper_stret
1054 // cache miss: go search the method lists
1055 LCacheMiss_objc_msgSendSuper_stret:
1056 // class still in r10
1057 jmp __objc_msgSend_stret_uncached
1059 END_ENTRY _objc_msgSendSuper_stret
1062 /********************************************************************
1063 * id objc_msgSendSuper2_stret
1064 ********************************************************************/
1066 ENTRY _objc_msgSendSuper2_stret
1067 UNWIND _objc_msgSendSuper2_stret, NoFrame
1069 // search the cache (objc_super in %a2)
1070 movq class(%a2), %r10 // class = objc_super->class
1071 movq receiver(%a2), %a2 // load real receiver
1072 movq 8(%r10), %r10 // class = class->superclass
1073 // calls IMP on success
1074 CacheLookup STRET, CALL, _objc_msgSendSuper2_stret
1076 // cache miss: go search the method lists
1077 LCacheMiss_objc_msgSendSuper2_stret:
1078 // superclass still in r10
1079 jmp __objc_msgSend_stret_uncached
1081 END_ENTRY _objc_msgSendSuper2_stret
1084 ENTRY _objc_msgLookupSuper2_stret
1086 // search the cache (objc_super in %a2)
1087 movq class(%a2), %r10 // class = objc_super->class
1088 movq receiver(%a2), %a2 // load real receiver
1089 movq 8(%r10), %r10 // class = class->superclass
1090 // returns IMP on success
1091 CacheLookup STRET, LOOKUP, _objc_msgLookupSuper2_stret
1093 // cache miss: go search the method lists
1094 LCacheMiss_objc_msgLookupSuper2_stret:
1095 // superclass still in r10
1096 jmp __objc_msgLookup_stret_uncached
1098 END_ENTRY _objc_msgLookupSuper2_stret
1101 ENTRY _objc_msgSendSuper2_stret_fixup
1103 END_ENTRY _objc_msgSendSuper2_stret_fixup
1106 STATIC_ENTRY _objc_msgSendSuper2_stret_fixedup
1107 // Load _cmd from the message_ref
1109 jmp _objc_msgSendSuper2_stret
1110 END_ENTRY _objc_msgSendSuper2_stret_fixedup
1113 /********************************************************************
1115 * _objc_msgSend_uncached
1116 * _objc_msgSend_stret_uncached
1117 * _objc_msgLookup_uncached
1118 * _objc_msgLookup_stret_uncached
1120 * The uncached method lookup.
1122 ********************************************************************/
1124 STATIC_ENTRY __objc_msgSend_uncached
1125 UNWIND __objc_msgSend_uncached, FrameWithNoSaves
1127 // THIS IS NOT A CALLABLE C FUNCTION
1128 // Out-of-band r10 is the searched class
1130 // r10 is already the class to search
1131 MethodTableLookup NORMAL // r11 = IMP
1132 jmp *%r11 // goto *imp
1134 END_ENTRY __objc_msgSend_uncached
1137 STATIC_ENTRY __objc_msgSend_stret_uncached
1138 UNWIND __objc_msgSend_stret_uncached, FrameWithNoSaves
1140 // THIS IS NOT A CALLABLE C FUNCTION
1141 // Out-of-band r10 is the searched class
1143 // r10 is already the class to search
1144 MethodTableLookup STRET // r11 = IMP
1145 jmp *%r11 // goto *imp
1147 END_ENTRY __objc_msgSend_stret_uncached
1150 STATIC_ENTRY __objc_msgLookup_uncached
1151 UNWIND __objc_msgLookup_uncached, FrameWithNoSaves
1153 // THIS IS NOT A CALLABLE C FUNCTION
1154 // Out-of-band r10 is the searched class
1156 // r10 is already the class to search
1157 MethodTableLookup NORMAL // r11 = IMP
1160 END_ENTRY __objc_msgLookup_uncached
1163 STATIC_ENTRY __objc_msgLookup_stret_uncached
1164 UNWIND __objc_msgLookup_stret_uncached, FrameWithNoSaves
1166 // THIS IS NOT A CALLABLE C FUNCTION
1167 // Out-of-band r10 is the searched class
1169 // r10 is already the class to search
1170 MethodTableLookup STRET // r11 = IMP
1173 END_ENTRY __objc_msgLookup_stret_uncached
1176 /********************************************************************
1178 * id _objc_msgForward(id self, SEL _cmd,...);
1180 * _objc_msgForward and _objc_msgForward_stret are the externally-callable
1181 * functions returned by things like method_getImplementation().
1182 * _objc_msgForward_impcache is the function pointer actually stored in
1185 ********************************************************************/
1187 STATIC_ENTRY __objc_msgForward_impcache
1188 // Method cache version
1190 // THIS IS NOT A CALLABLE C FUNCTION
1191 // Out-of-band condition register is NE for stret, EQ otherwise.
1193 je __objc_msgForward_stret
1194 jmp __objc_msgForward
1196 END_ENTRY __objc_msgForward_impcache
1199 ENTRY __objc_msgForward
1200 // Non-stret version
1202 movq __objc_forward_handler(%rip), %r11
1205 END_ENTRY __objc_msgForward
1208 ENTRY __objc_msgForward_stret
1209 // Struct-return version
1211 movq __objc_forward_stret_handler(%rip), %r11
1214 END_ENTRY __objc_msgForward_stret
1217 ENTRY _objc_msgSend_debug
1219 END_ENTRY _objc_msgSend_debug
1221 ENTRY _objc_msgSendSuper2_debug
1222 jmp _objc_msgSendSuper2
1223 END_ENTRY _objc_msgSendSuper2_debug
1225 ENTRY _objc_msgSend_stret_debug
1226 jmp _objc_msgSend_stret
1227 END_ENTRY _objc_msgSend_stret_debug
1229 ENTRY _objc_msgSendSuper2_stret_debug
1230 jmp _objc_msgSendSuper2_stret
1231 END_ENTRY _objc_msgSendSuper2_stret_debug
1233 ENTRY _objc_msgSend_fpret_debug
1234 jmp _objc_msgSend_fpret
1235 END_ENTRY _objc_msgSend_fpret_debug
1237 ENTRY _objc_msgSend_fp2ret_debug
1238 jmp _objc_msgSend_fp2ret
1239 END_ENTRY _objc_msgSend_fp2ret_debug
1242 ENTRY _objc_msgSend_noarg
1244 END_ENTRY _objc_msgSend_noarg
1247 ENTRY _method_invoke
1249 // See if this is a small method.
1251 jnz L_method_invoke_small
1253 // We can directly load the IMP from big methods.
1254 movq method_imp(%a2), %r11
1255 movq method_name(%a2), %a2
1258 L_method_invoke_small:
1259 // Small methods require a call to handle swizzling.
1262 call __method_getImplementationAndName
1269 END_ENTRY _method_invoke
1272 ENTRY _method_invoke_stret
1274 // See if this is a small method.
1276 jnz L_method_invoke_stret_small
1278 // We can directly load the IMP from big methods.
1279 movq method_imp(%a3), %r11
1280 movq method_name(%a3), %a3
1283 L_method_invoke_stret_small:
1284 // Small methods require a call to handle swizzling.
1287 call __method_getImplementationAndName
1294 END_ENTRY _method_invoke_stret
1297 .section __DATA,__objc_msg_break